private void startProcess(Target target, Parameters configuration, Pair<Target, Parameters> key) {
    ProgramRunner runner =
        new DefaultProgramRunner() {
          @NotNull
          public String getRunnerId() {
            return "MyRunner";
          }

          public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) {
            return true;
          }
        };
    Executor executor = DefaultRunExecutor.getRunExecutorInstance();
    ProcessHandler processHandler = null;
    try {
      RunProfileState state = getRunProfileState(target, configuration, executor);
      ExecutionResult result = state.execute(executor, runner);
      //noinspection ConstantConditions
      processHandler = result.getProcessHandler();
    } catch (Exception e) {
      dropProcessInfo(key, ExceptionUtil.getUserStackTrace(e, LOG), processHandler);
      return;
    }
    processHandler.addProcessListener(getProcessListener(key));
    processHandler.startNotify();
  }
  private void initConsoleUI(Process process) {
    // Init console view
    myConsoleView = createConsoleView();
    myConsoleView.setBorder(new SideBorder(UIUtil.getBorderColor(), SideBorder.LEFT));

    myProcessHandler = createProcessHandler(process, myProvider.getCommandLineString());

    myConsoleExecuteActionHandler = createConsoleExecuteActionHandler();

    ProcessTerminatedListener.attach(myProcessHandler);

    myProcessHandler.addProcessListener(
        new ProcessAdapter() {
          @Override
          public void processTerminated(ProcessEvent event) {
            finishConsole();
          }
        });

    // Attach to process
    myConsoleView.attachToProcess(myProcessHandler);

    // Runner creating
    final Executor defaultExecutor =
        ExecutorRegistry.getInstance().getExecutorById(DefaultRunExecutor.EXECUTOR_ID);
    final DefaultActionGroup toolbarActions = new DefaultActionGroup();
    final ActionToolbar actionToolbar =
        ActionManager.getInstance()
            .createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false);

    // Runner creating
    final JPanel panel = new JPanel(new BorderLayout());
    panel.add(actionToolbar.getComponent(), BorderLayout.WEST);
    panel.add(myConsoleView.getComponent(), BorderLayout.CENTER);

    actionToolbar.setTargetComponent(panel);

    final RunContentDescriptor contentDescriptor =
        new RunContentDescriptor(
            myConsoleView, myProcessHandler, panel, constructConsoleTitle(myConsoleTitle));

    // tool bar actions
    final List<AnAction> actions =
        fillToolBarActions(toolbarActions, defaultExecutor, contentDescriptor);
    registerActionShortcuts(actions, getLanguageConsole().getConsoleEditor().getComponent());
    registerActionShortcuts(actions, panel);
    panel.updateUI();
    showConsole(defaultExecutor, contentDescriptor);

    // Run
    myProcessHandler.startNotify();
  }
    @Override
    public void startNotify() {
      addProcessListener(
          new ProcessAdapter() {
            @Override
            public void startNotified(ProcessEvent event) {
              try {
                myWaitFor.setTerminationCallback(
                    new Consumer<Integer>() {
                      @Override
                      public void consume(Integer integer) {
                        notifyProcessTerminated(integer);
                      }
                    });
              } finally {
                removeProcessListener(this);
              }
            }
          });

      super.startNotify();
    }
  @Override
  public void startRunProfile(
      @NotNull final RunProfileStarter starter,
      @NotNull final RunProfileState state,
      @NotNull final ExecutionEnvironment environment) {
    final Project project = environment.getProject();
    RunContentDescriptor reuseContent = getContentManager().getReuseContent(environment);
    if (reuseContent != null) {
      reuseContent.setExecutionId(environment.getExecutionId());
      environment.setContentToReuse(reuseContent);
    }

    final Executor executor = environment.getExecutor();
    project
        .getMessageBus()
        .syncPublisher(EXECUTION_TOPIC)
        .processStartScheduled(executor.getId(), environment);

    Runnable startRunnable;
    startRunnable =
        () -> {
          if (project.isDisposed()) {
            return;
          }

          RunProfile profile = environment.getRunProfile();
          boolean started = false;
          try {
            project
                .getMessageBus()
                .syncPublisher(EXECUTION_TOPIC)
                .processStarting(executor.getId(), environment);

            final RunContentDescriptor descriptor = starter.execute(state, environment);
            if (descriptor != null) {
              final Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>
                  trinity =
                      Trinity.create(
                          descriptor, environment.getRunnerAndConfigurationSettings(), executor);
              myRunningConfigurations.add(trinity);
              Disposer.register(descriptor, () -> myRunningConfigurations.remove(trinity));
              getContentManager()
                  .showRunContent(executor, descriptor, environment.getContentToReuse());
              final ProcessHandler processHandler = descriptor.getProcessHandler();
              if (processHandler != null) {
                if (!processHandler.isStartNotified()) {
                  processHandler.startNotify();
                }
                project
                    .getMessageBus()
                    .syncPublisher(EXECUTION_TOPIC)
                    .processStarted(executor.getId(), environment, processHandler);
                started = true;

                ProcessExecutionListener listener =
                    new ProcessExecutionListener(
                        project, executor.getId(), environment, processHandler, descriptor);
                processHandler.addProcessListener(listener);

                // Since we cannot guarantee that the listener is added before process handled is
                // start notified,
                // we have to make sure the process termination events are delivered to the clients.
                // Here we check the current process state and manually deliver events, while
                // the ProcessExecutionListener guarantees each such event is only delivered once
                // either by this code, or by the ProcessHandler.

                boolean terminating = processHandler.isProcessTerminating();
                boolean terminated = processHandler.isProcessTerminated();
                if (terminating || terminated) {
                  listener.processWillTerminate(
                      new ProcessEvent(processHandler), false /*doesn't matter*/);

                  if (terminated) {
                    //noinspection ConstantConditions
                    int exitCode = processHandler.getExitCode();
                    listener.processTerminated(new ProcessEvent(processHandler, exitCode));
                  }
                }
              }
              environment.setContentToReuse(descriptor);
            }
          } catch (ProcessCanceledException e) {
            LOG.info(e);
          } catch (ExecutionException e) {
            ExecutionUtil.handleExecutionError(project, executor.getToolWindowId(), profile, e);
            LOG.info(e);
          } finally {
            if (!started) {
              project
                  .getMessageBus()
                  .syncPublisher(EXECUTION_TOPIC)
                  .processNotStarted(executor.getId(), environment);
            }
          }
        };

    if (ApplicationManager.getApplication().isUnitTestMode() && !myForceCompilationInTests) {
      startRunnable.run();
    } else {
      compileAndRun(
          () -> TransactionGuard.submitTransaction(project, startRunnable),
          environment,
          state,
          () -> {
            if (!project.isDisposed()) {
              project
                  .getMessageBus()
                  .syncPublisher(EXECUTION_TOPIC)
                  .processNotStarted(executor.getId(), environment);
            }
          });
    }
  }