private List<Long> sourceRootHash(BuildRootDescriptor rootDescriptor, BuildTarget<?> target) {
    try {
      File rootFile = rootDescriptor.getRootFile();
      if (!rootFile.exists() || rootFile.getAbsolutePath().startsWith(myOutputFolderPath)) {
        return null;
      }

      List<Long> targetRootHashes = new ArrayList<>();
      Files.walkFileTree(rootFile.toPath(), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<>() {
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
          return myBuildRootIndex.isDirectoryAccepted(dir.toFile(), rootDescriptor)
                 ? FileVisitResult.CONTINUE
                 : FileVisitResult.SKIP_SUBTREE;
        }

        @Override
        public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
          final File file = path.toFile();
          if (!myBuildRootIndex.isFileAccepted(file, rootDescriptor)) return FileVisitResult.CONTINUE;
          getFileHash(target, file, rootFile).ifPresent(targetRootHashes::add);
          return FileVisitResult.CONTINUE;
        }
      });
      return targetRootHashes;
    }
    catch (IOException e) {
      LOG.warn("Couldn't calculate build target hash for : " + target.getPresentableName(), e);
      return null;
    }
  }
private List<Long> sourceRootHash(BuildRootDescriptor rootDescriptor, BuildTarget<?> target)