@NotNull
  @Override
  public Collection<PsiReference> findReferences(final PsiElement element) {
    if (element instanceof GrField) {
      ArrayList<PsiReference> refs = new ArrayList<PsiReference>();

      GrField field = (GrField) element;
      PsiMethod setter = GroovyPropertyUtils.findSetterForField(field);
      GlobalSearchScope projectScope = GlobalSearchScope.projectScope(element.getProject());
      if (setter != null && setter instanceof GrAccessorMethod) {
        refs.addAll(
            RenameAliasedUsagesUtil.filterAliasedRefs(
                MethodReferencesSearch.search(setter, projectScope, true).findAll(), setter));
      }
      GrAccessorMethod[] getters = field.getGetters();
      for (GrAccessorMethod getter : getters) {
        refs.addAll(
            RenameAliasedUsagesUtil.filterAliasedRefs(
                MethodReferencesSearch.search(getter, projectScope, true).findAll(), getter));
      }
      refs.addAll(
          RenameAliasedUsagesUtil.filterAliasedRefs(
              ReferencesSearch.search(field, projectScope, true).findAll(), field));
      return refs;
    }
    return super.findReferences(element);
  }
  public static void addElementUsages(
      final PsiElement element,
      final Processor<UsageInfo> result,
      final FindUsagesOptions options) {
    final SearchScope searchScope = options.searchScope;
    if (element instanceof PsiMethod
        && ApplicationManager.getApplication()
            .runReadAction(
                new Computable<Boolean>() {
                  @Override
                  public Boolean compute() {
                    return ((PsiMethod) element).isConstructor();
                  }
                })) {
      PsiMethod method = (PsiMethod) element;
      final PsiClass parentClass = method.getContainingClass();

      if (parentClass != null) {
        MethodReferencesSearch.search(
                new MethodReferencesSearch.SearchParameters(
                    method,
                    searchScope,
                    options instanceof JavaMethodFindUsagesOptions
                        ? !((JavaMethodFindUsagesOptions) options).isIncludeOverloadUsages
                        : true,
                    options.fastTrack))
            .forEach(
                new ReadActionProcessor<PsiReference>() {
                  @Override
                  public boolean processInReadAction(final PsiReference ref) {
                    return addResult(result, ref, options);
                  }
                });
      }
      return;
    }

    final ReadActionProcessor<PsiReference> consumer =
        new ReadActionProcessor<PsiReference>() {
          @Override
          public boolean processInReadAction(final PsiReference ref) {
            return addResult(result, ref, options);
          }
        };

    if (element instanceof PsiMethod) {
      final boolean strictSignatureSearch =
          !(options instanceof JavaMethodFindUsagesOptions)
              || // field with getter
              !((JavaMethodFindUsagesOptions) options).isIncludeOverloadUsages;
      MethodReferencesSearch.search(
              new MethodReferencesSearch.SearchParameters(
                  (PsiMethod) element, searchScope, strictSignatureSearch, options.fastTrack))
          .forEach(consumer);
    } else {
      ReferencesSearch.search(
              new ReferencesSearch.SearchParameters(element, searchScope, false, options.fastTrack))
          .forEach(consumer);
    }
  }
  @NotNull
  @Override
  public Collection<PsiReference> findReferences(PsiElement element) {
    assert element instanceof GrField;

    ArrayList<PsiReference> refs = new ArrayList<>();

    GrField field = (GrField) element;
    GlobalSearchScope projectScope = GlobalSearchScope.projectScope(element.getProject());
    PsiMethod setter = field.getSetter();
    if (setter != null) {
      refs.addAll(
          RenameAliasedUsagesUtil.filterAliasedRefs(
              MethodReferencesSearch.search(setter, projectScope, true).findAll(), setter));
    }
    GrAccessorMethod[] getters = field.getGetters();
    for (GrAccessorMethod getter : getters) {
      refs.addAll(
          RenameAliasedUsagesUtil.filterAliasedRefs(
              MethodReferencesSearch.search(getter, projectScope, true).findAll(), getter));
    }
    refs.addAll(
        RenameAliasedUsagesUtil.filterAliasedRefs(
            ReferencesSearch.search(field, projectScope, false).findAll(), field));
    return refs;
  }
 @Override
 public Collection<PsiReference> findReferencesToHighlight(
     final PsiElement target, final SearchScope searchScope) {
   if (target instanceof PsiMethod) {
     final PsiMethod[] superMethods = ((PsiMethod) target).findDeepestSuperMethods();
     if (superMethods.length == 0) {
       return MethodReferencesSearch.search((PsiMethod) target, searchScope, true).findAll();
     }
     final Collection<PsiReference> result = new ArrayList<PsiReference>();
     for (PsiMethod superMethod : superMethods) {
       result.addAll(MethodReferencesSearch.search(superMethod, searchScope, true).findAll());
     }
     return result;
   }
   return super.findReferencesToHighlight(target, searchScope);
 }
  @NotNull
  @Override
  protected UsageInfo[] findUsages() {
    ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();

    final PsiMethod toSearchFor = ((PsiMethod) mySettings.getToSearchFor());

    if (!mySettings.generateDelegate()) {
      Collection<PsiReference> refs =
          MethodReferencesSearch.search(
                  toSearchFor, GlobalSearchScope.projectScope(myProject), true)
              .findAll();

      for (PsiReference ref1 : refs) {
        PsiElement ref = ref1.getElement();
        if (ref instanceof PsiMethod && ((PsiMethod) ref).isConstructor()) {
          DefaultConstructorImplicitUsageInfo implicitUsageInfo =
              new DefaultConstructorImplicitUsageInfo(
                  (PsiMethod) ref, ((PsiMethod) ref).getContainingClass(), toSearchFor);
          result.add(implicitUsageInfo);
        } else if (ref instanceof PsiClass) {
          result.add(new NoConstructorClassUsageInfo((PsiClass) ref));
        } else if (!PsiTreeUtil.isAncestor(mySettings.getToReplaceIn(), ref, false)) {
          result.add(new ExternalUsageInfo(ref));
        } else {
          result.add(new ChangedMethodCallInfo(ref));
        }
      }
    }

    if (mySettings.replaceAllOccurrences()) {
      PsiElement[] exprs = GroovyIntroduceParameterUtil.getOccurrences(mySettings);
      for (PsiElement expr : exprs) {
        result.add(new InternalUsageInfo(expr));
      }
    } else {
      if (mySettings.getExpression() != null) {
        result.add(new InternalUsageInfo(mySettings.getExpression()));
      }
    }

    Collection<PsiMethod> overridingMethods =
        OverridingMethodsSearch.search(toSearchFor, true).findAll();

    for (PsiMethod overridingMethod : overridingMethods) {
      result.add(new UsageInfo(overridingMethod));
    }

    final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
    return UsageViewUtil.removeDuplicatedUsages(usageInfos);
  }
 private static HashSet<PsiMethod> collectNonPhysicalMethodsToPropagate(PsiMethod method) {
   final HashSet<PsiMethod> methodsToPropagate = new HashSet<PsiMethod>();
   final PsiReference[] references =
       MethodReferencesSearch.search(method, GlobalSearchScope.allScope(getProject()), true)
           .toArray(PsiReference.EMPTY_ARRAY);
   for (PsiReference reference : references) {
     final PsiElement element = reference.getElement();
     Assert.assertTrue(element instanceof PsiClass);
     PsiClass containingClass = (PsiClass) element;
     methodsToPropagate.add(
         JavaPsiFacade.getElementFactory(getProject())
             .createMethodFromText(containingClass.getName() + "(){}", containingClass));
   }
   return methodsToPropagate;
 }
  @NotNull
  protected UsageInfo[] findUsages() {
    ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();

    PsiMethod[] overridingMethods =
        OverridingMethodsSearch.search(myMethodToSearchFor, true).toArray(PsiMethod.EMPTY_ARRAY);
    for (PsiMethod overridingMethod : overridingMethods) {
      result.add(new UsageInfo(overridingMethod));
    }
    if (!myGenerateDelegate) {
      PsiReference[] refs =
          MethodReferencesSearch.search(
                  myMethodToSearchFor, GlobalSearchScope.projectScope(myProject), true)
              .toArray(PsiReference.EMPTY_ARRAY);

      for (PsiReference ref1 : refs) {
        PsiElement ref = ref1.getElement();
        if (ref instanceof PsiMethod && ((PsiMethod) ref).isConstructor()) {
          DefaultConstructorImplicitUsageInfo implicitUsageInfo =
              new DefaultConstructorImplicitUsageInfo(
                  (PsiMethod) ref, ((PsiMethod) ref).getContainingClass(), myMethodToSearchFor);
          result.add(implicitUsageInfo);
        } else if (ref instanceof PsiClass) {
          result.add(new NoConstructorClassUsageInfo((PsiClass) ref));
        } else if (!IntroduceParameterUtil.insideMethodToBeReplaced(ref, myMethodToReplaceIn)) {
          result.add(new ExternalUsageInfo(ref));
        } else {
          result.add(new ChangedMethodCallInfo(ref));
        }
      }
    }

    if (myReplaceAllOccurences) {
      for (PsiElement expr : getOccurrences()) {
        result.add(new InternalUsageInfo(expr));
      }
    } else {
      if (myExpressionToSearch != null && myExpressionToSearch.isValid()) {
        result.add(new InternalUsageInfo(myExpressionToSearch));
      }
    }

    final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
    return UsageViewUtil.removeDuplicatedUsages(usageInfos);
  }
 private static void addMethodsUsages(
     final PsiClass aClass,
     final Processor<UsageInfo> results,
     final JavaClassFindUsagesOptions options) {
   if (options.isIncludeInherited) {
     final PsiManager manager = aClass.getManager();
     PsiMethod[] methods = aClass.getAllMethods();
     MethodsLoop:
     for (int i = 0; i < methods.length; i++) {
       final PsiMethod method = methods[i];
       // filter overriden methods
       MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY);
       for (int j = 0; j < i; j++) {
         if (methodSignature.equals(methods[j].getSignature(PsiSubstitutor.EMPTY)))
           continue MethodsLoop;
       }
       final PsiClass methodClass = method.getContainingClass();
       if (methodClass != null && manager.areElementsEquivalent(methodClass, aClass)) {
         addElementUsages(methods[i], results, options);
       } else {
         MethodReferencesSearch.search(
                 new MethodReferencesSearch.SearchParameters(
                     method, options.searchScope, true, options.fastTrack))
             .forEach(
                 new PsiReferenceProcessorAdapter(
                     new PsiReferenceProcessor() {
                       @Override
                       public boolean execute(PsiReference reference) {
                         addResultFromReference(
                             reference, methodClass, manager, aClass, results, options);
                         return true;
                       }
                     }));
       }
     }
   } else {
     for (PsiMethod method : aClass.getMethods()) {
       addElementUsages(method, results, options);
     }
   }
 }
 public void testOverloadConstructors() throws Exception {
   PsiClass aClass = myJavaFacade.findClass("B", GlobalSearchScope.allScope(myProject));
   PsiMethod constructor;
   //    constructor = myJavaFacade.getElementFactory().createConstructor();
   //    constructor = aClass.findMethodBySignature(constructor, false);
   constructor = aClass.findMethodsByName("B", false)[0];
   PsiMethodCallExpression superCall =
       (PsiMethodCallExpression) constructor.getBody().getStatements()[0].getFirstChild();
   PsiReferenceExpression superExpr = superCall.getMethodExpression();
   String[] fileNames = new String[] {"B.java", "A.java", "A.java", "B.java"};
   int[] starts = new int[] {};
   int[] ends = new int[] {};
   final ArrayList<PsiFile> filesList = new ArrayList<PsiFile>();
   final IntArrayList startsList = new IntArrayList();
   final IntArrayList endsList = new IntArrayList();
   PsiReference[] refs =
       MethodReferencesSearch.search(
               (PsiMethod) superExpr.resolve(), GlobalSearchScope.projectScope(myProject), false)
           .toArray(PsiReference.EMPTY_ARRAY);
   for (PsiReference ref : refs) {
     addReference(ref, filesList, startsList, endsList);
   }
   checkResult(fileNames, filesList, starts, startsList, ends, endsList);
 }
  @Override
  protected void processIntention(@NotNull PsiElement element, Project project, Editor editor)
      throws IncorrectOperationException {
    final GrField field;
    if (element.getParent() instanceof GrField) {
      field = (GrField) element.getParent();
    } else {
      final PsiReference ref = element.getReference();
      LOG.assertTrue(ref != null);
      PsiElement resolved = ref.resolve();
      if (resolved instanceof GrAccessorMethod) {
        resolved = ((GrAccessorMethod) resolved).getProperty();
      }
      LOG.assertTrue(resolved instanceof GrField);
      field = (GrField) resolved;
    }

    final HashSet<PsiReference> usages = new HashSet<PsiReference>();
    usages.addAll(ReferencesSearch.search(field).findAll());
    final GrAccessorMethod[] getters = field.getGetters();
    for (GrAccessorMethod getter : getters) {
      usages.addAll(MethodReferencesSearch.search(getter).findAll());
    }
    final GrAccessorMethod setter = field.getSetter();
    if (setter != null) {
      usages.addAll(MethodReferencesSearch.search(setter).findAll());
    }

    final String fieldName = field.getName();
    LOG.assertTrue(fieldName != null);
    final Collection<PsiElement> fieldUsages = new HashSet<PsiElement>();
    MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
    for (PsiReference usage : usages) {
      final PsiElement psiElement = usage.getElement();
      if (PsiUtil.isMethodUsage(psiElement)) continue;
      if (!GroovyFileType.GROOVY_LANGUAGE.equals(psiElement.getLanguage())) {
        conflicts.putValue(
            psiElement,
            GroovyIntentionsBundle.message("closure.is.accessed.outside.of.groovy", fieldName));
      } else {
        if (psiElement instanceof GrReferenceExpression) {
          fieldUsages.add(psiElement);
          if (PsiUtil.isAccessedForWriting((GrExpression) psiElement)) {
            conflicts.putValue(
                psiElement,
                GroovyIntentionsBundle.message("write.access.to.closure.variable", fieldName));
          }
        } else if (psiElement instanceof GrArgumentLabel) {
          conflicts.putValue(
              psiElement,
              GroovyIntentionsBundle.message("field.is.used.in.argument.label", fieldName));
        }
      }
    }
    final PsiClass containingClass = field.getContainingClass();
    final GrExpression initializer = field.getInitializerGroovy();
    LOG.assertTrue(initializer != null);
    final PsiType type = initializer.getType();
    LOG.assertTrue(type instanceof GrClosureType);
    final GrSignature signature = ((GrClosureType) type).getSignature();
    final List<MethodSignature> signatures =
        GrClosureSignatureUtil.generateAllMethodSignaturesBySignature(fieldName, signature);
    for (MethodSignature s : signatures) {
      final PsiMethod method = MethodSignatureUtil.findMethodBySignature(containingClass, s, true);
      if (method != null) {
        conflicts.putValue(
            method,
            GroovyIntentionsBundle.message(
                "method.with.signature.already.exists",
                GroovyPresentationUtil.getSignaturePresentation(s)));
      }
    }
    if (conflicts.size() > 0) {
      final ConflictsDialog conflictsDialog =
          new ConflictsDialog(
              project,
              conflicts,
              new Runnable() {
                @Override
                public void run() {
                  execute(field, fieldUsages);
                }
              });
      conflictsDialog.show();
      if (conflictsDialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) return;
    }
    execute(field, fieldUsages);
  }
  private PsiMethod[] findSimpleUsagesWithoutParameters(
      final PsiMethod method,
      final ArrayList<UsageInfo> result,
      boolean isToModifyArgs,
      boolean isToThrowExceptions,
      boolean isOriginal) {

    GlobalSearchScope projectScope = GlobalSearchScope.projectScope(method.getProject());
    PsiMethod[] overridingMethods =
        OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY);

    for (PsiMethod overridingMethod : overridingMethods) {
      result.add(
          new OverriderUsageInfo(
              overridingMethod, method, isOriginal, isToModifyArgs, isToThrowExceptions));
    }

    boolean needToChangeCalls =
        !myChangeInfo.isGenerateDelegate()
            && (myChangeInfo.isNameChanged()
                || myChangeInfo.isParameterSetOrOrderChanged()
                || myChangeInfo.isExceptionSetOrOrderChanged()
                || myChangeInfo.isVisibilityChanged() /*for checking inaccessible*/);
    if (needToChangeCalls) {
      int parameterCount = method.getParameterList().getParametersCount();

      PsiReference[] refs =
          MethodReferencesSearch.search(method, projectScope, true)
              .toArray(PsiReference.EMPTY_ARRAY);
      for (PsiReference ref : refs) {
        PsiElement element = ref.getElement();

        boolean isToCatchExceptions =
            isToThrowExceptions
                && needToCatchExceptions(RefactoringUtil.getEnclosingMethod(element));
        if (!isToCatchExceptions) {
          if (RefactoringUtil.isMethodUsage(element)) {
            PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(element);
            if (list == null
                || !method.isVarArgs() && list.getExpressions().length != parameterCount) continue;
          }
        }
        if (RefactoringUtil.isMethodUsage(element)) {
          result.add(new MethodCallUsageInfo(element, isToModifyArgs, isToCatchExceptions));
        } else if (element instanceof PsiDocTagValue) {
          result.add(new UsageInfo(element));
        } else if (element instanceof PsiMethod && ((PsiMethod) element).isConstructor()) {
          if (JavaLanguage.INSTANCE.equals(element.getLanguage())) {
            DefaultConstructorImplicitUsageInfo implicitUsageInfo =
                new DefaultConstructorImplicitUsageInfo(
                    (PsiMethod) element, ((PsiMethod) element).getContainingClass(), method);
            result.add(implicitUsageInfo);
          }
        } else if (element instanceof PsiClass) {
          LOG.assertTrue(method.isConstructor());
          final PsiClass psiClass = (PsiClass) element;
          if (JavaLanguage.INSTANCE.equals(psiClass.getLanguage())) {
            if (myChangeInfo instanceof JavaChangeInfo) {
              if (shouldPropagateToNonPhysicalMethod(
                  method,
                  result,
                  psiClass,
                  ((JavaChangeInfo) myChangeInfo).getMethodsToPropagateParameters())) {
                continue;
              }
            }
            result.add(new NoConstructorClassUsageInfo(psiClass));
          }
        } else if (ref instanceof PsiCallReference) {
          result.add(new CallReferenceUsageInfo((PsiCallReference) ref));
        } else {
          result.add(new MoveRenameUsageInfo(element, ref, method));
        }
      }

      // if (method.isConstructor() && parameterCount == 0) {
      //    RefactoringUtil.visitImplicitConstructorUsages(method.getContainingClass(),
      //                                                   new
      // DefaultConstructorUsageCollector(result));
      // }
    } else if (myChangeInfo.isParameterTypesChanged()) {
      PsiReference[] refs =
          MethodReferencesSearch.search(method, projectScope, true)
              .toArray(PsiReference.EMPTY_ARRAY);
      for (PsiReference reference : refs) {
        final PsiElement element = reference.getElement();
        if (element instanceof PsiDocTagValue) {
          result.add(new UsageInfo(reference));
        } else if (element instanceof XmlElement) {
          result.add(new MoveRenameUsageInfo(reference, method));
        } else if (element instanceof PsiMethodReferenceExpression) {
          result.add(new UsageInfo(reference));
        }
      }
    }

    // Conflicts
    detectLocalsCollisionsInMethod(method, result, isOriginal);
    for (final PsiMethod overridingMethod : overridingMethods) {
      detectLocalsCollisionsInMethod(overridingMethod, result, isOriginal);
    }

    return overridingMethods;
  }