default <T> Promise<T> prepareTargetToCommandExecution(@NotNull ExecutionEnvironment env,
                                                         @NotNull Logger logger,
                                                         @NonNls String logFailureMessage,
                                                         @NotNull ThrowableComputable<? extends T, ? extends ExecutionException> afterPreparation)
    throws ExecutionException {
    Promise<Object> preparationTasks;
    final Project project = env.getProject();
    RunProfile runProfile = env.getRunProfile();
    if (((TargetEnvironmentAwareRunProfile)runProfile).needPrepareTarget()) {
      preparationTasks = ExecutionManager.getInstance(project).executePreparationTasks(env, this);
    }
    else {
      preparationTasks = Promises.resolvedPromise();
    }

    return preparationTasks.thenAsync((Object o) -> {
      AsyncPromise<@Nullable T> promise = new AsyncPromise<>();
      ProgressManager.getInstance().run(new Task.Backgroundable(project, ExecutionBundle.message("progress.title.starting.run.configuration", runProfile.getName())) {
        @Override
        public void run(@NotNull ProgressIndicator indicator) {
          try {
            promise.setResult(afterPreparation.compute());
          }
          catch (ProcessCanceledException e) {
            promise.setError(ExecutionBundle.message("canceled.starting.run.configuration"));
          }
          catch (ExecutionException t) {
            logger.warn(logFailureMessage, t);
            promise.setError(t);
          }
          catch (Throwable t) {
            logger.error(logFailureMessage, t);
            promise.setError(t);
          }
        }
      });
      return promise;
    });
  }
default <T> Promise<T> prepareTargetToCommandExecution(@NotNull ExecutionEnvironment env,
                                                         @NotNull Logger logger,
                                                         @NonNls String logFailureMessage,
                                                         @NotNull ThrowableComputable<? extends T, ? extends ExecutionException> afterPreparation)