@Override
    public void renderValue(@NotNull XValueTextRenderer renderer, @Nullable XValueNodeImpl node) {
      boolean compact = node != null;
      if (myError != null) {
        if (myValue.endsWith(myError)) {
          renderer.renderValue(myValue.substring(0, myValue.length() - myError.length()));
        }
        renderer.renderError(myError);
      } else {
        if (compact && node.getValueContainer() instanceof JavaValue) {
          final JavaValue container = (JavaValue) node.getValueContainer();

          if (container.getDescriptor().isArray()) {
            final ArrayReference value = (ArrayReference) container.getDescriptor().getValue();
            final ArrayType type = (ArrayType) container.getDescriptor().getType();
            if (type != null) {
              final String typeName = type.componentTypeName();
              if (TypeConversionUtil.isPrimitive(typeName)
                  || CommonClassNames.JAVA_LANG_STRING.equals(typeName)) {
                int size = value.length();
                int max =
                    Math.min(size, CommonClassNames.JAVA_LANG_STRING.equals(typeName) ? 5 : 10);
                // TODO [eu]: this is a quick fix for IDEA-136606, need to move this away from
                // EDT!!!
                final List<Value> values = value.getValues(0, max);
                int i = 0;
                final List<String> vals = new ArrayList<String>(max);
                while (i < values.size()) {
                  vals.add(StringUtil.first(values.get(i).toString(), 15, true));
                  i++;
                }
                String more = "";
                if (vals.size() < size) {
                  more = ", + " + (size - vals.size()) + " more";
                }

                renderer.renderValue("{" + StringUtil.join(vals, ", ") + more + "}");
                return;
              }
            }
          }
        }

        String value = myValue;
        if (myValueDescriptor.isString()) {
          renderer.renderStringValue(myValue, "\"\\", XValueNode.MAX_VALUE_LENGTH);
          return;
        } else if (myValueDescriptor.getLastRenderer() instanceof ToStringRenderer
            || myValueDescriptor.getLastRenderer() instanceof ToStringBasedRenderer) {
          value = StringUtil.wrapWithDoubleQuote(truncateToMaxLength(myValue));
        } else if (myValueDescriptor.getLastRenderer() instanceof CompoundReferenceRenderer) {
          value = truncateToMaxLength(myValue);
        }
        renderer.renderValue(value);
      }
    }
 private void addToChildrenFrom(
     Set<TextWithImports> expressions,
     XValueChildrenList children,
     EvaluationContextImpl evaluationContext) {
   for (TextWithImports text : expressions) {
     WatchItemDescriptor descriptor = myNodeManager.getWatchItemDescriptor(null, text, null);
     children.add(JavaValue.create(descriptor, evaluationContext, myNodeManager));
   }
 }
 protected void superBuildVariables(
     final EvaluationContextImpl evaluationContext, XValueChildrenList children)
     throws EvaluateException {
   final StackFrameProxyImpl frame = getStackFrameProxy();
   for (final LocalVariableProxyImpl local : frame.visibleVariables()) {
     final LocalVariableDescriptorImpl descriptor =
         myNodeManager.getLocalVariableDescriptor(null, local);
     children.add(JavaValue.create(descriptor, evaluationContext, myNodeManager));
   }
 }
  // copied from FrameVariablesTree
  private void buildVariables(
      DebuggerContextImpl debuggerContext,
      final EvaluationContextImpl evaluationContext,
      @NotNull DebugProcessImpl debugProcess,
      XValueChildrenList children,
      ObjectReference thisObjectReference,
      Location location)
      throws EvaluateException {
    final Set<String> visibleLocals = new HashSet<String>();
    if (NodeRendererSettings.getInstance().getClassRenderer().SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) {
      if (thisObjectReference != null
          && debugProcess.getVirtualMachineProxy().canGetSyntheticAttribute()) {
        final ReferenceType thisRefType = thisObjectReference.referenceType();
        if (thisRefType instanceof ClassType
            && location != null
            && thisRefType.equals(location.declaringType())
            && thisRefType.name().contains("$")) { // makes sense for nested classes only
          for (Field field : thisRefType.fields()) {
            if (DebuggerUtils.isSynthetic(field)
                && StringUtil.startsWith(
                    field.name(), FieldDescriptorImpl.OUTER_LOCAL_VAR_FIELD_PREFIX)) {
              final FieldDescriptorImpl fieldDescriptor =
                  myNodeManager.getFieldDescriptor(myDescriptor, thisObjectReference, field);
              children.add(JavaValue.create(fieldDescriptor, evaluationContext, myNodeManager));
              visibleLocals.add(fieldDescriptor.calcValueName());
            }
          }
        }
      }
    }

    boolean myAutoWatchMode = DebuggerSettings.getInstance().AUTO_VARIABLES_MODE;
    if (evaluationContext == null) {
      return;
    }
    final SourcePosition sourcePosition = debuggerContext.getSourcePosition();
    if (sourcePosition == null) {
      return;
    }

    try {
      if (!XDebuggerSettingsManager.getInstance().getDataViewSettings().isAutoExpressions()
          && !myAutoWatchMode) {
        // optimization
        superBuildVariables(evaluationContext, children);
      } else {
        final Map<String, LocalVariableProxyImpl> visibleVariables =
            getVisibleVariables(getStackFrameProxy());
        final Pair<Set<String>, Set<TextWithImports>> usedVars =
            ApplicationManager.getApplication()
                .runReadAction(
                    new Computable<Pair<Set<String>, Set<TextWithImports>>>() {
                      @Override
                      public Pair<Set<String>, Set<TextWithImports>> compute() {
                        return findReferencedVars(
                            ContainerUtil.union(visibleVariables.keySet(), visibleLocals),
                            sourcePosition);
                      }
                    });
        // add locals
        if (myAutoWatchMode) {
          for (String var : usedVars.first) {
            LocalVariableProxyImpl local = visibleVariables.get(var);
            if (local != null) {
              children.add(
                  JavaValue.create(
                      myNodeManager.getLocalVariableDescriptor(null, local),
                      evaluationContext,
                      myNodeManager));
            }
          }
        } else {
          superBuildVariables(evaluationContext, children);
        }
        final EvaluationContextImpl evalContextCopy =
            evaluationContext.createEvaluationContext(evaluationContext.getThisObject());
        evalContextCopy.setAutoLoadClasses(false);

        final Set<TextWithImports> extraVars =
            computeExtraVars(usedVars, sourcePosition, evaluationContext);

        // add extra vars
        addToChildrenFrom(extraVars, children, evaluationContext);

        // add expressions
        addToChildrenFrom(usedVars.second, children, evalContextCopy);
      }
    } catch (EvaluateException e) {
      if (e.getCause() instanceof AbsentInformationException) {
        children.add(
            new DummyMessageValueNode(
                MessageDescriptor.LOCAL_VARIABLES_INFO_UNAVAILABLE.getLabel(),
                XDebuggerUIConstants.INFORMATION_MESSAGE_ICON));
        // trying to collect values from variable slots
        try {
          for (Map.Entry<DecompiledLocalVariable, Value> entry :
              LocalVariablesUtil.fetchValues(getStackFrameProxy(), debugProcess).entrySet()) {
            children.add(
                JavaValue.create(
                    myNodeManager.getArgumentValueDescriptor(
                        null, entry.getKey(), entry.getValue()),
                    evaluationContext,
                    myNodeManager));
          }
        } catch (Exception ex) {
          LOG.info(ex);
        }
      } else {
        throw e;
      }
    }
  }
  // copied from DebuggerTree
  private void buildVariablesThreadAction(
      DebuggerContextImpl debuggerContext, XValueChildrenList children, XCompositeNode node) {
    try {
      final EvaluationContextImpl evaluationContext = debuggerContext.createEvaluationContext();
      if (evaluationContext == null) {
        return;
      }
      if (!debuggerContext.isEvaluationPossible()) {
        node.setErrorMessage(MessageDescriptor.EVALUATION_NOT_POSSIBLE.getLabel());
        // myChildren.add(myNodeManager.createNode(MessageDescriptor.EVALUATION_NOT_POSSIBLE,
        // evaluationContext));
      }

      final Location location = myDescriptor.getLocation();

      final ObjectReference thisObjectReference = myDescriptor.getThisObject();
      if (thisObjectReference != null) {
        ValueDescriptorImpl thisDescriptor =
            myNodeManager.getThisDescriptor(null, thisObjectReference);
        children.add(JavaValue.create(thisDescriptor, evaluationContext, myNodeManager));
      } else if (location != null) {
        StaticDescriptorImpl staticDecriptor =
            myNodeManager.getStaticDescriptor(myDescriptor, location.declaringType());
        if (staticDecriptor.isExpandable()) {
          children.addTopGroup(
              new JavaStaticGroup(staticDecriptor, evaluationContext, myNodeManager));
        }
      }

      DebugProcessImpl debugProcess = debuggerContext.getDebugProcess();
      if (debugProcess == null) {
        return;
      }

      // add last method return value if any
      final Pair<Method, Value> methodValuePair = debugProcess.getLastExecutedMethod();
      if (methodValuePair != null) {
        ValueDescriptorImpl returnValueDescriptor =
            myNodeManager.getMethodReturnValueDescriptor(
                myDescriptor, methodValuePair.getFirst(), methodValuePair.getSecond());
        children.add(JavaValue.create(returnValueDescriptor, evaluationContext, myNodeManager));
      }
      // add context exceptions
      for (Pair<Breakpoint, Event> pair :
          DebuggerUtilsEx.getEventDescriptors(debuggerContext.getSuspendContext())) {
        final Event debugEvent = pair.getSecond();
        if (debugEvent instanceof ExceptionEvent) {
          final ObjectReference exception = ((ExceptionEvent) debugEvent).exception();
          if (exception != null) {
            final ValueDescriptorImpl exceptionDescriptor =
                myNodeManager.getThrownExceptionObjectDescriptor(myDescriptor, exception);
            children.add(JavaValue.create(exceptionDescriptor, evaluationContext, myNodeManager));
          }
        }
      }

      try {
        buildVariables(
            debuggerContext,
            evaluationContext,
            debugProcess,
            children,
            thisObjectReference,
            location);
        // if (classRenderer.SORT_ASCENDING) {
        //  Collections.sort(myChildren, NodeManagerImpl.getNodeComparator());
        // }
      } catch (EvaluateException e) {
        node.setErrorMessage(e.getMessage());
        // myChildren.add(myNodeManager.createMessageNode(new MessageDescriptor(e.getMessage())));
      }
    } catch (InvalidStackFrameException e) {
      LOG.info(e);
      // myChildren.clear();
      // notifyCancelled();
    } catch (InternalException e) {
      if (e.errorCode() == 35) {
        node.setErrorMessage(DebuggerBundle.message("error.corrupt.debug.info", e.getMessage()));
        // myChildren.add(
        //  myNodeManager.createMessageNode(new
        // MessageDescriptor(DebuggerBundle.message("error.corrupt.debug.info", e.getMessage()))));
      } else {
        throw e;
      }
    }
  }