 +        def notFound(f):
 +            f.trap(http.HTTPError)
 +            if f.response.code != responsecode.NOT_FOUND:
-+                raise f
++                return f
 +            return None
 +
 +        def _registerResource(child):
 +            self._resourcesByURL[child] = url
-+            self._resourcesFromURL[url] = child
++            self._urlsByResource[url] = child
 +            return child
 +        
 +        d = defer.maybeDeferred(self._getChild, None, res, [segment], updatepaths=False)
 +        d.addCallback(_registerResource)
 +        return d
- 
++
      def _processingFailed(self, reason):
          if reason.check(http.HTTPError) is not None:
+             # If the exception was an HTTPError, leave it alone

     def _rememberURLForResource(self, url, resource):
         """
         Remember the URL of visited resources.
@@ -387,6 +399,11 @@
         """
         if url is None: return None
 
+        try:
+            return succeed(self._resourcesFromURL[url])
+        except KeyError:
+            pass
+
         #
         # Parse the URL
         #
@@ -417,7 +434,52 @@
                 raise f
             return None
 
-        return defer.maybeDeferred(self._getChild, None, self.site.resource, segments, updatepaths=False)
+        def _registerResource(child):
+            self._resourcesByURL[child] = path
+            self._resourcesFromURL[path] = child
+            return child
+        
+        d = defer.maybeDeferred(self._getChild, None, self.site.resource, segments, updatepaths=False)
+        d.addCallback(_registerResource)
+        return d
+
+    def locateChildResource(self, res, childpath):
+        """
+        Looks up the child resource with the given name given the parent resource.

         d.addCallback(lambda res, req: res.renderHTTP(req), self)
         d.addCallback(self._cbFinishRender)
         d.addErrback(self._processingFailed)
@@ -320,8 +344,6 @@
                     url = "/" + "/".join(path)
                 else:
                     url = "/"
-        
-                self._rememberURLForResource(quote(url), res)
                 return res
             #else:
             #    raise ValueError("locateChild must not return StopTraversal with a resource other than self.")
@@ -342,12 +364,9 @@
                 self.prepath.append(self.postpath.pop(0))
 
         child = self._getChild(None, newres, newpath, updatepaths=updatepaths)
-        self._rememberURLForResource(quote(url), child)
 
         return child
 
