ActionCallback (@NotNull Progressive progressive) { assertIsDispatchThread(); EmptyProgressIndicator indicator = new EmptyProgressIndicator(); ActionCallback callback = new ActionCallback(); myBatchIndicators.put(progressive, indicator); myBatchCallbacks.put(progressive, callback); try { progressive.run(indicator); } catch (ProcessCanceledException e) { resetToReadyNow().doWhenProcessed(new TreeRunnable("AbstractTreeUi.batch: catch") { @Override public void perform() { callback.setRejected(); } }); return callback; } finally { if (isReleased()) return ActionCallback.REJECTED; _getReady().doWhenDone(new TreeRunnable("AbstractTreeUi.batch: finally") { @Override public void perform() { if (myBatchIndicators.containsKey(progressive)) { ProgressIndicator indicator = myBatchIndicators.remove(progressive); myBatchCallbacks.remove(progressive); if (indicator.isCanceled()) { callback.setRejected(); } else { callback.setDone(); } } else { callback.setRejected(); } } }); maybeReady(); } return callback; }