private static boolean traverseRecursively(CompileContext context,
                                             final BuildRootDescriptor rd,
                                             final CompilationRound round,
                                             final File file,
                                             final @NotNull StampsStorage<? extends StampsStorage.Stamp> stampStorage,
                                             final boolean forceDirty,
                                             @Nullable Set<? super File> currentFiles, @Nullable FileFilter filter) throws IOException {

    var fileConsumer = new FileConsumer() {
      boolean allFilesMarked = true;
      @Override
      public void consume(@NotNull File file, @Nullable BasicFileAttributes attrs) throws IOException {
        if (filter != null && !filter.accept(file)) {
          allFilesMarked = false;
        }
        else {
          boolean markDirty = forceDirty;
          if (!markDirty) {
            markDirty = attrs != null?
              stampStorage.isDirtyStamp(stampStorage.getPreviousStamp(file, rd.getTarget()), file, attrs) :
              stampStorage.isDirtyStamp(stampStorage.getPreviousStamp(file, rd.getTarget()), file);
          }
          if (markDirty) {
            // if it is full project rebuild, all storages are already completely cleared;
            // so passing null because there is no need to access the storage to clear non-existing data
            final StampsStorage<? extends StampsStorage.Stamp> marker = context.isProjectRebuild()? null : stampStorage;
            context.getProjectDescriptor().fsState.markDirty(context, round, file, rd, marker, false);
          }
          if (currentFiles != null) {
            currentFiles.add(file);
          }
          if (!markDirty) {
            allFilesMarked = false;
          }
        }
      }
    };
    traverseRecursively(context.getProjectDescriptor().getBuildRootIndex(), rd, file, fileConsumer);
    return fileConsumer.allFilesMarked;
  }
private static boolean traverseRecursively(CompileContext context,
                                             final BuildRootDescriptor rd,
                                             final CompilationRound round,
                                             final File file,
                                             final @NotNull StampsStorage<? extends StampsStorage.Stamp> stampStorage,
                                             final boolean forceDirty,
                                             @Nullable Set<? super File> currentFiles, @Nullable FileFilter filter)