@Nullable
  private static HighlightInfo createAnnotationForRef(
      @NotNull GrReferenceExpression ref, boolean compileStatic, @NotNull String message) {
    PsiElement refNameElement = ref.getReferenceNameElement();
    assert refNameElement != null;

    HighlightDisplayLevel displayLevel = getHighlightDisplayLevel(ref.getProject(), ref);

    if (compileStatic || displayLevel == HighlightDisplayLevel.ERROR) {
      return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF)
          .range(refNameElement)
          .descriptionAndTooltip(message)
          .create();
    }

    if (displayLevel == HighlightDisplayLevel.WARNING) {
      boolean isTestMode = ApplicationManager.getApplication().isUnitTestMode();
      HighlightInfoType infotype =
          isTestMode ? HighlightInfoType.WARNING : HighlightInfoType.INFORMATION;

      HighlightInfo.Builder builder =
          HighlightInfo.newHighlightInfo(infotype).range(refNameElement);
      builder.descriptionAndTooltip(message);
      return builder.needsUpdateOnTyping(false).textAttributes(UNRESOLVED_ACCESS).create();
    }

    HighlightInfoType highlightInfoType = HighlightInfo.convertSeverity(displayLevel.getSeverity());
    return HighlightInfo.newHighlightInfo(highlightInfoType)
        .range(refNameElement)
        .descriptionAndTooltip(message)
        .create();
  }
 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);
 }
 @Nullable
 private static PsiType getTypeFromMapAccess(@NotNull GrReferenceExpression ref) {
   // map access
   GrExpression qualifier = ref.getQualifierExpression();
   if (qualifier instanceof GrReferenceExpression) {
     if (((GrReferenceExpression) qualifier).resolve() instanceof PsiClass) return null;
   }
   if (qualifier != null) {
     PsiType qType = qualifier.getType();
     if (qType instanceof PsiClassType) {
       PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
       PsiClass clazz = qResult.getElement();
       if (clazz != null) {
         PsiClass mapClass =
             JavaPsiFacade.getInstance(ref.getProject())
                 .findClass(CommonClassNames.JAVA_UTIL_MAP, ref.getResolveScope());
         if (mapClass != null && mapClass.getTypeParameters().length == 2) {
           PsiSubstitutor substitutor =
               TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
           if (substitutor != null) {
             PsiType substituted = substitutor.substitute(mapClass.getTypeParameters()[1]);
             if (substituted != null) {
               return PsiImplUtil.normalizeWildcardTypeByPosition(substituted, ref);
             }
           }
         }
       }
     }
   }
   return null;
 }
  private static void registerReferenceFixes(
      GrReferenceExpression refExpr,
      HighlightInfo info,
      boolean compileStatic,
      final HighlightDisplayKey key) {
    PsiClass targetClass = QuickfixUtil.findTargetClass(refExpr, compileStatic);
    if (targetClass == null) return;

    if (!compileStatic) {
      addDynamicAnnotation(info, refExpr, key);
    }
    if (targetClass.isWritable()) {
      QuickFixAction.registerQuickFixAction(
          info, new CreateFieldFromUsageFix(refExpr, targetClass), key);

      if (refExpr.getParent() instanceof GrCall && refExpr.getParent() instanceof GrExpression) {
        QuickFixAction.registerQuickFixAction(
            info, new CreateMethodFromUsageFix(refExpr, targetClass), key);
      }
    }

    if (!refExpr.isQualified()) {
      GrVariableDeclarationOwner owner =
          PsiTreeUtil.getParentOfType(refExpr, GrVariableDeclarationOwner.class);
      if (!(owner instanceof GroovyFileBase) || ((GroovyFileBase) owner).isScript()) {
        QuickFixAction.registerQuickFixAction(
            info, new CreateLocalVariableFromUsageFix(refExpr, owner), key);
      }
      if (PsiTreeUtil.getParentOfType(refExpr, GrMethod.class) != null) {
        QuickFixAction.registerQuickFixAction(info, new CreateParameterFromUsageFix(refExpr), key);
      }
    }
  }
    @Override
    public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) {
      super.visitMethodCallExpression(grMethodCallExpression);
      final GrArgumentList args = grMethodCallExpression.getArgumentList();
      if (args.getExpressionArguments().length != 1) {
        return;
      }
      if (PsiImplUtil.hasNamedArguments(args)) {
        return;
      }
      final GrExpression methodExpression = grMethodCallExpression.getInvokedExpression();
      if (!(methodExpression instanceof GrReferenceExpression)) {
        return;
      }
      final GrReferenceExpression referenceExpression = (GrReferenceExpression) methodExpression;
      final String name = referenceExpression.getReferenceName();
      if (!"get".equals(name)) {
        return;
      }
      final GrExpression qualifier = referenceExpression.getQualifierExpression();

      if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
        return;
      }

      if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
      final PsiType type = qualifier.getType();
      if (!InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
        return;
      }
      registerMethodCallError(grMethodCallExpression);
    }
  private static void addDynamicAnnotation(
      HighlightInfo info, GrReferenceExpression referenceExpression, HighlightDisplayKey key) {
    final PsiFile containingFile = referenceExpression.getContainingFile();
    if (containingFile != null) {
      VirtualFile file = containingFile.getVirtualFile();
      if (file == null) return;
    } else {
      return;
    }

    if (isCall(referenceExpression)) {
      PsiType[] argumentTypes = PsiUtil.getArgumentTypes(referenceExpression, false);
      if (argumentTypes != null) {
        QuickFixAction.registerQuickFixAction(
            info,
            referenceExpression.getTextRange(),
            new DynamicMethodFix(referenceExpression, argumentTypes),
            key);
      }
    } else {
      QuickFixAction.registerQuickFixAction(
          info,
          referenceExpression.getTextRange(),
          new DynamicPropertyFix(referenceExpression),
          key);
    }
  }
    public boolean satisfiedBy(PsiElement element) {
      if (element instanceof GrMethodCallExpression) {
        final GrMethodCallExpression expression = (GrMethodCallExpression) element;
        //        final PsiElement parent = expression.getParent();
        //        if (parent instanceof GrAssignmentExpression) return false;
        //        if (parent instanceof GrArgumentList) return false;
        //        if (parent instanceof GrReturnStatement) return false;
        //        if (!(parent instanceof GrCodeBlock || parent instanceof GrIfStatement|| parent
        // instanceof GrCaseSection)) return false;

        final GrExpression invokedExpression = expression.getInvokedExpression();
        if (invokedExpression instanceof GrReferenceExpression) {
          GrReferenceExpression referenceExpression = (GrReferenceExpression) invokedExpression;
          if ("each".equals(referenceExpression.getReferenceName())) {
            final GrArgumentList argumentList = expression.getArgumentList();
            if (argumentList != null) {
              if (PsiImplUtil.hasExpressionArguments(argumentList)) return false;
              if (PsiImplUtil.hasNamedArguments(argumentList)) return false;
            }
            final GrClosableBlock[] closureArguments = expression.getClosureArguments();
            if (closureArguments.length != 1) return false;
            final GrParameter[] parameters = closureArguments[0].getParameterList().getParameters();
            if (parameters.length > 1) return false;
            return true;
          }
        }
      }
      return false;
    }
 @Override
 public PsiType fun(GrSuperReferenceExpressionImpl ref) {
   final GrReferenceExpression qualifier = ref.getQualifier();
   if (qualifier == null) {
     GroovyPsiElement context =
         PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, GroovyFileBase.class);
     if (context instanceof GrTypeDefinition) {
       final PsiClass superClass = ((GrTypeDefinition) context).getSuperClass();
       if (superClass != null) {
         return JavaPsiFacade.getInstance(ref.getProject())
             .getElementFactory()
             .createType(superClass);
       }
     } else if (context instanceof GroovyFileBase) {
       PsiClass scriptClass = ((GroovyFileBase) context).getScriptClass();
       if (scriptClass != null) {
         PsiClass superClass = scriptClass.getSuperClass();
         if (superClass != null) {
           return JavaPsiFacade.getInstance(ref.getProject())
               .getElementFactory()
               .createType(superClass);
         }
       }
       return GrClassImplUtil.getGroovyObjectType(ref);
     }
   } else {
     final PsiElement resolved = qualifier.resolve();
     if (resolved instanceof PsiClass) {
       return ref.getSuperType((PsiClass) resolved);
     }
   }
   return null;
 }
 @Override
 public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
   final PsiElement resolved = referenceExpression.resolve();
   if (resolved instanceof PsiVariable) {
     if (!isStaticFinalField((PsiVariable) resolved)) {
       if (expr instanceof GrClosableBlock) {
         if (!PsiTreeUtil.isContextAncestor(scope, resolved, true)) {
           throw new GrRefactoringError(
               GroovyRefactoringBundle.message("closure.uses.external.variables"));
         }
       } else {
         throw new GrRefactoringError(
             RefactoringBundle.message("selected.expression.cannot.be.a.constant.initializer"));
       }
     }
   } else if (resolved instanceof PsiMethod
       && ((PsiMethod) resolved).getContainingClass() != null) {
     final GrExpression qualifier = referenceExpression.getQualifierExpression();
     if (qualifier == null
         || (qualifier instanceof GrReferenceExpression
             && ((GrReferenceExpression) qualifier).resolve() instanceof PsiClass)) {
       if (!((PsiMethod) resolved).hasModifierProperty(PsiModifier.STATIC)) {
         throw new GrRefactoringError(
             RefactoringBundle.message("selected.expression.cannot.be.a.constant.initializer"));
       }
     }
   }
 }
 @Override
 public void visitReferenceExpression(GrReferenceExpression expression) {
   super.visitReferenceExpression(expression);
   if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         expression.putCopyableUserData(SUPER_REF, Boolean.TRUE);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   } else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isThisReference(expression)) {
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         expression.putCopyableUserData(THIS_REF, Boolean.TRUE);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   }
 }
  public FieldConflictsResolver(String name, GrCodeBlock scope) {
    myScope = scope;
    if (myScope == null) return;

    final GroovyPsiElement resolved = ResolveUtil.resolveProperty(myScope, name);
    if (resolved instanceof GrReferenceExpression || resolved == null) return;

    assert resolved instanceof PsiVariable;
    final PsiVariable oldVariable = (PsiVariable) resolved;
    myField = oldVariable instanceof PsiField ? (PsiField) oldVariable : null;
    if (!(oldVariable instanceof PsiField)) return;

    myReferenceExpressions = new ArrayList<>();
    for (PsiReference reference :
        ReferencesSearch.search(myField, new LocalSearchScope(myScope), false)) {
      final PsiElement element = reference.getElement();
      if (element instanceof GrReferenceExpression) {
        final GrReferenceExpression referenceExpression = (GrReferenceExpression) element;
        if (referenceExpression.getQualifier() == null) {
          myReferenceExpressions.add(referenceExpression);
        }
      }
    }
    if (myField.hasModifierProperty(PsiModifier.STATIC)) {
      myQualifyingClass = myField.getContainingClass();
    }
  }
  private static void qualify(PsiMember member, PsiElement renamed, String name) {
    if (!(renamed instanceof GrReferenceExpression)) return;

    final PsiClass clazz = member.getContainingClass();
    if (clazz == null) return;

    final GrReferenceExpression refExpr = (GrReferenceExpression) renamed;
    final PsiElement replaced;
    if (member.hasModifierProperty(GrModifier.STATIC)) {
      final GrReferenceExpression newRefExpr =
          GroovyPsiElementFactory.getInstance(member.getProject())
              .createReferenceExpressionFromText(clazz.getQualifiedName() + "." + name);
      replaced = refExpr.replace(newRefExpr);
    } else {
      final PsiClass containingClass = PsiTreeUtil.getParentOfType(renamed, PsiClass.class);
      if (member.getManager().areElementsEquivalent(containingClass, clazz)) {
        final GrReferenceExpression newRefExpr =
            GroovyPsiElementFactory.getInstance(member.getProject())
                .createReferenceExpressionFromText("this." + name);
        replaced = refExpr.replace(newRefExpr);
      } else {
        final GrReferenceExpression newRefExpr =
            GroovyPsiElementFactory.getInstance(member.getProject())
                .createReferenceExpressionFromText(clazz.getQualifiedName() + ".this." + name);
        replaced = refExpr.replace(newRefExpr);
      }
    }
    PsiUtil.shortenReferences((GroovyPsiElement) replaced);
  }
  private void fixReferencesToStatic(GroovyPsiElement classMember, Set<PsiMember> movedMembers)
      throws IncorrectOperationException {
    final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers);
    classMember.accept(collector);
    ArrayList<GrReferenceElement> refs = collector.getReferences();
    ArrayList<PsiElement> members = collector.getReferees();
    ArrayList<PsiClass> classes = collector.getRefereeClasses();
    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);

    for (int i = 0; i < refs.size(); i++) {
      GrReferenceElement ref = refs.get(i);
      PsiElement namedElement = members.get(i);
      PsiClass aClass = classes.get(i);

      if (namedElement instanceof PsiNamedElement) {
        GrReferenceExpression newRef =
            (GrReferenceExpression)
                factory.createExpressionFromText(
                    "a." + ((PsiNamedElement) namedElement).getName(), null);
        GrExpression qualifier = newRef.getQualifierExpression();
        assert qualifier != null;
        qualifier =
            (GrExpression)
                qualifier.replace(
                    factory.createReferenceExpressionFromText(aClass.getQualifiedName()));
        qualifier.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified());
        PsiElement replaced = ref.replace(newRef);
        JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced);
      }
    }
  }
  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 boolean isQualifiedStaticMethodWithUnnecessaryQualifier(
      GrReferenceExpression ref) {
    if (ref.getQualifier() == null) return false;

    final PsiElement resolved = ref.resolve();
    if (!(resolved instanceof PsiMember)) return false;
    if (!((PsiMember) resolved).hasModifierProperty(PsiModifier.STATIC)) return false;

    PsiElement copyResolved;
    final PsiElement parent = ref.getParent();
    if (parent instanceof GrMethodCall) {
      final GrMethodCall copy = (GrMethodCall) parent.copy();
      GrReferenceExpression invoked = (GrReferenceExpression) copy.getInvokedExpression();
      assert invoked != null;

      invoked.setQualifier(null);

      copyResolved = ((GrReferenceExpression) copy.getInvokedExpression()).resolve();
    } else {
      final GrReferenceExpression copy = (GrReferenceExpression) ref.copy();
      copy.setQualifier(null);
      copyResolved = copy.resolve();
    }
    return ref.getManager().areElementsEquivalent(copyResolved, resolved);
  }
 private static boolean isPropertyAccessInStaticMethod(GrReferenceExpression referenceExpression) {
   if (referenceExpression.getParent() instanceof GrMethodCall
       || referenceExpression.getQualifier() != null) return false;
   GrMember context =
       PsiTreeUtil.getParentOfType(
           referenceExpression, GrMember.class, true, GrClosableBlock.class);
   return (context instanceof GrMethod || context instanceof GrClassInitializer)
       && context.hasModifierProperty(STATIC);
 }
  private static GrExpression genRefForGetter(GrMethodCall call, String accessorName) {
    String name = GroovyPropertyUtils.getPropertyNameByGetterName(accessorName, true);
    GrReferenceExpression refExpr = (GrReferenceExpression) call.getInvokedExpression();
    String oldNameStr = refExpr.getReferenceNameElement().getText();
    String newRefExpr = StringUtil.trimEnd(refExpr.getText(), oldNameStr) + name;

    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject());
    return factory.createExpressionFromText(newRefExpr, call);
  }
  @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;
  }
 @Override
 protected GrReferenceExpression bindWithQualifiedRef(@NotNull String qName) {
   final GrTypeArgumentList list = getTypeArgumentList();
   final String typeArgs = (list != null) ? list.getText() : "";
   final String text = qName + typeArgs;
   GrReferenceExpression qualifiedRef =
       GroovyPsiElementFactory.getInstance(getProject()).createReferenceExpressionFromText(text);
   getNode().getTreeParent().replaceChild(getNode(), qualifiedRef.getNode());
   return qualifiedRef;
 }
 public void fix() throws IncorrectOperationException {
   if (myField == null) return;
   final PsiManager manager = myScope.getManager();
   for (GrReferenceExpression referenceExpression : myReferenceExpressions) {
     if (!referenceExpression.isValid()) continue;
     final PsiElement newlyResolved = referenceExpression.resolve();
     if (!manager.areElementsEquivalent(newlyResolved, myField)) {
       qualifyReference(referenceExpression, myField, myQualifyingClass);
     }
   }
 }
 @Override
 protected GrReferenceExpression bindWithQualifiedRef(@NotNull String qName) {
   GrReferenceExpression qualifiedRef =
       GroovyPsiElementFactory.getInstance(getProject()).createReferenceExpressionFromText(qName);
   final GrTypeArgumentList list = getTypeArgumentList();
   if (list != null) {
     qualifiedRef.getNode().addChild(list.copy().getNode());
   }
   getNode().getTreeParent().replaceChild(getNode(), qualifiedRef.getNode());
   return qualifiedRef;
 }
  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);
  }
    @Override
    public void visitReferenceExpression(GrReferenceExpression ref) {
      super.visitReferenceExpression(ref);
      final GrExpression qualifier = ref.getQualifier();
      if (!PsiUtil.isThisReference(qualifier)) return;

      final PsiElement resolved = ref.resolve();
      if (!(resolved instanceof PsiField)) return;
      final PsiMethod getter = GroovyPropertyUtils.findGetterForField((PsiField) resolved);
      if (getter != null) {
        result.add((PsiField) resolved);
      }
    }
 private static boolean isDeclarationAssignment(
     @NotNull GrReferenceExpression lRefExpr, @Nullable String nameHint) {
   if (nameHint == null || nameHint.equals(lRefExpr.getName())) {
     final PsiElement target =
         lRefExpr
             .resolve(); // this is NOT quadratic since the next statement will prevent from
                         // further processing declarations upstream
     if (!(target instanceof PsiVariable) && !(target instanceof GrAccessorMethod)) {
       return true;
     }
   }
   return false;
 }
  @Nullable
  public static String getNameByReference(@Nullable PsiElement expression) {
    if (!(expression instanceof GrReferenceExpression)) return null;

    PsiElement firstChild = expression.getFirstChild();
    if (firstChild != expression.getLastChild()
        || !PsiImplUtil.isLeafElementOfType(firstChild, GroovyTokenTypes.mIDENT)) return null;

    GrReferenceExpression ref = (GrReferenceExpression) expression;
    if (ref.isQualified()) return null;

    return ref.getReferenceName();
  }
 @Override
 public void visitReferenceExpression(GrReferenceExpression expression) {
   super.visitReferenceExpression(expression);
   if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(
       expression.getQualifierExpression())) {
     PsiElement resolved = expression.resolve();
     if (resolved == null
         || resolved instanceof PsiMethod && shouldFixSuper((PsiMethod) resolved)) {
       mySupersToDelete.add(expression.getQualifierExpression());
     }
   } else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
     mySupersToChangeToThis.add(expression);
   }
 }
    public void fixSupers() throws IncorrectOperationException {
      final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
      GrReferenceExpression thisExpression =
          (GrReferenceExpression) factory.createExpressionFromText("this", null);
      for (GrExpression expression : mySupersToDelete) {
        if (expression.getParent() instanceof GrReferenceExpression) {
          ((GrReferenceExpression) expression.getParent()).setQualifier(null);
        }
      }

      for (GrReferenceExpression superExpression : mySupersToChangeToThis) {
        superExpression.replace(thisExpression);
      }
    }
 @Override
 public void visitReferenceExpression(GrReferenceExpression expression) {
   super.visitReferenceExpression(expression);
   if (expression.getCopyableUserData(SUPER_REF) != null) {
     expression.putCopyableUserData(SUPER_REF, null);
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
         GrExpression newExpr =
             factory.createExpressionFromText(myTargetSuperClass.getName() + ".this", null);
         expression.replace(newExpr);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   } else if (expression.getCopyableUserData(THIS_REF) != null) {
     expression.putCopyableUserData(THIS_REF, null);
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         ((GrReferenceExpression) qualifier).bindToElement(myTargetSuperClass);
         GroovyChangeContextUtil.clearContextInfo(qualifier);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   }
 }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiElement referenceName = descriptor.getPsiElement();
   final GrReferenceExpression invokedExpression =
       (GrReferenceExpression) referenceName.getParent();
   final GrMethodCallExpression callExpression =
       (GrMethodCallExpression) invokedExpression.getParent();
   final GrArgumentList args = callExpression.getArgumentList();
   final GrExpression arg = args.getExpressionArguments()[0];
   replaceExpression(
       callExpression,
       invokedExpression.getQualifierExpression().getText() + '[' + arg.getText() + ']');
 }
  @Nullable
  public static PsiType checkReassignedVar(
      GrReferenceExpression refExpr, boolean honorCompileStatic) {
    if (honorCompileStatic && !PsiUtil.isCompileStatic(refExpr) || refExpr.getQualifier() != null) {
      return null;
    }

    final PsiElement resolved = refExpr.resolve();
    if (!GroovyRefactoringUtil.isLocalVariable(resolved)) {
      return null;
    }

    assert resolved != null;
    return getLeastUpperBoundByVar((GrVariable) resolved);
  }