@Override
  protected void perform(@NotNull final XDebugSession session, DataContext dataContext) {
    final XDebuggerEditorsProvider editorsProvider = session.getDebugProcess().getEditorsProvider();
    final XStackFrame stackFrame = session.getCurrentStackFrame();
    final XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
    if (evaluator == null) {
      return;
    }

    // replace data context, because we need to have it for the focused component, not the target component (if from the toolbar)
    Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
    if (focusOwner == null) {
      // maybe this is in the toolbar menu - use getMostRecentFocusOwner
      Window window = ComponentUtil.getWindow(dataContext.getData(PlatformCoreDataKeys.CONTEXT_COMPONENT));
      if (window != null) {
        focusOwner = window.getMostRecentFocusOwner();
      }
    }
    if (focusOwner != null && ClientId.isCurrentlyUnderLocalId()) {
      dataContext = DataManager.getInstance().getDataContext(focusOwner);
    }

    final VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
    XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(dataContext);
    getSelectedTextAsync(evaluator, dataContext)
            .onSuccess(pair -> {
              Promise<XExpression> expressionPromise = Promises.resolvedPromise(null);
              if (pair.first != null) {
                expressionPromise = Promises.resolvedPromise(XExpressionImpl.fromText(pair.first, pair.second));
              }
              else if (node != null) {
                expressionPromise = node.calculateEvaluationExpression();
              }
              expressionPromise.onSuccess(
                expression -> AppUIUtil.invokeOnEdt(() -> showDialog(session, file, editorsProvider, stackFrame, evaluator, expression)));
            });
  }
@Override
  protected void perform(@NotNull final XDebugSession session, DataContext dataContext)