private FileVisitResult walk(Path file, CallContext context, int depth) throws IOException {

    DcFile target = null;
    try {
      target = provider.getFile(file, context);
    } catch (AccessDeniedException ex) {
      // Fail if this was the first directory, otherwise skip.
      if (depth == 0) {
        throw ex;
      }
      return FileVisitResult.CONTINUE;
    } catch (IOException ex) {
      return visitor.visitFileFailed(file, ex);
    }

    // at maximum depth
    if (depth >= maxDepth) {
      return FileVisitResult.CONTINUE;
    }

    // the exception notified to the postVisitDirectory method
    IOException ioe = null;
    FileVisitResult result;

    // invoke preVisitDirectory and then visit each entry
    result = visitor.preVisitDirectory(file, target);
    if (result != FileVisitResult.CONTINUE) {
      return result;
    }

    try {
      for (Path dir : target.getAttributeView(SubdirectoryView.class).getChildrenPaths()) {
        result = walk(dir, context, depth + 1);

        // returning null will cause NPE to be thrown
        if (result == null || result == FileVisitResult.TERMINATE) {
          return result;
        }

        // skip remaining siblings in this directory
        if (result == FileVisitResult.SKIP_SIBLINGS) {
          break;
        }
      }
    } catch (DirectoryIteratorException e) {
      // IOException will be notified to postVisitDirectory
      ioe = e.getCause();
    }

    // invoke postVisitDirectory last
    return visitor.postVisitDirectory(file, ioe);
  }
 @Override
 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
     throws IOException {
   DcFile file = (DcFile) attrs;
   // Groups can only contain other groups. If we are searching groups, accept the group,
   // otherwise, continue
   if (file.getType() instanceof GroupType) {
     if (filter.searchGroups() && filter.matcher.matches(dir)) {
       accept(file);
     }
     return FileVisitResult.SKIP_SUBTREE;
   }
   folderStack.add(file);
   return FileVisitResult.CONTINUE;
 }
 public void accept(DcFile file) {
   files.add(file.getObject());
 }