private static boolean allSuperMethodsSelectedToDelete(
     List<PsiMethod> unselectedMethods, PsiMethod method) {
   final ArrayList<PsiMethod> superMethods =
       new ArrayList<>(Arrays.asList(method.findSuperMethods()));
   superMethods.retainAll(unselectedMethods);
   return superMethods.isEmpty();
 }
  @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);
    };
  }
  @Nullable
  @Override
  public Collection<? extends PsiElement> getElementsToSearch(
      @NotNull PsiElement element,
      @Nullable Module module,
      @NotNull Collection<PsiElement> allElementsToDelete) {
    Project project = element.getProject();
    if (element instanceof PsiPackage && module != null) {
      final PsiDirectory[] directories =
          ((PsiPackage) element).getDirectories(module.getModuleScope());
      if (directories.length == 0) return null;
      return Arrays.asList(directories);
    } else if (element instanceof PsiMethod) {
      final PsiMethod[] methods =
          SuperMethodWarningUtil.checkSuperMethods(
              (PsiMethod) element,
              RefactoringBundle.message("to.delete.with.usage.search"),
              allElementsToDelete);
      if (methods.length == 0) return null;
      final ArrayList<PsiMethod> psiMethods = new ArrayList<>(Arrays.asList(methods));
      psiMethods.add((PsiMethod) element);
      return psiMethods;
    } else if (element instanceof PsiParameter
        && ((PsiParameter) element).getDeclarationScope() instanceof PsiMethod) {
      PsiMethod method = (PsiMethod) ((PsiParameter) element).getDeclarationScope();
      final Set<PsiParameter> parametersToDelete = new HashSet<>();
      parametersToDelete.add((PsiParameter) element);
      final int parameterIndex =
          method.getParameterList().getParameterIndex((PsiParameter) element);
      final List<PsiMethod> superMethods =
          new ArrayList<>(Arrays.asList(method.findDeepestSuperMethods()));
      if (superMethods.isEmpty()) {
        superMethods.add(method);
      }
      for (PsiMethod superMethod : superMethods) {
        parametersToDelete.add(superMethod.getParameterList().getParameters()[parameterIndex]);
        OverridingMethodsSearch.search(superMethod)
            .forEach(
                overrider -> {
                  parametersToDelete.add(
                      overrider.getParameterList().getParameters()[parameterIndex]);
                  return true;
                });
      }

      if (parametersToDelete.size() > 1 && !ApplicationManager.getApplication().isUnitTestMode()) {
        String message =
            RefactoringBundle.message(
                "0.is.a.part.of.method.hierarchy.do.you.want.to.delete.multiple.parameters",
                UsageViewUtil.getLongName(method));
        int result =
            Messages.showYesNoCancelDialog(
                project, message, SafeDeleteHandler.REFACTORING_NAME, Messages.getQuestionIcon());
        if (result == Messages.CANCEL) return null;
        if (result == Messages.NO) return Collections.singletonList(element);
      }
      return parametersToDelete;
    } else if (element instanceof PsiTypeParameter) {
      final PsiTypeParameterListOwner owner = ((PsiTypeParameter) element).getOwner();
      if (owner instanceof PsiMethod && !owner.hasModifierProperty(PsiModifier.STATIC)) {
        final PsiTypeParameterList typeParameterList = owner.getTypeParameterList();
        if (typeParameterList != null) {
          final int index = typeParameterList.getTypeParameterIndex((PsiTypeParameter) element);
          if (index >= 0) {
            final ArrayList<PsiTypeParameter> overriders = new ArrayList<>();
            overriders.add((PsiTypeParameter) element);
            OverridingMethodsSearch.search((PsiMethod) owner)
                .forEach(
                    overrider -> {
                      final PsiTypeParameter[] typeParameters = overrider.getTypeParameters();
                      if (index < typeParameters.length) {
                        overriders.add(typeParameters[index]);
                      }
                      return true;
                    });
            if (overriders.size() > 1) {
              String message =
                  RefactoringBundle.message(
                      "0.is.a.part.of.method.hierarchy.do.you.want.to.delete.multiple.type.parameters",
                      UsageViewUtil.getLongName(owner));
              int result =
                  ApplicationManager.getApplication().isUnitTestMode()
                      ? Messages.YES
                      : Messages.showYesNoCancelDialog(
                          project,
                          message,
                          SafeDeleteHandler.REFACTORING_NAME,
                          Messages.getQuestionIcon());
              if (result == Messages.CANCEL) return null;
              if (result == Messages.YES) return overriders;
            }
          }
        }
      }
    }

    return Collections.singletonList(element);
  }
 private static boolean isInside(PsiElement place, PsiElement[] ancestors) {
   return isInside(place, Arrays.asList(ancestors));
 }