void registerListener(@NotNull Disposable lifetime,
                          @Nullable ProgressIndicator uiIndicator,
                          @NotNull Consumer<? super Boolean> completedCallback) {
      myModalityTracker.updateModality();

      //there is no need to add yet another copy of the same component
      if (!myCompleteListeners.add(completedCallback)) return;

      // make the UI indicator receive events, when the background task runs
      if (uiIndicator instanceof ProgressIndicatorEx indicatorEx) {
        myProgressIndicator.addStateDelegate(indicatorEx);
      }

      Disposable unsubscribe = new Disposable() {
        @Override
        public void dispose() {
          if (uiIndicator instanceof ProgressIndicatorEx indicatorEx) {
            myProgressIndicator.removeStateDelegate(indicatorEx);
          }
          myCompleteListeners.remove(completedCallback);
          myDisposables.remove(this);
        }
      };
      Disposer.register(lifetime, unsubscribe);
      myDisposables.add(unsubscribe);
    }
void registerListener(@NotNull Disposable lifetime,
                          @Nullable ProgressIndicator uiIndicator,
                          @NotNull Consumer<? super Boolean> completedCallback)