@Nullable
  private static Condition<PsiElement> findMethodUsages(
      final PsiMethod psiMethod, final PsiElement[] allElementsToDelete, List<UsageInfo> usages) {
    final Collection<PsiReference> references = ReferencesSearch.search(psiMethod).findAll();

    if (psiMethod.isConstructor()) {
      return findConstructorUsages(psiMethod, references, usages, allElementsToDelete);
    }
    final PsiMethod[] overridingMethods =
        removeDeletedMethods(
            OverridingMethodsSearch.search(psiMethod).toArray(PsiMethod.EMPTY_ARRAY),
            allElementsToDelete);

    findFunctionalExpressions(usages, ArrayUtil.prepend(psiMethod, overridingMethods));

    final HashMap<PsiMethod, Collection<PsiReference>> methodToReferences = new HashMap<>();
    for (PsiMethod overridingMethod : overridingMethods) {
      final Collection<PsiReference> overridingReferences =
          ReferencesSearch.search(overridingMethod).findAll();
      methodToReferences.put(overridingMethod, overridingReferences);
    }
    final Set<PsiMethod> validOverriding =
        validateOverridingMethods(
            psiMethod,
            references,
            Arrays.asList(overridingMethods),
            methodToReferences,
            usages,
            allElementsToDelete);
    for (PsiReference reference : references) {
      final PsiElement element = reference.getElement();
      if (!isInside(element, allElementsToDelete) && !isInside(element, validOverriding)) {
        usages.add(
            new SafeDeleteReferenceJavaDeleteUsageInfo(
                element,
                psiMethod,
                PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class) != null));
      }
    }

    final List<PsiMethod> calleesSafeToDelete =
        SafeDeleteJavaCalleeChooser.computeCalleesSafeToDelete(psiMethod);
    if (calleesSafeToDelete != null) {
      for (PsiMethod method : calleesSafeToDelete) {
        usages.add(new SafeDeleteMethodCalleeUsageInfo(method, psiMethod));
      }
    }

    return usage -> {
      if (usage instanceof PsiFile) return false;
      return isInside(usage, allElementsToDelete) || isInside(usage, validOverriding);
    };
  }