@NotNull
  private static Consumer<Boolean> startProgressAndCreateStopAction(Project project,
                                                                    @NlsContexts.ProgressTitle String progressTitle,
                                                                    AtomicReference<? extends CancellablePromise<?>> promiseRef,
                                                                    Editor editor) {
    AtomicReference<Consumer<Boolean>> stopActionRef = new AtomicReference<>();

    Consumer<Boolean> originalStopAction = (cancel) -> {
      stopActionRef.set(null);
      if (cancel) {
        CancellablePromise<?> promise = promiseRef.get();
        if (promise != null) {
          promise.cancel();
        }
      }
    };

    if (progressTitle == null) {
      stopActionRef.set(originalStopAction);
    } else {
      final Disposable disposable = Disposer.newDisposable();
      Disposer.register(project, disposable);

      JBLoadingPanel loadingPanel =
        new JBLoadingPanel(null, panel -> new LoadingDecorator(panel, disposable, 0, false, new AsyncProcessIcon("ShowParameterInfo")) {
          @Override
          protected NonOpaquePanel customizeLoadingLayer(JPanel parent, JLabel text, AnimatedIcon icon) {
            parent.setLayout(new FlowLayout(FlowLayout.LEFT));
            final NonOpaquePanel result = new NonOpaquePanel();
            result.add(icon);
            parent.add(result);
            return result;
          }
        });
      loadingPanel.add(new JBLabel(EmptyIcon.ICON_18));
      loadingPanel.add(new JBLabel(progressTitle));

      ComponentPopupBuilder builder =
        JBPopupFactory.getInstance().createComponentPopupBuilder(loadingPanel, null)
          .setProject(project)
          .setCancelCallback(() -> {
            Consumer<Boolean> stopAction = stopActionRef.get();
            if (stopAction != null) {
              stopAction.accept(true);
            }
            return true;
          });
      JBPopup popup = builder.createPopup();
      Disposer.register(disposable, popup);
      ScheduledFuture<?> showPopupFuture = EdtScheduledExecutorService.getInstance().schedule(() -> {
        if (!popup.isDisposed() && !popup.isVisible() && !editor.isDisposed()) {
          RelativePoint popupPosition = JBPopupFactory.getInstance().guessBestPopupLocation(editor);
          loadingPanel.startLoading();
          popup.show(popupPosition);
        }
      }, ModalityState.defaultModalityState(), DEFAULT_PROGRESS_POPUP_DELAY_MS, TimeUnit.MILLISECONDS);

      stopActionRef.set((cancel) -> {
        try {
          loadingPanel.stopLoading();
          originalStopAction.accept(cancel);
        } finally {
          showPopupFuture.cancel(false);
          UIUtil.invokeLaterIfNeeded(() -> {
            if (popup.isVisible()) {
              popup.setUiVisible(false);
            }
            Disposer.dispose(disposable);
          });
        }
      });
    }

    return stopActionRef.get();
  }
@NotNull
  private static Consumer<Boolean> startProgressAndCreateStopAction(Project project,
                                                                    @NlsContexts.ProgressTitle String progressTitle,
                                                                    AtomicReference<? extends CancellablePromise<?>> promiseRef,
                                                                    Editor editor)