public void deleteElement(@NotNull DataContext dataContext) {
   PsiElement[] elements = getPsiElements(dataContext);
   if (elements == null) return;
   Project project = PlatformDataKeys.PROJECT.getData(dataContext);
   if (project == null) return;
   LocalHistoryAction a =
       LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting"));
   try {
     deletePsiElement(elements, project);
   } finally {
     a.finish();
   }
 }
    public void deleteElement(DataContext dataContext) {
      List<PsiElement> allElements = Arrays.asList(getElementsToDelete());
      List<PsiElement> validElements = new ArrayList<PsiElement>();
      for (PsiElement psiElement : allElements) {
        if (psiElement != null && psiElement.isValid()) validElements.add(psiElement);
      }
      final PsiElement[] elements = validElements.toArray(new PsiElement[validElements.size()]);

      LocalHistoryAction a =
          LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting"));
      try {
        DeleteHandler.deletePsiElement(elements, myProject);
      } finally {
        a.finish();
      }
    }
  private static void replaceDuplicate(
      final Project project,
      final Map<PsiMember, List<Match>> duplicates,
      final Set<PsiMember> methods) {
    final ProgressIndicator progressIndicator =
        ProgressManager.getInstance().getProgressIndicator();
    if (progressIndicator != null && progressIndicator.isCanceled()) return;

    final Runnable replaceRunnable =
        () -> {
          LocalHistoryAction a = LocalHistory.getInstance().startAction(REFACTORING_NAME);
          try {
            for (final PsiMember member : methods) {
              final List<Match> matches = duplicates.get(member);
              if (matches == null) continue;
              final int duplicatesNo = matches.size();
              WindowManager.getInstance()
                  .getStatusBar(project)
                  .setInfo(getStatusMessage(duplicatesNo));
              CommandProcessor.getInstance()
                  .executeCommand(
                      project,
                      () ->
                          PostprocessReformattingAspect.getInstance(project)
                              .postponeFormattingInside(
                                  () -> {
                                    final MatchProvider matchProvider =
                                        member instanceof PsiMethod
                                            ? new MethodDuplicatesMatchProvider(
                                                (PsiMethod) member, matches)
                                            : new ConstantMatchProvider(member, project, matches);
                                    DuplicatesImpl.invoke(project, matchProvider);
                                  }),
                      REFACTORING_NAME,
                      REFACTORING_NAME);

              WindowManager.getInstance().getStatusBar(project).setInfo("");
            }
          } finally {
            a.finish();
          }
        };
    ApplicationManager.getApplication().invokeLater(replaceRunnable, ModalityState.NON_MODAL);
  }
  // invoked inside Command and Atomic action
  private void doRefactoring(
      final Project project, final PsiClass subclass, final ExtractSuperclassDialog dialog) {
    final String superclassName = dialog.getExtractedSuperName();
    final PsiDirectory targetDirectory = dialog.getTargetDirectory();
    final MemberInfo[] selectedMemberInfos =
        ArrayUtil.toObjectArray(dialog.getSelectedMemberInfos(), MemberInfo.class);
    final DocCommentPolicy javaDocPolicy = new DocCommentPolicy(dialog.getDocCommentPolicy());
    LocalHistoryAction a =
        LocalHistory.getInstance().startAction(getCommandName(subclass, superclassName));
    try {
      final PsiClass superclass;

      try {
        superclass =
            ExtractSuperClassUtil.extractSuperClass(
                project,
                targetDirectory,
                superclassName,
                subclass,
                selectedMemberInfos,
                javaDocPolicy);
      } finally {
        a.finish();
      }

      // ask whether to search references to subclass and turn them into refs to superclass if
      // possible
      if (superclass != null) {
        final SmartPsiElementPointer<PsiClass> classPointer =
            SmartPointerManager.getInstance(project).createSmartPsiElementPointer(subclass);
        final SmartPsiElementPointer<PsiClass> interfacePointer =
            SmartPointerManager.getInstance(project).createSmartPsiElementPointer(superclass);
        final Runnable turnRefsToSuperRunnable =
            new Runnable() {
              public void run() {
                ExtractClassUtil.askAndTurnRefsToSuper(project, classPointer, interfacePointer);
              }
            };
        SwingUtilities.invokeLater(turnRefsToSuperRunnable);
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  public void testSavingDocumentBeforeAndAfterAction() throws Exception {
    VirtualFile f = createFile("f.txt", "file1");

    setContent(f, "file2");

    setDocumentTextFor(f, "doc1");

    LocalHistoryAction a = LocalHistory.getInstance().startAction("name");
    setDocumentTextFor(f, "doc2");
    a.finish();

    List<Revision> rr = getRevisionsFor(f);
    assertEquals(5, rr.size());
    assertContent("doc2", rr.get(0).findEntry());
    assertEquals("name", rr.get(1).getChangeSetName());
    assertContent("doc1", rr.get(1).findEntry());
    assertContent("file2", rr.get(2).findEntry());
    assertContent("file1", rr.get(3).findEntry());
  }
  private void doRefactoring() throws IncorrectOperationException {
    LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
    final PsiClass anInterface;
    try {
      anInterface =
          extractInterface(
              myTargetDir, myClass, myInterfaceName, mySelectedMembers, myJavaDocPolicy);
    } finally {
      a.finish();
    }

    if (anInterface != null) {
      final Runnable turnRefsToSuperRunnable =
          new Runnable() {
            @Override
            public void run() {
              ExtractClassUtil.askAndTurnRefsToSuper(myProject, myClass, anInterface);
            }
          };
      SwingUtilities.invokeLater(turnRefsToSuperRunnable);
    }
  }
  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"));
      }
    }
  }