@Override
          public Iterable<JavaFileObject> fun(File root) {
            try {
              final boolean isFile;

              FileOperations.Archive archive = myFileOperations.lookupArchive(root);
              if (archive != null) {
                isFile = true;
              }
              else {
                isFile = myFileOperations.isFile(root);
              }

              if (isFile) {
                // Not a directory; either a file or non-existent, create the archive
                try {
                  if (archive == null) {
                    archive = myFileOperations.openArchive(root, myEncodingName, location);
                  }
                  if (archive != null) {
                    return archive.list(packageName.replace('.', '/'), kinds, recurse);
                  }
                  // fallback to default implementation
                  return JpsJavacFileManager.super.list(location, packageName, kinds, recurse);
                }
                catch (IOException ex) {
                  throw new IOException("Error reading file " + root + ": " + ex.getMessage(), ex);
                }
              }

              // is a directory or does not exist
              final File dir = new File(root, packageName.replace('.', '/'));

              // Generally, no directories should be included in result. If recurse:= false,
              // the fileOperations.listFiles(dir, recurse) output may contain children directories, so the filter should skip them too
              final BooleanFunction<File> kindsMatcher = ourKindFilter.getFor(kinds);
              final BooleanFunction<File> filter = recurse || !kinds.contains(JavaFileObject.Kind.OTHER) ? kindsMatcher : new BooleanFunction<File>() {
                @Override
                public boolean fun(File file) {
                  return kindsMatcher.fun(file) && (
                    !(kinds.size() == 1 || JpsFileObject.findKind(file.getName()) == JavaFileObject.Kind.OTHER) /* the kind != OTHER */ || myFileOperations.isFile(file)
                  );
                }
              };
              return Iterators.map(Iterators.filter(myFileOperations.listFiles(dir, recurse), filter), location.isOutputLocation()? myFileToInputFileObjectConverter : myFileToCachingInputFileObjectConverter);
            }
            catch (IOException e) {
              throw new RuntimeException(e);
            }
          }
@Override
          public Iterable<JavaFileObject> fun(File root)