@Override
 public Collection<String> findConflicts(
     PsiElement element, PsiElement[] elements, UsageInfo[] usages) {
   String methodRefFound = null;
   if (!ApplicationManager.getApplication().isUnitTestMode()
       && (element instanceof PsiMethod || element instanceof PsiParameter)) {
     for (UsageInfo usage : usages) {
       final PsiElement refElement = usage.getElement();
       if (refElement instanceof PsiMethodReferenceExpression) {
         methodRefFound = RefactoringBundle.message("expand.method.reference.warning");
         break;
       }
     }
   }
   if (methodRefFound != null) {
     Collection<String> result = new ArrayList<>();
     result.add(methodRefFound);
     final Collection<String> conflicts = super.findConflicts(element, elements, usages);
     if (conflicts != null) {
       result.addAll(conflicts);
     }
     return result;
   }
   return super.findConflicts(element, elements, usages);
 }
  public Collection<PsiElement> getAdditionalElementsToDelete(
      @NotNull final PsiElement element,
      @NotNull final Collection<PsiElement> allElementsToDelete,
      final boolean askUser) {
    if (element instanceof PsiField) {
      PsiField field = (PsiField) element;
      final Project project = element.getProject();
      String propertyName =
          JavaCodeStyleManager.getInstance(project)
              .variableNameToPropertyName(field.getName(), VariableKind.FIELD);

      PsiClass aClass = field.getContainingClass();
      if (aClass != null) {
        boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
        PsiMethod[] getters =
            GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic);
        if (getters != null) {
          final List<PsiMethod> validGetters = new ArrayList<>(1);
          for (PsiMethod getter : getters) {
            if (!allElementsToDelete.contains(getter) && (getter != null && getter.isPhysical())) {
              validGetters.add(getter);
            }
          }
          getters =
              validGetters.isEmpty()
                  ? null
                  : validGetters.toArray(new PsiMethod[validGetters.size()]);
        }

        PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false);
        if (allElementsToDelete.contains(setter) || setter != null && !setter.isPhysical())
          setter = null;
        if (askUser && (getters != null || setter != null)) {
          final String message =
              RefactoringMessageUtil.getGetterSetterMessage(
                  field.getName(),
                  RefactoringBundle.message("delete.title"),
                  getters != null ? getters[0] : null,
                  setter);
          if (!ApplicationManager.getApplication().isUnitTestMode()
              && Messages.showYesNoDialog(
                      project,
                      message,
                      RefactoringBundle.message("safe.delete.title"),
                      Messages.getQuestionIcon())
                  != Messages.YES) {
            getters = null;
            setter = null;
          }
        }
        List<PsiElement> elements = new ArrayList<>();
        if (setter != null) elements.add(setter);
        if (getters != null) Collections.addAll(elements, getters);
        return elements;
      }
    }
    return null;
  }
  private static void findTypeParameterExternalUsages(
      final PsiTypeParameter typeParameter, final Collection<UsageInfo> usages) {
    PsiTypeParameterListOwner owner = typeParameter.getOwner();
    if (owner != null) {
      final PsiTypeParameterList parameterList = owner.getTypeParameterList();
      if (parameterList != null) {
        final int paramsCount = parameterList.getTypeParameters().length;
        final int index = parameterList.getTypeParameterIndex(typeParameter);

        ReferencesSearch.search(owner)
            .forEach(
                reference -> {
                  if (reference instanceof PsiJavaCodeReferenceElement) {
                    final PsiReferenceParameterList parameterList1 =
                        ((PsiJavaCodeReferenceElement) reference).getParameterList();
                    if (parameterList1 != null) {
                      PsiTypeElement[] typeArgs = parameterList1.getTypeParameterElements();
                      if (typeArgs.length > index) {
                        if (typeArgs.length == 1
                            && paramsCount > 1
                            && typeArgs[0].getType() instanceof PsiDiamondType) return true;
                        usages.add(
                            new SafeDeleteReferenceJavaDeleteUsageInfo(
                                typeArgs[index], typeParameter, true));
                      }
                    }
                  }
                  return true;
                });
      }
    }
  }
 @NotNull
 public Collection<String> getMessages() {
   List<String> result = new ArrayList<>(messages);
   for (int i = 0; i < messages.size(); i++) {
     result.set(i, result.get(i).replaceAll("<[^>]+>", ""));
   }
   return result;
 }
 private void captureUsagesExpandState(TreePath pathFrom, final Collection<UsageState> states) {
   if (!myTree.isExpanded(pathFrom)) {
     return;
   }
   final DefaultMutableTreeNode node = (DefaultMutableTreeNode) pathFrom.getLastPathComponent();
   final int childCount = node.getChildCount();
   for (int idx = 0; idx < childCount; idx++) {
     final TreeNode child = node.getChildAt(idx);
     if (child instanceof UsageNode) {
       final Usage usage = ((UsageNode) child).getUsage();
       states.add(
           new UsageState(
               usage,
               myTree.getSelectionModel().isPathSelected(pathFrom.pathByAddingChild(child))));
     } else {
       captureUsagesExpandState(pathFrom.pathByAddingChild(child), states);
     }
   }
 }
  private void doRefactoring(@NotNull final Collection<UsageInfo> usageInfoSet) {
    for (Iterator<UsageInfo> iterator = usageInfoSet.iterator(); iterator.hasNext(); ) {
      UsageInfo usageInfo = iterator.next();
      final PsiElement element = usageInfo.getElement();
      if (element == null || !isToBeChanged(usageInfo)) {
        iterator.remove();
      }
    }

    LocalHistoryAction action = LocalHistory.getInstance().startAction(getCommandName());

    final UsageInfo[] writableUsageInfos = usageInfoSet.toArray(new UsageInfo[usageInfoSet.size()]);
    try {
      PsiDocumentManager.getInstance(myProject).commitAllDocuments();
      RefactoringListenerManagerImpl listenerManager =
          (RefactoringListenerManagerImpl) RefactoringListenerManager.getInstance(myProject);
      myTransaction = listenerManager.startTransaction();
      final Map<RefactoringHelper, Object> preparedData = new LinkedHashMap<>();
      final Runnable prepareHelpersRunnable =
          new Runnable() {
            @Override
            public void run() {
              for (final RefactoringHelper helper :
                  Extensions.getExtensions(RefactoringHelper.EP_NAME)) {
                Object operation =
                    ApplicationManager.getApplication()
                        .runReadAction(
                            new Computable<Object>() {
                              @Override
                              public Object compute() {
                                return helper.prepareOperation(writableUsageInfos);
                              }
                            });
                preparedData.put(helper, operation);
              }
            }
          };

      ProgressManager.getInstance()
          .runProcessWithProgressSynchronously(
              prepareHelpersRunnable, "Prepare ...", false, myProject);

      ApplicationManager.getApplication()
          .runWriteAction(
              new Runnable() {
                @Override
                public void run() {
                  final String refactoringId = getRefactoringId();
                  if (refactoringId != null) {
                    RefactoringEventData data = getBeforeData();
                    if (data != null) {
                      data.addUsages(usageInfoSet);
                    }
                    myProject
                        .getMessageBus()
                        .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
                        .refactoringStarted(refactoringId, data);
                  }

                  try {
                    if (refactoringId != null) {
                      UndoableAction action = new UndoRefactoringAction(myProject, refactoringId);
                      UndoManager.getInstance(myProject).undoableActionPerformed(action);
                    }

                    performRefactoring(writableUsageInfos);
                  } finally {
                    if (refactoringId != null) {
                      myProject
                          .getMessageBus()
                          .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
                          .refactoringDone(refactoringId, getAfterData(writableUsageInfos));
                    }
                  }
                }
              });

      DumbService.getInstance(myProject).completeJustSubmittedTasks();

      for (Map.Entry<RefactoringHelper, Object> e : preparedData.entrySet()) {
        //noinspection unchecked
        e.getKey().performOperation(myProject, e.getValue());
      }
      myTransaction.commit();
      ApplicationManager.getApplication()
          .runWriteAction(
              new Runnable() {
                @Override
                public void run() {
                  performPsiSpoilingRefactoring();
                }
              });
    } finally {
      action.finish();
    }

    int count = writableUsageInfos.length;
    if (count > 0) {
      StatusBarUtil.setStatusBarInfo(
          myProject, RefactoringBundle.message("statusBar.refactoring.result", count));
    } else {
      if (!isPreviewUsages(writableUsageInfos)) {
        StatusBarUtil.setStatusBarInfo(myProject, RefactoringBundle.message("statusBar.noUsages"));
      }
    }
  }