private static Runnable createTimeLimitedExecutionProcess(@NotNull ProcessHandler processHandler,
                                                            @NotNull ExecutionMode mode,
                                                            final @NotNull String presentableCmdline) {
    ProcessOutput outputCollected = new ProcessOutput();
    processHandler.addProcessListener(new ProcessAdapter() {
      @Override
      public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) {
        String eventText = event.getText();
        if (StringUtil.isNotEmpty(eventText)) {
          if (ProcessOutputType.isStdout(outputType)) {
            outputCollected.appendStdout(eventText);
          }
          else if (ProcessOutputType.isStderr(outputType)) {
            outputCollected.appendStderr(eventText);
          }
        }
      }
    });
    Throwable invocatorStack = new Throwable();
    return new Runnable() {
      private final Semaphore mySemaphore = new Semaphore();

      private final Runnable myProcessRunnable = () -> {
        try {
          final boolean finished = processHandler.waitFor(1000L * mode.getTimeout());
          if (!finished) {
            mode.onTimeout(processHandler, presentableCmdline, outputCollected, invocatorStack);
            processHandler.destroyProcess();
          }
        }
        finally {
          mySemaphore.up();
        }
      };

      @Override
      public void run() {
        mySemaphore.down();
        ApplicationManager.getApplication().executeOnPooledThread(myProcessRunnable);
        OSProcessHandler.checkEdtAndReadAction(processHandler);
        mySemaphore.waitFor();
      }
    };
  }
private static Runnable createTimeLimitedExecutionProcess(@NotNull ProcessHandler processHandler,
                                                            @NotNull ExecutionMode mode,
                                                            final @NotNull String presentableCmdline)