@Nullable
  private static HighlightInfo checkRefInner(GrReferenceExpression ref) {
    PsiElement refNameElement = ref.getReferenceNameElement();
    if (refNameElement == null) return null;

    boolean cannotBeDynamic = PsiUtil.isCompileStatic(ref) || isPropertyAccessInStaticMethod(ref);
    GroovyResolveResult resolveResult = getBestResolveResult(ref);

    if (resolveResult.getElement() != null) {
      if (!isInspectionEnabled(ref.getContainingFile(), ref.getProject())) return null;

      if (isStaticOk(resolveResult)) return null;
      String message = GroovyBundle.message("cannot.reference.non.static", ref.getReferenceName());
      return createAnnotationForRef(ref, cannotBeDynamic, message);
    }

    if (ResolveUtil.isKeyOfMap(ref) || isClassReference(ref)) {
      return null;
    }

    if (!cannotBeDynamic) {
      if (!isInspectionEnabled(ref.getContainingFile(), ref.getProject())) return null;
      GrUnresolvedAccessInspection inspection =
          getInstance(ref.getContainingFile(), ref.getProject());

      if (!inspection.myHighlightIfGroovyObjectOverridden && areGroovyObjectMethodsOverridden(ref))
        return null;
      if (!inspection.myHighlightIfMissingMethodsDeclared && areMissingMethodsDeclared(ref))
        return null;

      if (GroovySuppressableInspectionTool.isElementToolSuppressedIn(ref, SHORT_NAME)) return null;
    }

    if (cannotBeDynamic || shouldHighlightAsUnresolved(ref)) {
      HighlightInfo info =
          createAnnotationForRef(
              ref, cannotBeDynamic, GroovyBundle.message("cannot.resolve", ref.getReferenceName()));
      LOG.assertTrue(info != null);

      HighlightDisplayKey displayKey = HighlightDisplayKey.find(SHORT_NAME);
      if (ref.getParent() instanceof GrMethodCall) {
        registerStaticImportFix(ref, info, displayKey);
      } else {
        registerCreateClassByTypeFix(ref, info, displayKey);
        registerAddImportFixes(ref, info, displayKey);
      }

      registerReferenceFixes(ref, info, cannotBeDynamic, displayKey);
      UnresolvedReferenceQuickFixProvider.registerReferenceFixes(
          ref, new QuickFixActionRegistrarAdapter(info, displayKey));
      OrderEntryFix.registerFixes(new QuickFixActionRegistrarAdapter(info, displayKey), ref);
      return info;
    }

    return null;
  }
 public static boolean isClassReference(GrReferenceExpression ref) {
   GrExpression qualifier = ref.getQualifier();
   return "class".equals(ref.getReferenceName())
       && qualifier instanceof GrReferenceExpression
       && ((GrReferenceExpression) qualifier).resolve() instanceof PsiClass
       && !PsiUtil.isThisReference(qualifier);
 }
  public void visitReferenceExpression(GrReferenceExpression refExpr) {
    super.visitReferenceExpression(refExpr);

    if (myPolicy.isReferenceAccepted(refExpr)) {
      String name = refExpr.getReferenceName();
      if (name == null) return;

      if (ControlFlowUtils.isIncOrDecOperand(refExpr)) {
        final InstructionImpl i = new ReadWriteVariableInstruction(name, refExpr, READ);
        addNodeAndCheckPending(i);
        addNode(new ReadWriteVariableInstruction(name, refExpr, WRITE));
      } else {
        final int type = PsiUtil.isLValue(refExpr) ? WRITE : READ;
        addNodeAndCheckPending(new ReadWriteVariableInstruction(name, refExpr, type));
        if (refExpr.getParent() instanceof GrArgumentList
            && refExpr.getParent().getParent() instanceof GrCall) {
          addNodeAndCheckPending(new ArgumentInstruction(refExpr));
        }
      }
    }

    if (refExpr.isQualified() && !(refExpr.getParent() instanceof GrCall)) {
      visitCall(refExpr);
    }
  }
  private static void registerStaticImportFix(
      @NotNull GrReferenceExpression referenceExpression,
      @Nullable HighlightInfo info,
      @Nullable final HighlightDisplayKey key) {
    final String referenceName = referenceExpression.getReferenceName();
    if (StringUtil.isEmpty(referenceName)) return;
    if (referenceExpression.getQualifier() != null) return;

    QuickFixAction.registerQuickFixAction(
        info, new GroovyStaticImportMethodFix((GrMethodCall) referenceExpression.getParent()), key);
  }
  @NotNull
  public static GroovyResolveResult[] resolveNonQualifiedRefWithoutFlow(
      @NotNull GrReferenceExpression ref) {
    LOG.assertTrue(!ref.isQualified());

    final String referenceName = ref.getReferenceName();
    final ResolverProcessor processor = new PropertyResolverProcessor(referenceName, ref);

    ResolveUtil.treeWalkUp(ref, processor, false);
    final GroovyResolveResult[] candidates = processor.getCandidates();
    if (candidates.length != 0) {
      return candidates;
    }

    return GroovyResolveResult.EMPTY_ARRAY;
  }
  private static boolean isSetterInvocation(GrMethodCall call) {
    GrExpression expr = call.getInvokedExpression();

    if (!(expr instanceof GrReferenceExpression)) return false;
    GrReferenceExpression refExpr = (GrReferenceExpression) expr;

    PsiMethod method;
    if (call instanceof GrApplicationStatement) {
      PsiElement element = refExpr.resolve();
      if (!(element instanceof PsiMethod)
          || !GroovyPropertyUtils.isSimplePropertySetter(((PsiMethod) element))) return false;
      method = (PsiMethod) element;
    } else {
      method = call.resolveMethod();
      if (!GroovyPropertyUtils.isSimplePropertySetter(method)) return false;
      LOG.assertTrue(method != null);
    }

    if (!GroovyNamesUtil.isValidReference(
        GroovyPropertyUtils.getPropertyNameBySetterName(method.getName()),
        ((GrReferenceExpression) expr).getQualifier() != null,
        call.getProject())) {
      return false;
    }

    GrArgumentList args = call.getArgumentList();
    if (args == null
        || args.getExpressionArguments().length != 1
        || PsiImplUtil.hasNamedArguments(args)) {
      return false;
    }

    GrAssignmentExpression assignment = genRefForSetter(call, refExpr.getReferenceName());
    if (assignment != null) {
      GrExpression value = assignment.getLValue();
      if (value instanceof GrReferenceExpression
          && call.getManager()
              .areElementsEquivalent(((GrReferenceExpression) value).resolve(), method)) {
        return true;
      }
    }

    return false;
  }