@Override
    public void contextAction(@NotNull SuspendContextImpl suspendContext) {
      if (myContainer.isObsolete()) return;
      if (myStackFramesIterator != null && myStackFramesIterator.hasNext()) {
        StackFrameProxyImpl frameProxy;
        CompletableFuture<List<XStackFrame>> framesAsync;
        boolean first = myAdded == 0;
        frameProxy = myStackFramesIterator.next();
        if (first && myTopFramesReady) {
          framesAsync = CompletableFuture.completedFuture(myTopFrames);
        }
        else {
          framesAsync = createStackFramesAsync(frameProxy).thenApply(fs -> {
            if (first && !myTopFramesReady) {
              myTopFrames = fs;
              myTopFramesReady = true;
            }
            return fs;
          });
        }

        framesAsync.thenAccept(frames -> {
          for (XStackFrame frame : ContainerUtil.notNullize(frames)) {
            if (first || showFrame(frame)) {
              if (frame instanceof JavaStackFrame) {
                ((JavaStackFrame)frame).getDescriptor().updateRepresentationNoNotify(null, () -> {
                  // repaint on icon change
                  addStackFrames(Collections.emptyList(), !myStackFramesIterator.hasNext());
                });
              }
              addFrameIfNeeded(frame, false);
            }
            else {
              rememberHiddenFrame(frame);
            }
          }

          // replace the rest with the related stack (if available)
          if (myAsyncStack != null) {
            schedule(suspendContext, null, myAsyncStack, null, true);
            return;
          }

          List<StackFrameItem> relatedStack = null;
          var creationStack = myCreationStack;
          XStackFrame topFrame = ContainerUtil.getFirstItem(frames);
          if (AsyncStacksToggleAction.isAsyncStacksEnabled(
            (XDebugSessionImpl)suspendContext.getDebugProcess().getXdebugProcess().getSession()) &&
              topFrame instanceof JavaStackFrame frame) {
            if (creationStack == null) {
              creationStack = DebuggerUtilsImpl.computeSafeIfAny(CreationStackTraceProvider.EP,
                                                                 p -> p.getCreationStackTrace(frame, suspendContext));
            }
            relatedStack = DebuggerUtilsImpl.computeSafeIfAny(AsyncStackTraceProvider.EP,
                                                              p -> p.getAsyncStackTrace(frame, suspendContext));
            if (relatedStack != null) {
              schedule(suspendContext, null, relatedStack, null, true);
              return;
            }
            // append agent stack after the next frame
            relatedStack = AsyncStacksUtils.getAgentRelatedStack(frameProxy, suspendContext);
          }

          schedule(suspendContext, myStackFramesIterator, relatedStack, creationStack, false);
        }).exceptionally(throwable -> DebuggerUtilsAsync.logError(throwable));
      }
      else if (myAsyncStack != null && myAddedAsync < myAsyncStack.size()) {
        appendRelatedStack(suspendContext, myAsyncStack.subList(myAddedAsync, myAsyncStack.size()));
      }
      else if (myCreationStack != null && myAddedAsync < myCreationStack.size()) {
        appendRelatedStack(suspendContext, myCreationStack.subList(myAddedAsync, myCreationStack.size()));
      }
      else {
        addStackFrames(Collections.emptyList(), true);
      }
    }
@Override
    public void contextAction(@NotNull SuspendContextImpl suspendContext)