@Override
  public void processSessionEvent(@NotNull final SessionEvent event) {
    XStackFrame stackFrame = mySession.getCurrentStackFrame();
    XDebuggerTree tree = myTreePanel.getTree();

    if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) {
      if (myTreeRestorer != null) {
        myTreeRestorer.dispose();
      }
      myTreeState = XDebuggerTreeState.saveState(tree);
      if (event == SessionEvent.BEFORE_RESUME) {
        return;
      }
    }

    if (stackFrame != null) {
      tree.setSourcePosition(stackFrame.getSourcePosition());
      myRootNode.updateWatches(stackFrame.getEvaluator());
      if (myTreeState != null) {
        myTreeRestorer = myTreeState.restoreState(tree);
      }
    } else {
      tree.setSourcePosition(null);
      myRootNode.updateWatches(null);
    }
  }
  @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);
              }
            });
  }
  void onIsolatePaused(
      @NotNull final IsolateRef isolateRef,
      @Nullable final ElementList<Breakpoint> vmBreakpoints,
      @Nullable final InstanceRef exception,
      @Nullable final Frame vmTopFrame,
      boolean atAsyncSuspension) {
    if (vmTopFrame == null) {
      myDebugProcess.getSession().positionReached(new XSuspendContext() {});
      return;
    }

    final DartVmServiceSuspendContext suspendContext =
        new DartVmServiceSuspendContext(
            myDebugProcess, isolateRef, vmTopFrame, exception, atAsyncSuspension);
    final XStackFrame xTopFrame = suspendContext.getActiveExecutionStack().getTopFrame();
    final XSourcePosition sourcePosition = xTopFrame == null ? null : xTopFrame.getSourcePosition();

    if (vmBreakpoints == null || vmBreakpoints.isEmpty()) {
      final StepOption latestStep = myDebugProcess.getVmServiceWrapper().getLatestStep();

      if (latestStep == StepOption.Over
          && equalSourcePositions(myLatestSourcePosition, sourcePosition)) {
        // continue stepping to change current line
        myDebugProcess.getVmServiceWrapper().resumeIsolate(isolateRef.getId(), latestStep);
      } else {
        myLatestSourcePosition = sourcePosition;
        myDebugProcess.getSession().positionReached(suspendContext);
      }
    } else {
      if (vmBreakpoints.size() > 1) {
        // Shouldn't happen. IDE doesn't allow to set 2 breakpoints on one line.
        LOG.error(vmBreakpoints.size() + " breakpoints hit in one shot.");
      }

      // Remove any temporary (run to cursor) breakpoints.
      myBreakpointHandler.removeTemporaryBreakpoints(isolateRef.getId());

      final XLineBreakpoint<XBreakpointProperties> xBreakpoint =
          myBreakpointHandler.getXBreakpoint(vmBreakpoints.get(0));

      if (xBreakpoint == null) {
        // breakpoint could be set in the Observatory
        myLatestSourcePosition = sourcePosition;
        myDebugProcess.getSession().positionReached(suspendContext);
        return;
      }

      if ("false"
          .equals(
              evaluateExpression(
                  isolateRef.getId(), vmTopFrame, xBreakpoint.getConditionExpression()))) {
        myDebugProcess.getVmServiceWrapper().resumeIsolate(isolateRef.getId(), null);
        return;
      }

      myLatestSourcePosition = sourcePosition;

      final String logExpression =
          evaluateExpression(isolateRef.getId(), vmTopFrame, xBreakpoint.getLogExpressionObject());
      final boolean suspend =
          myDebugProcess.getSession().breakpointReached(xBreakpoint, logExpression, suspendContext);
      if (!suspend) {
        myDebugProcess.getVmServiceWrapper().resumeIsolate(isolateRef.getId(), null);
      }
    }
  }
 protected void customizeInvalidFramePresentation(ColoredTextContainer component) {
   super.customizePresentation(component);
 }
 @Nullable
 public XDebuggerEvaluator getEvaluator() {
   XStackFrame frame = getSession().getCurrentStackFrame();
   return frame == null ? null : frame.getEvaluator();
 }