@Override
  public Collection<ClassObject> compileJavaCode(List<String> options,
                                                 Collection<? extends File> platformCp,
                                                 Collection<? extends File> classpath,
                                                 Collection<? extends File> upgradeModulePath,
                                                 Collection<? extends File> modulePath,
                                                 Collection<? extends File> sourcePath,
                                                 Collection<? extends File> files,
                                                 File outputDir) throws IOException, CompilationException {
    final Pair<Sdk, JavaSdkVersion> runtime = BuildManager.getJavacRuntimeSdk(myProject);

    final Sdk sdk = runtime.getFirst();
    final SdkTypeId type = sdk.getSdkType();
    String javaHome = null;
    if (type instanceof JavaSdkType) {
      javaHome = sdk.getHomePath();
      if (!isJdkOrJre(javaHome)) {
        // this can be a java-dependent SDK, implementing JavaSdkType
        // hack, because there is no direct way to obtain the java sdk, this sdk depends on
        final String binPath = ((JavaSdkType)type).getBinPath(sdk);
        javaHome = binPath != null? new File(binPath).getParent() : null;
        if (!isJdkOrJre(javaHome)) {
          javaHome = null;
        }
      }
    }
    if (javaHome == null) {
      throw new IOException("Was not able to determine JDK for project " + myProject.getName());
    }

    final OutputCollector outputCollector = new OutputCollector();
    DiagnosticCollector diagnostic = new DiagnosticCollector();

    final Set<File> sourceRoots = FileCollectionFactory.createCanonicalFileSet();
    if (!sourcePath.isEmpty()) {
      sourceRoots.addAll(sourcePath);
    }
    else {
      for (File file : files) {
        final File parentFile = file.getParentFile();
        if (parentFile != null) {
          sourceRoots.add(parentFile);
        }
      }
    }
    final Map<File, Set<File>> outs = Collections.singletonMap(outputDir, sourceRoots);

    final ExternalJavacManager javacManager = getJavacManager();
    final CompilationPaths paths = CompilationPaths.create(platformCp, classpath, upgradeModulePath, ModulePath.create(modulePath), sourcePath);
    // do not keep process alive in tests since every test expects all spawned processes to terminate in teardown
    boolean compiledOk = javacManager != null && javacManager.forkJavac(
      javaHome, -1, Collections.emptyList(), options, paths, files, outs, diagnostic, outputCollector,
      new JavacCompilerTool(), CanceledStatus.NULL, !ApplicationManager.getApplication().isUnitTestMode()
    ).get();

    if (!compiledOk) {
      final List<CompilationException.Message> messages = new SmartList<>();
      for (Diagnostic<? extends JavaFileObject> d : diagnostic.getDiagnostics()) {
        final JavaFileObject source = d.getSource();
        final URI uri = source != null ? source.toUri() : null;
        messages.add(new CompilationException.Message(
          kindToCategory(d.getKind()), d.getMessage(Locale.US), uri != null? uri.toURL().toString() : null, (int)d.getLineNumber(), (int)d.getColumnNumber()
        ));
      }
      throw new CompilationException("Compilation failed", messages);
    }

    final List<ClassObject> result = new ArrayList<>();
    for (OutputFileObject fileObject : outputCollector.getCompiledClasses()) {
      final BinaryContent content = fileObject.getContent();
      result.add(new CompiledClass(fileObject.getName(), fileObject.getClassName(), content != null ? content.toByteArray() : null));
    }
    return result;
  }
@Override
  public Collection<ClassObject> compileJavaCode(List<String> options,
                                                 Collection<? extends File> platformCp,
                                                 Collection<? extends File> classpath,
                                                 Collection<? extends File> upgradeModulePath,
                                                 Collection<? extends File> modulePath,
                                                 Collection<? extends File> sourcePath,
                                                 Collection<? extends File> files,
                                                 File outputDir)