@Override
 public void visitArrayAccessExpression(final PsiArrayAccessExpression expression) {
   if (myCollectExpressions
       && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(expression, myVisibleLocals)) {
     myExpressions.add(new TextWithImportsImpl(expression));
   }
   super.visitArrayAccessExpression(expression);
 }
 @Override
 public void visitMethodCallExpression(final PsiMethodCallExpression expression) {
   if (myCollectExpressions) {
     final PsiMethod psiMethod = expression.resolveMethod();
     if (psiMethod != null
         && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(expression, myVisibleLocals)) {
       myExpressions.add(new TextWithImportsImpl(expression));
     }
   }
   super.visitMethodCallExpression(expression);
 }
 @Override
 public void visitReferenceExpression(final PsiReferenceExpression reference) {
   if (myLineRange.intersects(reference.getTextRange())) {
     final PsiElement psiElement = reference.resolve();
     if (psiElement instanceof PsiVariable) {
       final PsiVariable var = (PsiVariable) psiElement;
       if (var instanceof PsiField) {
         if (myCollectExpressions
             && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(
                 reference, myVisibleLocals)) {
           /*
           if (var instanceof PsiEnumConstant && reference.getQualifier() == null) {
             final PsiClass enumClass = ((PsiEnumConstant)var).getContainingClass();
             if (enumClass != null) {
               final PsiExpression expression = JavaPsiFacade.getInstance(var.getProject()).getParserFacade().createExpressionFromText(enumClass.getName() + "." + var.getName(), var);
               final PsiReference ref = expression.getReference();
               if (ref != null) {
                 ref.bindToElement(var);
                 myExpressions.add(new TextWithImportsImpl(expression));
               }
             }
           }
           else {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
           */
           final PsiModifierList modifierList = var.getModifierList();
           boolean isConstant =
               (var instanceof PsiEnumConstant)
                   || (modifierList != null
                       && modifierList.hasModifierProperty(PsiModifier.STATIC)
                       && modifierList.hasModifierProperty(PsiModifier.FINAL));
           if (!isConstant) {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
         }
       } else {
         if (myVisibleLocals.contains(var.getName())) {
           myVars.add(var.getName());
         } else {
           // fix for variables used in inner classes
           if (!Comparing.equal(
               PsiTreeUtil.getParentOfType(reference, PsiClass.class),
               PsiTreeUtil.getParentOfType(var, PsiClass.class))) {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
         }
       }
     }
   }
   super.visitReferenceExpression(reference);
 }
  private void runAction(final EvaluationContextImpl context, LocatableEvent event) {
    if (LOG_ENABLED || LOG_EXPRESSION_ENABLED) {
      final StringBuilder buf = StringBuilderSpinAllocator.alloc();
      try {
        if (LOG_ENABLED) {
          buf.append(getEventMessage(event));
          buf.append("\n");
        }
        final DebugProcessImpl debugProcess = context.getDebugProcess();
        final TextWithImports expressionToEvaluate = getLogMessage();
        if (LOG_EXPRESSION_ENABLED
            && expressionToEvaluate != null
            && !"".equals(expressionToEvaluate.getText())) {
          if (!debugProcess.isAttached()) {
            return;
          }

          try {
            ExpressionEvaluator evaluator =
                DebuggerInvocationUtil.commitAndRunReadAction(
                    getProject(),
                    new EvaluatingComputable<ExpressionEvaluator>() {
                      public ExpressionEvaluator compute() throws EvaluateException {
                        return EvaluatorBuilderImpl.build(
                            expressionToEvaluate,
                            ContextUtil.getContextElement(context),
                            ContextUtil.getSourcePosition(context));
                      }
                    });
            final Value eval = evaluator.evaluate(context);
            final String result =
                eval instanceof VoidValue ? "void" : DebuggerUtils.getValueAsString(context, eval);
            buf.append(result);
          } catch (EvaluateException e) {
            buf.append(DebuggerBundle.message("error.unable.to.evaluate.expression"));
            buf.append(" \"");
            buf.append(expressionToEvaluate);
            buf.append("\"");
            buf.append(" : ");
            buf.append(e.getMessage());
          }
          buf.append("\n");
        }
        if (buf.length() > 0) {
          debugProcess.printToConsole(buf.toString());
        }
      } finally {
        StringBuilderSpinAllocator.dispose(buf);
      }
    }
  }
  @SuppressWarnings({"HardCodedStringLiteral"})
  public static RemoteConnection createDebugParameters(
      final JavaParameters parameters,
      final boolean debuggerInServerMode,
      int transport,
      final String debugPort,
      boolean checkValidity)
      throws ExecutionException {
    if (checkValidity) {
      checkTargetJPDAInstalled(parameters);
    }

    final boolean useSockets = transport == DebuggerSettings.SOCKET_TRANSPORT;

    String address = "";
    if (StringUtil.isEmptyOrSpaces(debugPort)) {
      try {
        address = DebuggerUtils.getInstance().findAvailableDebugAddress(useSockets);
      } catch (ExecutionException e) {
        if (checkValidity) {
          throw e;
        }
      }
    } else {
      address = debugPort;
    }

    final TransportServiceWrapper transportService =
        TransportServiceWrapper.getTransportService(useSockets);
    final String debugAddress =
        debuggerInServerMode && useSockets ? "127.0.0.1:" + address : address;
    String debuggeeRunProperties =
        "transport=" + transportService.transportId() + ",address=" + debugAddress;
    if (debuggerInServerMode) {
      debuggeeRunProperties += ",suspend=y,server=n";
    } else {
      debuggeeRunProperties += ",suspend=n,server=y";
    }

    if (hasWhitespace(debuggeeRunProperties)) {
      debuggeeRunProperties = "\"" + debuggeeRunProperties + "\"";
    }
    final String _debuggeeRunProperties = debuggeeRunProperties;

    ApplicationManager.getApplication()
        .runReadAction(
            new Runnable() {
              @Override
              @SuppressWarnings({"HardCodedStringLiteral"})
              public void run() {
                JavaSdkUtil.addRtJar(parameters.getClassPath());

                final Sdk jdk = parameters.getJdk();
                final boolean forceClassicVM = shouldForceClassicVM(jdk);
                final boolean forceNoJIT = shouldForceNoJIT(jdk);
                final String debugKey = System.getProperty(DEBUG_KEY_NAME, "-Xdebug");
                final boolean needDebugKey =
                    shouldAddXdebugKey(jdk)
                        || !"-Xdebug".equals(debugKey) /*the key is non-standard*/;

                if (forceClassicVM || forceNoJIT || needDebugKey || !isJVMTIAvailable(jdk)) {
                  parameters
                      .getVMParametersList()
                      .replaceOrPrepend("-Xrunjdwp:", "-Xrunjdwp:" + _debuggeeRunProperties);
                } else {
                  // use newer JVMTI if available
                  parameters.getVMParametersList().replaceOrPrepend("-Xrunjdwp:", "");
                  parameters
                      .getVMParametersList()
                      .replaceOrPrepend(
                          "-agentlib:jdwp=", "-agentlib:jdwp=" + _debuggeeRunProperties);
                }

                if (forceNoJIT) {
                  parameters
                      .getVMParametersList()
                      .replaceOrPrepend("-Djava.compiler=", "-Djava.compiler=NONE");
                  parameters.getVMParametersList().replaceOrPrepend("-Xnoagent", "-Xnoagent");
                }

                if (needDebugKey) {
                  parameters.getVMParametersList().replaceOrPrepend(debugKey, debugKey);
                } else {
                  // deliberately skip outdated parameter because it can disable full-speed
                  // debugging for some jdk builds
                  // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6272174
                  parameters.getVMParametersList().replaceOrPrepend("-Xdebug", "");
                }

                parameters
                    .getVMParametersList()
                    .replaceOrPrepend("-classic", forceClassicVM ? "-classic" : "");
              }
            });

    return new RemoteConnection(useSockets, "127.0.0.1", address, debuggerInServerMode);
  }
  // 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;
      }
    }
  }