@Override
  public void addChildren(@NotNull final XValueChildrenList children, final boolean last) {
    if (myObsolete) return;
    invokeNodeUpdate(() -> {
      if (myObsolete) return;
      List<XValueContainerNode<?>> newChildren;
      if (children.size() > 0) {
        newChildren = new ArrayList<>(children.size());
        if (myValueChildren == null) {
          myValueChildren = initChildrenList(children.size());
        }
        boolean valuesInline = XDebuggerSettingsManager.getInstance().getDataViewSettings().isShowValuesInline();
        InlineDebuggerHelper inlineHelper = getTree().getEditorsProvider().getInlineDebuggerHelper();
        for (int i = 0; i < children.size(); i++) {
          XValueNodeImpl node = new XValueNodeImpl(myTree, this, children.getName(i), children.getValue(i));
          myValueChildren.add(node);
          newChildren.add(node);

          if (valuesInline && inlineHelper.shouldEvaluateChildrenByDefault(node) && isUseGetChildrenHack(myTree)) { //todo[kb]: try to generify this dirty hack
            node.getChildren();
          }
        }
      }
      else {
        newChildren = new SmartList<>();
        if (myValueChildren == null) {
          myValueChildren = new SmartList<>();
        }
      }

      myTopGroups = createGroupNodes(children.getTopGroups(), myTopGroups, newChildren);
      myBottomGroups = createGroupNodes(children.getBottomGroups(), myBottomGroups, newChildren);
      myCachedAllChildren = null;
      fireNodesInserted(newChildren);
      if (last && myTemporaryMessageChildren != null) {
        final int[] ints = getNodesIndices(myTemporaryMessageChildren);
        final TreeNode[] removed = myTemporaryMessageChildren.toArray(new TreeNode[0]);
        myCachedAllChildren = null;
        myTemporaryMessageChildren = null;
        fireNodesRemoved(ints, removed);
      }
      myTree.childrenLoaded(this, newChildren, last);
    });
  }
@Override
  public void addChildren(@NotNull final XValueChildrenList children, final boolean last)