@Override
  public void save(final @NotNull OutputFileObject fileObject) {
    final BinaryContent content = fileObject.getContent();
    boolean isTemp = false;
    final JavaFileObject.Kind outKind = fileObject.getKind();
    final Collection<File> sourceFiles = ContainerUtil.collect(fileObject.getSourceFiles().iterator());

    if (!sourceFiles.isEmpty() && content != null) {
      final List<String> sourcePaths = ContainerUtil.map(sourceFiles, f -> FileUtil.toSystemIndependentName(f.getPath()));
      
      JavaSourceRootDescriptor rootDescriptor = null;
      for (File srcFile : sourceFiles) {
        rootDescriptor = myContext.getProjectDescriptor().getBuildRootIndex().findJavaRootDescriptor(myContext, srcFile);
        if (rootDescriptor != null) {
          break;
        }
      }

      try {
        if (rootDescriptor != null) {
          isTemp = rootDescriptor.isTemp;
          if (!isTemp) {
            // first, handle [src->output] mapping and register paths for files_generated event
            if (outKind == JavaFileObject.Kind.CLASS) {
              myOutputConsumer.registerCompiledClass(rootDescriptor.target, new CompiledClass(fileObject.getFile(), sourceFiles, fileObject.getClassName(), content)); // todo: avoid array copying?
            }
            else {
              myOutputConsumer.registerOutputFile(rootDescriptor.target, fileObject.getFile(), sourcePaths);
            }
          }
        }
        else {
          // was not able to determine the source root descriptor or the source root is excluded from compilation (e.g. for annotation processors)
          if (outKind == JavaFileObject.Kind.CLASS) {
            myOutputConsumer.registerCompiledClass(null, new CompiledClass(fileObject.getFile(), sourceFiles, fileObject.getClassName(), content));
          }
        }
      }
      catch (IOException e) {
        myContext.processMessage(new CompilerMessage(JavaBuilder.getBuilderName(), e));
      }

      if (!isTemp && outKind == JavaFileObject.Kind.CLASS) {
        // register in mappings any non-temp class file
        try {
          final ClassReader reader = new FailSafeClassReader(content.getBuffer(), content.getOffset(), content.getLength());
          String fileName = JavaBuilderUtil.isDepGraphEnabled()?
            myChunkOutputRootName + "/" + FileUtil.toSystemIndependentName(fileObject.getRelativePath()) :
            FileUtil.toSystemIndependentName(fileObject.getFile().getPath());
          myMappingsCallback.associate(fileName, sourcePaths, reader, fileObject.isGenerated());
        }
        catch (Throwable e) {
          // need this to make sure that unexpected errors in, for example, ASM will not ruin the compilation
          final String message = JpsBuildBundle.message(
            "build.message.class.dependency.information.may.be.incomplete", fileObject.getFile().getPath()
          );
          LOG.info(message, e);
          for (String sourcePath : sourcePaths) {
            myContext.processMessage(new CompilerMessage(
              JavaBuilder.getBuilderName(), BuildMessage.Kind.WARNING, message + "\n" + CompilerMessage.getTextFromThrowable(e), sourcePath
            ));
          }
        }
      }
    }

    if (outKind == JavaFileObject.Kind.CLASS) {
      myContext.processMessage(new ProgressMessage(JpsBuildBundle.message("progress.message.writing.classes.0", myChunkName)));
      if (!isTemp && !sourceFiles.isEmpty()) {
        mySuccessfullyCompiled.addAll(sourceFiles);
      }
    }
  }
@Override
  public void save(final @NotNull OutputFileObject fileObject)