boolean (final String executorId, final ExecutionEnvironment environment, ProgramRunner<?> runner) { final Semaphore targetDone = new Semaphore(); final Ref<Boolean> result = new Ref<>(false); final Disposable disposable = Disposer.newDisposable(); environment.getProject().getMessageBus().connect(disposable).subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionListener() { @Override public void processStartScheduled(final @NotNull String executorIdLocal, final @NotNull ExecutionEnvironment environmentLocal) { if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) { targetDone.down(); } } @Override public void processNotStarted(final @NotNull String executorIdLocal, final @NotNull ExecutionEnvironment environmentLocal) { if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) { Boolean skipRun = environment.getUserData(ExecutionManagerImpl.EXECUTION_SKIP_RUN); if (skipRun != null && skipRun) { result.set(true); } targetDone.up(); } } @Override public void processTerminated(@NotNull String executorIdLocal, @NotNull ExecutionEnvironment environmentLocal, @NotNull ProcessHandler handler, int exitCode) { if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) { result.set(exitCode == 0); targetDone.up(); } } }); try { ApplicationManager.getApplication().invokeAndWait(() -> { try { runner.execute(environment); } catch (ExecutionException e) { targetDone.up(); LOG.error(e); } }, ModalityState.defaultModalityState()); } catch (Exception e) { LOG.error(e); Disposer.dispose(disposable); return false; } targetDone.waitFor(); Disposer.dispose(disposable); return result.get(); }