@Override
  public String getToolTipText(MouseEvent e) {
    TreePath path = getPathForLocation(e.getX(), e.getY());
    if (path == null) return null;
    Object lastComponent = path.getLastPathComponent();
    if (!(lastComponent instanceof ProblemDescriptionNode node)) return null;

    if (!node.needCalculateTooltip()) return node.getToolTipText();

    Promise<@NlsContexts.Tooltip String> tooltipLazy = scheduledTooltipTasks.computeIfAbsent(node, key -> {
      final var tooltipManager = IdeTooltipManager.getInstance();
      final Component component = e.getComponent();

      return ReadAction.nonBlocking(() -> node.getToolTipText())
        .finishOnUiThread(ModalityState.any(), tooltipText -> tooltipManager.updateShownTooltip(component))
        .submit(AppExecutorUtil.getAppExecutorService())
        .onError(throwable -> {
          if (!(throwable instanceof CancellationException)) {
            LOG.error("Exception in ProblemDescriptionNode#getToolTipText", throwable);
          }
          scheduledTooltipTasks.remove(node);
        })
        .onSuccess(tooltipText -> scheduledTooltipTasks.remove(node));
    });

    if (tooltipLazy.isSucceeded()) {
      try {
        return tooltipLazy.blockingGet(0);
      }
      catch (TimeoutException | ExecutionException error) {
        LOG.error(error);
      }
    }
    return UIBundle.message("crumbs.calculating.tooltip");
  }
@Override
  public String getToolTipText(MouseEvent e)