code: protected List<CmsPair<CmsResource, CmsResource>> getMatchingResources(String source, String target)
      throws CmsException {
  
          List<CmsResource> sourceResources = readTree(source);
          Map<String, CmsResource> sourceRelative = getResourcesByRelativePath(sourceResources, source);
  
          List<CmsResource> targetResources = readTree(target);
          Map<String, CmsResource> targetRelative = getResourcesByRelativePath(targetResources, target);
  
          List<CmsPair<CmsResource, CmsResource>> result = new ArrayList<CmsPair<CmsResource, CmsResource>>();
          sourceRelative.keySet().retainAll(targetRelative.keySet());
          for (Map.Entry<String, CmsResource> entry : sourceRelative.entrySet()) {
              String key = entry.getKey();
              CmsResource sourceRes = entry.getValue();
              CmsResource targetRes = targetRelative.get(key);
              result.add(CmsPair.create(sourceRes, targetRes));
          }
          return result;
      }
docs: Gets a list of resource pairs whose paths relative to the source/target roots passed match.<p>
  
  @param source the source root
  @param target the target root
  
  @return the list of matching resources
  
  @throws CmsException if something goes wrong