 +        d.addErrback(notFound)
 +        return d
  
-+    def locateChildResource(self, res, childpath):
++    def locateChildResource(self, resource, child_path):
 +        """
-+        Looks up the child resource with the given name given the parent resource.
-+        @param uri: The URL last path segment of the desired resource.
++        Looks up the child resource with the given name given the parent
++        resource.  This is similar to locateResource(), but doesn't have to
++        start the lookup from the root resource, so it is potentially faster.
++        @param resource: the parent of the resource being looked up.
++        @param child_path: the path of the resource being looked up, relative
++            to C{parent}.
 +        @return: a L{Deferred} resulting in the L{IResource} at the
 +            given URL or C{None} if no such resource can be located.
 +        @raise HTTPError: If C{url} is not a URL on the site that this

         #
         # Parse the URL
         #
@@ -414,11 +431,48 @@
         def notFound(f):
             f.trap(http.HTTPError)
             if f.response.code != responsecode.NOT_FOUND:

+            The contained response will have a status code of
+            L{responsecode.BAD_REQUEST}.
+        """
+        if resource is None or child_path is None:
+            return None
+        
+        url = joinURL(self.urlForResource(resource), child_path)
+
+        cached = self._urlsByResource.get(url, None)
+        if cached is not None:
+            return succeed(cached)
+
+        segment = unquote(child_path)
+
+        def notFound(f):
+            f.trap(http.HTTPError)
