private boolean compileJava(CompileContext context,
                              ModuleChunk chunk,
                              Collection<? extends File> files,
                              Collection<? extends File> originalClassPath,
                              Collection<? extends File> originalPlatformCp,
                              Collection<? extends File> sourcePath,
                              DiagnosticOutputConsumer diagnosticSink,
                              OutputFileConsumer outputSink,
                              JavaCompilingTool compilingTool,
                              File moduleInfoFile) throws IOException {
    final Semaphore counter = new Semaphore();
    COUNTER_KEY.set(context, counter);

    final Set<JpsModule> modules = chunk.getModules();
    ProcessorConfigProfile profile = null;

    final JpsJavaCompilerConfiguration compilerConfig = JpsJavaExtensionService.getInstance().getCompilerConfiguration(
      context.getProjectDescriptor().getProject()
    );

    if (modules.size() == 1) {
      profile = compilerConfig.getAnnotationProcessingProfile(modules.iterator().next());
    }
    else {
      final String message = validateCycle(context, chunk);
      if (message != null) {
        diagnosticSink.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, message));
        return false;
      }
    }

    final Map<File, Set<File>> outs = buildOutputDirectoriesMap(context, chunk);
    try {
      final int targetLanguageLevel = getTargetPlatformLanguageVersion(chunk.representativeTarget().getModule());

      // when forking external javac, compilers from SDK 1.7 and higher are supported
      final Pair<String, Integer> forkSdk;
      if (shouldForkCompilerProcess(context, chunk, targetLanguageLevel, compilingTool)) {
        forkSdk = getForkedJavacSdk(diagnosticSink, chunk, targetLanguageLevel);
        if (forkSdk == null) {
          return false;
        }
      }
      else {
        forkSdk = null;
      }

      final int compilerSdkVersion = forkSdk == null ? JavaVersion.current().feature : forkSdk.getSecond();

      final Pair<Iterable<String>, Iterable<String>> vm_compilerOptions = getCompilationOptions(compilerSdkVersion, context, chunk, profile, compilingTool);
      final Iterable<String> vmOptions = vm_compilerOptions.first;
      final Iterable<String> options = vm_compilerOptions.second;

      Iterable<? extends File> effectivePlatformCp = calcEffectivePlatformCp(originalPlatformCp, options, compilingTool);
      if (effectivePlatformCp == null) {
        String text = JpsBuildBundle.message(
          "build.message.unsupported.compact.compilation.profile.was.requested", chunk.getName(), System.getProperty("java.version")
        );
        context.processMessage(new CompilerMessage(getBuilderName(), BuildMessage.Kind.ERROR, text));
        return false;
      }

      final Iterable<? extends File> platformCp;
      final Iterable<? extends File> classPath;
      final ModulePath modulePath;
      final Iterable<? extends File> upgradeModulePath;
      if (moduleInfoFile != null) { // has modules
        final ModulePathSplitter splitter = MODULE_PATH_SPLITTER.get(context);
        final Pair<ModulePath, Collection<File>> pair = splitter.splitPath(
          moduleInfoFile, outs.keySet(), ProjectPaths.getCompilationModulePath(chunk, false), collectAdditionalRequires(options)
        );
        final boolean useModulePathOnly = Boolean.parseBoolean(System.getProperty(USE_MODULE_PATH_ONLY_OPTION))/*compilerConfig.useModulePathOnly()*/;
        if (useModulePathOnly) {
          // in Java 9, named modules are not allowed to read classes from the classpath
          // moreover, the compiler requires all transitive dependencies to be on the module path
          ModulePath.Builder mpBuilder = ModulePath.newBuilder();
          for (File file : ProjectPaths.getCompilationModulePath(chunk, false)) {
            mpBuilder.add(pair.first.getModuleName(file), file);
          }
          modulePath = mpBuilder.create();
          classPath = Collections.emptyList();
        }
        else {
          // placing only explicitly referenced modules into the module path and the rest of deps to classpath
          modulePath = pair.first;
          classPath = pair.second;
        }
        // modules above the JDK in the order entry list make a module upgrade path
        upgradeModulePath = effectivePlatformCp;
        platformCp = Collections.emptyList();
      }
      else {
        modulePath = ModulePath.EMPTY;
        upgradeModulePath = Collections.emptyList();
        if (!Iterators.isEmpty(effectivePlatformCp) && (getChunkSdkVersion(chunk)) >= 9) {
          // if chunk's SDK is 9 or higher, there is no way to specify full platform classpath
          // because platform classes are stored in jimage binary files with unknown format.
          // Because of this we are clearing platform classpath so that javac will resolve against its own boot classpath
          // and prepending additional jars from the JDK configuration to compilation classpath
          platformCp = Collections.emptyList();
          classPath = Iterators.flat(effectivePlatformCp, originalClassPath);
        }
        else {
          platformCp = effectivePlatformCp;
          classPath = originalClassPath;
        }
      }

      final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);

      if (forkSdk != null) {
        updateCompilerUsageStatistics(context, "javac " + forkSdk.getSecond(), chunk);
        final ExternalJavacManager server = ensureJavacServerStarted(context);
        final CompilationPaths paths = CompilationPaths.create(platformCp, classPath, upgradeModulePath, modulePath, sourcePath);
        final int heapSize = Utils.suggestForkedCompilerHeapSize();
        return invokeJavac(compilerSdkVersion, context, chunk, compilingTool, options, files, classesConsumer, (_options, _files, _outSink) -> {
          logJavacCall(chunk, _options, "fork");
          return server.forkJavac(
            forkSdk.getFirst(), heapSize, vmOptions, _options, paths, _files, outs, diagnosticSink, _outSink, compilingTool, context.getCancelStatus(), true
          ).get();
        });
      }

      updateCompilerUsageStatistics(context, compilingTool.getDescription(), chunk);
      return invokeJavac(compilerSdkVersion, context, chunk, compilingTool, options, files, classesConsumer, (_options, _files, _outSink) -> {
        logJavacCall(chunk, _options, "in-process");
        return JavacMain.compile(
          _options, _files, classPath, platformCp, modulePath, upgradeModulePath, sourcePath, outs, diagnosticSink, _outSink, context.getCancelStatus(), compilingTool
        );
      });
    }
    finally {
      counter.waitFor();
    }
  }
private boolean compileJava(CompileContext context,
                              ModuleChunk chunk,
                              Collection<? extends File> files,
                              Collection<? extends File> originalClassPath,
                              Collection<? extends File> originalPlatformCp,
                              Collection<? extends File> sourcePath,
                              DiagnosticOutputConsumer diagnosticSink,
                              OutputFileConsumer outputSink,
                              JavaCompilingTool compilingTool,
                              File moduleInfoFile)