@ApiStatus.Internal
  public static boolean updateMappingsOnRoundCompletion(
    CompileContext context, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, ModuleChunk chunk) throws IOException {

    BuildDataManager dataManager = context.getProjectDescriptor().dataManager;
    GraphConfiguration graphConfig = dataManager.getDependencyGraph();
    if(isDepGraphEnabled() && graphConfig != null) {
      Delta delta = null;
      BackendCallbackToGraphDeltaAdapter callback = GRAPH_DELTA_CALLBACK_KEY.get(context);

      NodeSourcePathMapper pathMapper = graphConfig.getPathMapper();
      Set<File> inputFiles = getFilesContainer(context, FILES_TO_COMPILE_KEY);

      if (callback != null) {
        // Important: in case of errors some sources sent to recompilation might not have corresponding output classes either because a source has compilation errors
        // or because compiler stopped compilation and has not managed to compile some sources.
        // In this case use empty set of delta's "base sources" for dependency calculation, so that only actually recompiled sources will take part in dependency analysis and affected files calculation.
        // Otherwise, some classes that correspond to non-compiled sources might be considered as "deleted" which might result in a large set of affected files,
        // so the next compilation might compile much more files than is actually needed.
        Set<File> deltaBaseSources = Utils.errorsDetected(context)? Collections.emptySet() : inputFiles;
        delta = graphConfig.getGraph().createDelta(
          Iterators.map(deltaBaseSources, pathMapper::toNodeSource),
          Iterators.map(getRemovedPaths(chunk, dirtyFilesHolder), pathMapper::toNodeSource),
          false
        );
        for (var nodeData : callback.getNodes()) {
          delta.associate(nodeData.getFirst(), nodeData.getSecond());
        }
        // todo: consider using delta for marking additional sources for compilation
        //for (NodeSource src : delta.getBaseSources()) {
        //  if (!inputFiles.contains(src.getPath())) {
        //    FSOperations.markDirtyIfNotDeleted(context, CompilationRound.CURRENT, src.getPath().toFile());
        //  }
        //}
      }

      for (Key<?> key : List.of(GRAPH_DELTA_CALLBACK_KEY, FILES_TO_COMPILE_KEY, COMPILED_WITH_ERRORS_KEY, SUCCESSFULLY_COMPILED_FILES_KEY)) {
        key.set(context, null);
      }
      return delta != null && updateDependencyGraph(context, delta, chunk, CompilationRound.NEXT, createOrFilter(SKIP_MARKING_DIRTY_FILTERS_KEY.get(context)));
    }

    Mappings delta = null;

    final Pair<Mappings, Callbacks.Backend> pair = MAPPINGS_DELTA_KEY.get(context);
    if (pair != null) {
      MAPPINGS_DELTA_KEY.set(context, null);
      delta = pair.getFirst();
    }

    if (delta == null) {
      return false;
    }
    final Set<File> compiledFiles = getFilesContainer(context, FILES_TO_COMPILE_KEY);
    FILES_TO_COMPILE_KEY.set(context, null);
    final Set<File> successfullyCompiled = getFilesContainer(context, SUCCESSFULLY_COMPILED_FILES_KEY);
    SUCCESSFULLY_COMPILED_FILES_KEY.set(context, null);
    FileFilter filter = createOrFilter(SKIP_MARKING_DIRTY_FILTERS_KEY.get(context));
    return updateMappings(context, delta, dirtyFilesHolder, chunk, compiledFiles, successfullyCompiled, CompilationRound.NEXT, filter);
  }
@ApiStatus.Internal
  public static boolean updateMappingsOnRoundCompletion(
    CompileContext context, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, ModuleChunk chunk)