void (@NotNull ProgressIndicator indicator) { indicator.setIndeterminate(true); var targetDone = new Semaphore(); var result = new Ref<>(false); var disposable = Disposer.newDisposable(); project.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)) { 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 { environment.getRunner().execute(environment); } catch (ExecutionException e) { targetDone.up(); LOG.error(e); } }, ModalityState.defaultModalityState()); } catch (Exception e) { LOG.error(e); Disposer.dispose(disposable); return; } targetDone.waitFor(); Disposer.dispose(disposable); if (callback != null) { if (result.get()) { callback.onSuccess(); } else { callback.onFailure(); } } if (!result.get()) { ApplicationManager.getApplication().invokeLater(() -> { var window = ToolWindowManager.getInstance(project).getToolWindow(environment.getExecutor().getToolWindowId()); if (window != null) { window.activate(null, false, false); } }, project.getDisposed()); } }