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();
  }
  @Nullable
  @ToDebugAPI
  public ExecutionResult startSession(
      final Executor executor,
      final ProgramRunner runner,
      final RunProfileState state,
      Project project)
      throws ExecutionException {
    assert ThreadUtils.isEventDispatchThread() : "must be called from EDT only";

    debuggerSettings = getDebuggerSettings(state);

    startListeningForJavascriptVM();
    try {
      executionResult = execute(executor, runner, state);
      if (executionResult == null) {
        chromeSessionCreateError("Can't start the process - execution result is empty");
        return null;
      }

      @NotNull ProcessHandler processHandler = executionResult.getProcessHandler();
      debugSession.setProcessHandler(processHandler);

      chromeEventProcessor.getReporter().setProcessHandler(processHandler);
    } catch (ExecutionException e) {
      chromeSessionCreateError("Can't start the process: " + e.getMessage());
      throw e;
    }
    return executionResult;
  }
  @Override
  @Nullable
  public DebuggerSession attachVirtualMachine(@NotNull DebugEnvironment environment)
      throws ExecutionException {
    ApplicationManager.getApplication().assertIsDispatchThread();
    final DebugProcessEvents debugProcess = new DebugProcessEvents(myProject);
    debugProcess.addDebugProcessListener(
        new DebugProcessAdapter() {
          @Override
          public void processAttached(final DebugProcess process) {
            process.removeDebugProcessListener(this);
            for (Function<DebugProcess, PositionManager> factory :
                myCustomPositionManagerFactories) {
              final PositionManager positionManager = factory.fun(process);
              if (positionManager != null) {
                process.appendPositionManager(positionManager);
              }
            }
            for (PositionManagerFactory factory :
                Extensions.getExtensions(PositionManagerFactory.EP_NAME, myProject)) {
              final PositionManager manager = factory.createPositionManager(debugProcess);
              if (manager != null) {
                process.appendPositionManager(manager);
              }
            }
          }

          @Override
          public void processDetached(final DebugProcess process, final boolean closedByUser) {
            debugProcess.removeDebugProcessListener(this);
          }

          @Override
          public void attachException(
              final RunProfileState state,
              final ExecutionException exception,
              final RemoteConnection remoteConnection) {
            debugProcess.removeDebugProcessListener(this);
          }
        });
    DebuggerSession session =
        DebuggerSession.create(environment.getSessionName(), debugProcess, environment);
    ExecutionResult executionResult = session.getProcess().getExecutionResult();
    if (executionResult == null) {
      return null;
    }
    session.getContextManager().addListener(mySessionListener);
    getContextManager()
        .setState(
            DebuggerContextUtil.createDebuggerContext(
                session, session.getContextManager().getContext().getSuspendContext()),
            session.getState(),
            DebuggerSession.Event.CONTEXT,
            null);

    final ProcessHandler processHandler = executionResult.getProcessHandler();

    synchronized (mySessions) {
      mySessions.put(processHandler, session);
    }

    if (!(processHandler instanceof RemoteDebugProcessHandler)) {
      // add listener only to non-remote process handler:
      // on Unix systems destroying process does not cause VMDeathEvent to be generated,
      // so we need to call debugProcess.stop() explicitly for graceful termination.
      // RemoteProcessHandler on the other hand will call debugProcess.stop() as a part of
      // destroyProcess() and detachProcess() implementation,
      // so we shouldn't add the listener to avoid calling stop() twice
      processHandler.addProcessListener(
          new ProcessAdapter() {
            @Override
            public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) {
              final DebugProcessImpl debugProcess = getDebugProcess(event.getProcessHandler());
              if (debugProcess != null) {
                // if current thread is a "debugger manager thread", stop will execute synchronously
                // it is KillableColoredProcessHandler responsibility to terminate VM
                debugProcess.stop(
                    willBeDestroyed
                        && !(event.getProcessHandler() instanceof KillableColoredProcessHandler));

                // wait at most 10 seconds: the problem is that debugProcess.stop() can hang if
                // there are troubles in the debuggee
                // if processWillTerminate() is called from AWT thread debugProcess.waitFor() will
                // block it and the whole app will hang
                if (!DebuggerManagerThreadImpl.isManagerThread()) {
                  if (SwingUtilities.isEventDispatchThread()) {
                    ProgressManager.getInstance()
                        .runProcessWithProgressSynchronously(
                            new Runnable() {
                              @Override
                              public void run() {
                                ProgressManager.getInstance()
                                    .getProgressIndicator()
                                    .setIndeterminate(true);
                                debugProcess.waitFor(10000);
                              }
                            },
                            "Waiting For Debugger Response",
                            false,
                            debugProcess.getProject());
                  } else {
                    debugProcess.waitFor(10000);
                  }
                }
              }
            }
          });
    }
    myDispatcher.getMulticaster().sessionCreated(session);
    return session;
  }