          
          d = defer.Deferred()
          d.addCallback(self._getChild, self.site.resource, self.postpath)
-+        d.addCallback(self._rememberResource, "/" + "/".join(self.prepath))
++        d.addCallback(self._rememberResource, "/" + "/".join(self.postpath))
          d.addCallback(lambda res, req: res.renderHTTP(req), self)
          d.addCallback(self._cbFinishRender)
          d.addErrback(self._processingFailed)

         assert segments[0] == "", "URL path didn't begin with '/': %s" % (path,)
         segments = segments[1:]
-        segments = map(unquote, segments)
 
         def notFound(f):
             f.trap(http.HTTPError)
             if f.response.code != responsecode.NOT_FOUND:
-                raise f
+                return f
             return None
 
-        return defer.maybeDeferred(self._getChild, None, self.site.resource, segments, updatepaths=False)
+        d = defer.maybeDeferred(self._getChild, None, self.site.resource, segments, updatepaths=False)
+        d.addCallback(self._rememberResource, path)
+        d.addErrback(notFound)
+        return d
 
+    def locateChildResource(self, parent, child_name):
+        """
+        Looks up the child resource with the given name given the parent

 
     def locateResource(self, url):
         """
@@ -385,7 +397,12 @@
             The contained response will have a status code of
             L{responsecode.BAD_REQUEST}.
         """
-        if url is None: return None
+        if url is None:
+            return None
+
+        cached = self._urlsByResource.get(url, None)
+        if cached is not None:
+            return succeed(cached)
 
         #
         # Parse the URL
@@ -406,10 +423,50 @@
                 "URL is not on this site (%s://%s/): %s" % (scheme, self.headers.getHeader("host"), url)
             ))
 
