protected String[] doListFileNames(
      String pathName, FileStoreFilter filter, boolean recurse, boolean exitBranchOnFirstMatch) {
    java.util.ArrayList<String> nameList = null;

    for (StoreLocation location : this.readLocations) {
      // If the path name is null, then just search from the root of each location. Otherwise search
      // from the
      // named cache path.
      java.io.File dir = location.getFile();
      if (pathName != null) dir = new java.io.File(makeAbsolutePath(dir, pathName));

      // Either the location does not exists, or the speciifed path does not exist under that
      // location. In either
      // case we skip searching this location.
      if (!dir.exists()) continue;

      // Lazily initialize the list of file names. If no location contains the specified path, then
      // the list is
      // not created, and this method will return null.
      if (nameList == null) nameList = new java.util.ArrayList<String>();

      this.doListFileNames(location, dir, filter, recurse, exitBranchOnFirstMatch, nameList);
    }

    if (nameList == null) return null;

    String[] names = new String[nameList.size()];
    nameList.toArray(names);
    return names;
  }
  protected void doListFileNames(
      StoreLocation location,
      java.io.File dir,
      FileStoreFilter filter,
      boolean recurse,
      boolean exitBranchOnFirstMatch,
      java.util.Collection<String> names) {
    java.util.ArrayList<java.io.File> subDirs = new java.util.ArrayList<java.io.File>();

    // Search the children of the specified directory. If the child is a directory, append it to the
    // list of sub
    // directories to search later. Otherwise, try to list the file as a match. If the file is a
    // match and
    // exitBranchOnFirstMatch is true, then exit this branch without considering any other files.
    // This has the
    // effect of choosing files closest to the search root.
    for (java.io.File childFile : dir.listFiles()) {
      if (childFile == null) continue;

      if (childFile.isDirectory()) {
        subDirs.add(childFile);
      } else {
        if (this.listFile(location, childFile, filter, names) && exitBranchOnFirstMatch) return;
      }
    }

    if (!recurse) return;

    // Recursively search each sub-directory. If exitBranchOnFirstMatch is true, then we did not
    // find a match under
    // this directory.
    for (java.io.File childDir : subDirs) {
      this.doListFileNames(location, childDir, filter, recurse, exitBranchOnFirstMatch, names);
    }
  }
 public java.util.List<? extends java.io.File> getLocations() {
   java.util.ArrayList<java.io.File> locations = new java.util.ArrayList<java.io.File>();
   for (StoreLocation location : this.readLocations) {
     locations.add(location.getFile());
   }
   return locations;
 }