private static int execInProcess(
     String compilerClassName,
     String[] arguments,
     CompilerEnvironment environment,
     PrintStream out,
     MessageCollector messageCollector) {
   try {
     messageCollector.report(
         CompilerMessageSeverity.INFO,
         "Using kotlinHome=" + environment.getKotlinPaths().getHomePath(),
         CompilerMessageLocation.NO_LOCATION);
     messageCollector.report(
         CompilerMessageSeverity.INFO,
         "Invoking in-process compiler "
             + compilerClassName
             + " with arguments "
             + Arrays.asList(arguments),
         CompilerMessageLocation.NO_LOCATION);
     Object rc =
         CompilerRunnerUtil.invokeExecMethod(
             compilerClassName,
             arguments,
             environment,
             messageCollector,
             out,
             /*usePreloader=*/ true);
     // exec() returns a K2JVMCompiler.ExitCode object, that class is not accessible here,
     // so we take it's contents through reflection
     return CompilerRunnerUtil.getReturnCodeFromObject(rc);
   } catch (Throwable e) {
     MessageCollectorUtil.reportException(messageCollector, e);
     return -1;
   }
 }
 private static void runInProcess(
     final String compilerClassName,
     final String[] arguments,
     final MessageCollector messageCollector,
     OutputItemsCollector collector,
     final CompilerEnvironment environment) {
   CompilerRunnerUtil.outputCompilerMessagesAndHandleExitCode(
       messageCollector,
       collector,
       new Function<PrintStream, Integer>() {
         @Override
         public Integer fun(PrintStream stream) {
           return execInProcess(
               compilerClassName, arguments, environment, stream, messageCollector);
         }
       });
 }
  private static void runOutOfProcess(
      String compilerClassName,
      String[] arguments,
      final MessageCollector messageCollector,
      final OutputItemsCollector itemCollector,
      CompilerEnvironment environment) {
    SimpleJavaParameters params = new SimpleJavaParameters();
    params.setJdk(new SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome()));
    params.setMainClass(compilerClassName);

    for (String arg : arguments) {
      params.getProgramParametersList().add(arg);
    }

    for (File jar :
        CompilerRunnerUtil.kompilerClasspath(environment.getKotlinPaths(), messageCollector)) {
      params.getClassPath().add(jar);
    }

    params.getVMParametersList().addParametersString("-Djava.awt.headless=true -Xmx512m");
    //        params.getVMParametersList().addParametersString("-agentlib:yjpagent=sampling");

    Sdk sdk = params.getJdk();

    assert sdk != null;

    GeneralCommandLine commandLine =
        JdkUtil.setupJVMCommandLine(
            ((JavaSdkType) sdk.getSdkType()).getVMExecutablePath(sdk), params, false);

    messageCollector.report(
        CompilerMessageSeverity.INFO,
        "Invoking out-of-process compiler with arguments: " + commandLine,
        CompilerMessageLocation.NO_LOCATION);

    try {
      final Process process = commandLine.createProcess();

      ApplicationManager.getApplication()
          .executeOnPooledThread(
              new Runnable() {
                @Override
                public void run() {
                  CompilerOutputParser.parseCompilerMessagesFromReader(
                      messageCollector,
                      new InputStreamReader(process.getInputStream()),
                      itemCollector);
                }
              });

      ApplicationManager.getApplication()
          .executeOnPooledThread(
              new Runnable() {
                @Override
                public void run() {
                  try {
                    FileUtil.loadBytes(process.getErrorStream());
                  } catch (IOException e) {
                    // Don't care
                  }
                }
              });

      int exitCode = process.waitFor();
      CompilerRunnerUtil.handleProcessTermination(exitCode, messageCollector);
    } catch (Exception e) {
      messageCollector.report(
          CompilerMessageSeverity.ERROR,
          "[Internal Error] " + e.getLocalizedMessage(),
          CompilerMessageLocation.NO_LOCATION);
    }
  }