protected void doRun(
     @NotNull final ExecutionEnvironment environment, @NotNull final Runnable startRunnable) {
   Boolean allowSkipRun = environment.getUserData(EXECUTION_SKIP_RUN);
   if (allowSkipRun != null && allowSkipRun) {
     environment
         .getProject()
         .getMessageBus()
         .syncPublisher(EXECUTION_TOPIC)
         .processNotStarted(environment.getExecutor().getId(), environment);
   } else {
     // important! Do not use DumbService.smartInvokeLater here because it depends on modality
     // state
     // and execution of startRunnable could be skipped if modality state check fails
     //noinspection SSBasedInspection
     SwingUtilities.invokeLater(
         () -> {
           if (!myProject.isDisposed()) {
             if (!Registry.is("dumb.aware.run.configurations")) {
               DumbService.getInstance(myProject).runWhenSmart(startRunnable);
             } else {
               try {
                 DumbService.getInstance(myProject).setAlternativeResolveEnabled(true);
                 startRunnable.run();
               } catch (IndexNotReadyException ignored) {
                 ExecutionUtil.handleExecutionError(
                     environment,
                     new ExecutionException("cannot start while indexing is in progress."));
               } finally {
                 DumbService.getInstance(myProject).setAlternativeResolveEnabled(false);
               }
             }
           }
         });
   }
 }
  @Override
  public void compileAndRun(
      @NotNull final Runnable startRunnable,
      @NotNull final ExecutionEnvironment environment,
      @Nullable final RunProfileState state,
      @Nullable final Runnable onCancelRunnable) {
    long id = environment.getExecutionId();
    if (id == 0) {
      id = environment.assignNewExecutionId();
    }

    RunProfile profile = environment.getRunProfile();
    if (!(profile instanceof RunConfiguration)) {
      startRunnable.run();
      return;
    }

    final RunConfiguration runConfiguration = (RunConfiguration) profile;
    final List<BeforeRunTask> beforeRunTasks =
        RunManagerEx.getInstanceEx(myProject).getBeforeRunTasks(runConfiguration);
    if (beforeRunTasks.isEmpty()) {
      startRunnable.run();
    } else {
      DataContext context = environment.getDataContext();
      final DataContext projectContext =
          context != null ? context : SimpleDataContext.getProjectContext(myProject);
      final long finalId = id;
      final Long executionSessionId = new Long(id);
      ApplicationManager.getApplication()
          .executeOnPooledThread(
              () -> {
                for (BeforeRunTask task : beforeRunTasks) {
                  if (myProject.isDisposed()) {
                    return;
                  }
                  @SuppressWarnings("unchecked")
                  BeforeRunTaskProvider<BeforeRunTask> provider =
                      BeforeRunTaskProvider.getProvider(myProject, task.getProviderId());
                  if (provider == null) {
                    LOG.warn(
                        "Cannot find BeforeRunTaskProvider for id='" + task.getProviderId() + "'");
                    continue;
                  }
                  ExecutionEnvironment taskEnvironment =
                      new ExecutionEnvironmentBuilder(environment).contentToReuse(null).build();
                  taskEnvironment.setExecutionId(finalId);
                  EXECUTION_SESSION_ID_KEY.set(taskEnvironment, executionSessionId);
                  if (!provider.executeTask(
                      projectContext, runConfiguration, taskEnvironment, task)) {
                    if (onCancelRunnable != null) {
                      SwingUtilities.invokeLater(onCancelRunnable);
                    }
                    return;
                  }
                }

                doRun(environment, startRunnable);
              });
    }
  }