@Override
  public void computeChildren(@NotNull final XCompositeNode node) {
    if (node.isObsolete()) return;
    XStackFrame xFrame = getDescriptor().getXStackFrame();
    if (xFrame != null) {
      xFrame.computeChildren(node);
      return;
    }
    myDebugProcess
        .getManagerThread()
        .schedule(
            new DebuggerContextCommandImpl(
                myDebugProcess.getDebuggerContext(), myDescriptor.getFrameProxy().threadProxy()) {
              @Override
              public Priority getPriority() {
                return Priority.NORMAL;
              }

              @Override
              public void threadAction() {
                if (node.isObsolete()) return;
                XValueChildrenList children = new XValueChildrenList();
                buildVariablesThreadAction(getFrameDebuggerContext(), children, node);
                node.addChildren(children, true);
              }
            });
  }
  @Override
  public void evaluate(
      @NotNull final XExpression expression,
      @NotNull final XEvaluationCallback callback,
      @Nullable XSourcePosition expressionPosition) {
    myDebugProcess
        .getManagerThread()
        .schedule(
            new DebuggerContextCommandImpl(
                myDebugProcess.getDebuggerContext(),
                myStackFrame.getStackFrameProxy().threadProxy()) {
              @Override
              public Priority getPriority() {
                return Priority.NORMAL;
              }

              @Override
              public void threadAction() {
                if (DebuggerUIUtil.isObsolete(callback)) {
                  return;
                }

                JavaDebugProcess process = myDebugProcess.getXdebugProcess();
                if (process == null) {
                  callback.errorOccurred("No debug process");
                  return;
                }
                TextWithImports text = TextWithImportsImpl.fromXExpression(expression);
                NodeManagerImpl nodeManager = process.getNodeManager();
                WatchItemDescriptor descriptor =
                    nodeManager.getWatchItemDescriptor(null, text, null);
                EvaluationContextImpl evalContext =
                    myStackFrame
                        .getFrameDebuggerContext(getDebuggerContext())
                        .createEvaluationContext();
                if (evalContext == null) {
                  callback.errorOccurred("Context is not available");
                  return;
                }
                descriptor.setContext(evalContext);
                @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
                EvaluateException exception = descriptor.getEvaluateException();
                if (exception != null && descriptor.getValue() == null) {
                  callback.errorOccurred(exception.getMessage());
                  return;
                }
                callback.evaluated(
                    JavaValue.create(null, descriptor, evalContext, nodeManager, true));
              }
            });
  }
 DebuggerContextImpl getFrameDebuggerContext() {
   DebuggerManagerThreadImpl.assertIsManagerThread();
   DebuggerContextImpl context = myDebugProcess.getDebuggerContext();
   if (context.getFrameProxy() != getStackFrameProxy()) {
     SuspendContextImpl threadSuspendContext =
         SuspendManagerUtil.getSuspendContextForThread(
             context.getSuspendContext(), getStackFrameProxy().threadProxy());
     context =
         DebuggerContextImpl.createDebuggerContext(
             myDebugProcess.mySession,
             threadSuspendContext,
             getStackFrameProxy().threadProxy(),
             getStackFrameProxy());
     context.setPositionCache(myDescriptor.getSourcePosition());
     context.initCaches();
   }
   return context;
 }