Promise<Void> (@NotNull Runnable bgBuildAction, @Nullable Runnable edtPostRunnable) { if (!canInitiateNewActivity()) return Promises.rejectedPromise(); AsyncPromise<Void> result = new AsyncPromise<>(); AtomicReference<ProcessCanceledException> fail = new AtomicReference<>(); Runnable finalizer = new TreeRunnable("AbstractTreeUi.queueToBackground: finalizer") { @Override public void perform() { ProcessCanceledException exception = fail.get(); if (exception == null) { result.setResult(null); } else { result.setError(exception); } } }; registerWorkerTask(bgBuildAction); Runnable pooledThreadWithProgressRunnable = new TreeRunnable("AbstractTreeUi.queueToBackground: progress") { @Override public void perform() { try { AbstractTreeBuilder builder = getBuilder(); if (!canInitiateNewActivity()) { throw new ProcessCanceledException(); } builder.runBackgroundLoading(new TreeRunnable("AbstractTreeUi.queueToBackground: background") { @Override public void perform() { assertNotDispatchThread(); try { if (!canInitiateNewActivity()) { throw new ProcessCanceledException(); } execute(bgBuildAction); if (edtPostRunnable != null) { builder.updateAfterLoadedInBackground(new TreeRunnable("AbstractTreeUi.queueToBackground: update after") { @Override public void perform() { try { assertIsDispatchThread(); if (!canInitiateNewActivity()) { throw new ProcessCanceledException(); } execute(edtPostRunnable); } catch (ProcessCanceledException e) { fail.set(e); cancelUpdate(); } finally { unregisterWorkerTask(bgBuildAction, finalizer); } } }); } else { unregisterWorkerTask(bgBuildAction, finalizer); } } catch (ProcessCanceledException e) { fail.set(e); unregisterWorkerTask(bgBuildAction, finalizer); cancelUpdate(); } catch (Throwable t) { unregisterWorkerTask(bgBuildAction, finalizer); throw new RuntimeException(t); } } }); } catch (ProcessCanceledException e) { unregisterWorkerTask(bgBuildAction, finalizer); cancelUpdate(); } } }; Runnable pooledThreadRunnable = new TreeRunnable("AbstractTreeUi.queueToBackground") { @Override public void perform() { try { if (myProgress != null && ProgressIndicatorProvider.getGlobalProgressIndicator() != myProgress) { ProgressManager.getInstance().runProcess(pooledThreadWithProgressRunnable, myProgress); } else { execute(pooledThreadWithProgressRunnable); } } catch (ProcessCanceledException e) { fail.set(e); unregisterWorkerTask(bgBuildAction, finalizer); cancelUpdate(); } } }; if (isPassthroughMode()) { execute(pooledThreadRunnable); } else { myWorker.addFirst(pooledThreadRunnable); } return result; }