private void buildVariables(DebuggerContextImpl debuggerContext,
                              @NotNull final EvaluationContextImpl evaluationContext,
                              @NotNull DebugProcessImpl debugProcess,
                              XValueChildrenList children,
                              ObjectReference thisObjectReference,
                              Location location) throws EvaluateException {
    final Set<String> visibleLocals = new HashSet<>();
    int positionOfLocalVariablesAsFields = children.size();
    final List<FieldDescriptorImpl> outerLocalVariablesAsFields = new SmartList<>();
    if (NodeRendererSettings.getInstance().getClassRenderer().SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) {
      if (thisObjectReference != null && evaluationContext.getSuspendContext().getVirtualMachine().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);
              outerLocalVariablesAsFields.add(fieldDescriptor);
              visibleLocals.add(fieldDescriptor.calcValueName());
            }
          }
        }
      }
    }

    boolean myAutoWatchMode = DebuggerSettings.getInstance().AUTO_VARIABLES_MODE;

    try {
      if (!XDebuggerSettingsManager.getInstance().getDataViewSettings().isAutoExpressions() && !myAutoWatchMode) {
        // optimization
        superBuildVariables(evaluationContext, children);
      }
      else {
        final SourcePosition sourcePosition = debuggerContext.getSourcePosition();
        final Map<String, LocalVariableProxyImpl> visibleVariables =
          ContainerUtil.map2Map(getVisibleVariables(),
                                var -> Pair.create(var.name(), var));

        Pair<Set<String>, Set<TextWithImports>> usedVars = EMPTY_USED_VARS;
        if (sourcePosition != null) {
          usedVars = ReadAction.compute(
            () -> DumbService.isDumb(debugProcess.getProject())
                  ? EMPTY_USED_VARS
                  : findReferencedVars(ContainerUtil.union(visibleVariables.keySet(), visibleLocals), sourcePosition));
        }
        // add locals
        if (myAutoWatchMode) {
          List<LocalVariableProxyImpl> localVariables = usedVars.first.stream()
            .map(var -> visibleVariables.get(var))
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
          buildLocalVariables(evaluationContext, children, localVariables);
        }
        else {
          superBuildVariables(evaluationContext, children);
        }
        final EvaluationContextImpl evalContextCopy = evaluationContext.withAutoLoadClasses(false);

        if (sourcePosition != null) {
          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(LOCAL_VARIABLES_INFO_UNAVAILABLE_MESSAGE_NODE);
        // trying to collect values from variable slots
        try {
          for (Map.Entry<DecompiledLocalVariable, Value> entry : LocalVariablesUtil.fetchValues(getStackFrameProxy(), debugProcess, true).entrySet()) {
            children.add(JavaValue.create(myNodeManager.getArgumentValueDescriptor(
              null, entry.getKey(), entry.getValue()), evaluationContext, myNodeManager));
          }
        }
        catch (VMDisconnectedException ex) {
          throw ex;
        }
        catch (Exception ex) {
          LOG.info(ex);
        }
      }
      else {
        throw e;
      }
    }

    if (!outerLocalVariablesAsFields.isEmpty()) {
      // Insert all non-yet added fields before other variables preserving the original order, see IDEA-318062.
      HashSet<String> alreadyAdded = new HashSet<>();
      for (int i = 0; i < children.size(); i++) {
        alreadyAdded.add(children.getName(i));
      }
      for (FieldDescriptorImpl f : outerLocalVariablesAsFields) {
        if (!alreadyAdded.contains(f.calcValueName())) {
          children.add(positionOfLocalVariablesAsFields++, JavaValue.create(f, evaluationContext, myNodeManager));
        }
      }
    }
  }
private void buildVariables(DebuggerContextImpl debuggerContext,
                              @NotNull final EvaluationContextImpl evaluationContext,
                              @NotNull DebugProcessImpl debugProcess,
                              XValueChildrenList children,
                              ObjectReference thisObjectReference,
                              Location location)