protected ExecutionResult startSMRunner(Executor executor) throws ExecutionException {
    if (!isSmRunnerUsed()) {
      return null;
    }
    getJavaParameters()
        .getVMParametersList()
        .addProperty("idea." + getFrameworkId() + ".sm_runner");

    final RunnerSettings runnerSettings = getRunnerSettings();

    final SMTRunnerConsoleProperties testConsoleProperties =
        getConfiguration().createTestConsoleProperties(executor);
    testConsoleProperties.setIfUndefined(TestConsoleProperties.HIDE_PASSED_TESTS, false);

    final BaseTestsOutputConsoleView consoleView =
        SMTestRunnerConnectionUtil.createConsole(getFrameworkName(), testConsoleProperties);
    final SMTestRunnerResultsForm viewer = ((SMTRunnerConsoleView) consoleView).getResultsViewer();
    Disposer.register(getConfiguration().getProject(), consoleView);

    final OSProcessHandler handler = createHandler(executor);
    consoleView.attachToProcess(handler);
    handler.addProcessListener(
        new ProcessAdapter() {
          @Override
          public void startNotified(ProcessEvent event) {
            if (getConfiguration().isSaveOutputToFile()) {
              viewer.getRoot().setOutputFilePath(getConfiguration().getOutputFilePath());
            }
          }

          @Override
          public void processTerminated(ProcessEvent event) {
            Runnable runnable =
                new Runnable() {
                  public void run() {
                    viewer.getRoot().flush();
                    deleteTempFiles();
                    clear();
                  }
                };
            UIUtil.invokeLaterIfNeeded(runnable);
            handler.removeProcessListener(this);
          }
        });

    AbstractRerunFailedTestsAction rerunFailedTestsAction =
        testConsoleProperties.createRerunFailedTestsAction(consoleView);
    LOG.assertTrue(rerunFailedTestsAction != null);
    rerunFailedTestsAction.setModelProvider(
        new Getter<TestFrameworkRunningModel>() {
          @Override
          public TestFrameworkRunningModel get() {
            return viewer;
          }
        });

    final DefaultExecutionResult result = new DefaultExecutionResult(consoleView, handler);
    result.setRestartActions(rerunFailedTestsAction);

    JavaRunConfigurationExtensionManager.getInstance()
        .attachExtensionsToProcess(getConfiguration(), handler, runnerSettings);
    return result;
  }
  @Override
  public ExecutionResult execute(final Executor executor, @NotNull final ProgramRunner runner)
      throws ExecutionException {
    final JUnitProcessHandler handler = createHandler(executor);
    final RunnerSettings runnerSettings = getRunnerSettings();
    JavaRunConfigurationExtensionManager.getInstance()
        .attachExtensionsToProcess(myConfiguration, handler, runnerSettings);
    final TestProxy unboundOutputRoot = new TestProxy(new RootTestInfo());
    final JUnitConsoleProperties consoleProperties =
        new JUnitConsoleProperties(myConfiguration, executor);
    final JUnitTreeConsoleView consoleView =
        new JUnitTreeConsoleView(
            consoleProperties, runnerSettings, getConfigurationSettings(), unboundOutputRoot);
    consoleView.initUI();
    consoleView.attachToProcess(handler);
    unboundOutputRoot.setPrinter(consoleView.getPrinter());
    Disposer.register(consoleView, unboundOutputRoot);
    final TestsPacketsReceiver packetsReceiver =
        new TestsPacketsReceiver(consoleView, unboundOutputRoot) {
          @Override
          public void notifyStart(TestProxy root) {
            if (!isRunning()) return;
            super.notifyStart(root);
            unboundOutputRoot.addChild(root);
            if (myConfiguration.isSaveOutputToFile()) {
              unboundOutputRoot.setOutputFilePath(myConfiguration.getOutputFilePath());
            }
            final JUnitRunningModel model = getModel();
            if (model != null) {
              handler.getOut().setDispatchListener(model.getNotifier());
              Disposer.register(
                  model,
                  new Disposable() {
                    @Override
                    public void dispose() {
                      handler.getOut().setDispatchListener(DispatchListener.DEAF);
                    }
                  });
              consoleView.attachToModel(model);
            }
          }
        };

    final DeferredActionsQueue queue = new DeferredActionsQueueImpl();
    handler.getOut().setPacketDispatcher(packetsReceiver, queue);
    handler.getErr().setPacketDispatcher(packetsReceiver, queue);

    handler.addProcessListener(
        new ProcessAdapter() {
          private boolean myStarted = false;

          @Override
          public void startNotified(ProcessEvent event) {
            myStarted = true;
          }

          @Override
          public void processTerminated(ProcessEvent event) {
            handler.removeProcessListener(this);
            if (myTempFile != null) {
              FileUtil.delete(myTempFile);
            }
            if (myListenersFile != null) {
              FileUtil.delete(myListenersFile);
            }
            IJSwingUtilities.invoke(
                new Runnable() {
                  @Override
                  public void run() {
                    try {
                      unboundOutputRoot.flush();
                      packetsReceiver.checkTerminated();
                      final JUnitRunningModel model = packetsReceiver.getModel();
                      notifyByBalloon(model, myStarted, consoleProperties);
                    } finally {
                      if (ApplicationManager.getApplication().isUnitTestMode()) {
                        Disposer.dispose(consoleView);
                      }
                    }
                  }
                });
          }

          @Override
          public void onTextAvailable(final ProcessEvent event, final Key outputType) {
            final String text = event.getText();
            final ConsoleViewContentType consoleViewType =
                ConsoleViewContentType.getConsoleViewType(outputType);
            final Printable printable =
                new Printable() {
                  @Override
                  public void printOn(final Printer printer) {
                    printer.print(text, consoleViewType);
                  }
                };
            final Extractor extractor;
            if (consoleViewType == ConsoleViewContentType.ERROR_OUTPUT
                || consoleViewType == ConsoleViewContentType.SYSTEM_OUTPUT) {
              extractor = handler.getErr();
            } else {
              extractor = handler.getOut();
            }
            extractor.getEventsDispatcher().processOutput(printable);
          }
        });

    if (ApplicationManager.getApplication().isUnitTestMode()) {
      return new DefaultExecutionResult(null, handler);
    }

    final RerunFailedTestsAction rerunFailedTestsAction = new RerunFailedTestsAction(consoleView);
    rerunFailedTestsAction.init(consoleProperties, myEnvironment);
    rerunFailedTestsAction.setModelProvider(
        new Getter<TestFrameworkRunningModel>() {
          @Override
          public TestFrameworkRunningModel get() {
            return packetsReceiver.getModel();
          }
        });

    final DefaultExecutionResult result = new DefaultExecutionResult(consoleView, handler);
    result.setRestartActions(rerunFailedTestsAction);
    return result;
  }