@Override
 public void excludeUsages(@NotNull Usage[] usages) {
   for (Usage usage : usages) {
     final UsageNode node = myUsageNodes.get(usage);
     if (node != NULL_NODE && node != null) {
       node.setUsageExcluded(true);
     }
   }
   updateImmediately();
 }
 @NotNull
 private Set<Usage> getReadOnlyUsages() {
   final Set<Usage> result = new THashSet<Usage>();
   final Set<Map.Entry<Usage, UsageNode>> usages = myUsageNodes.entrySet();
   for (Map.Entry<Usage, UsageNode> entry : usages) {
     Usage usage = entry.getKey();
     UsageNode node = entry.getValue();
     if (node != null && node != NULL_NODE && !node.isExcluded() && usage.isReadOnly()) {
       result.add(usage);
     }
   }
   return result;
 }
  @Override
  public void selectUsages(@NotNull Usage[] usages) {
    List<TreePath> paths = new LinkedList<TreePath>();

    for (Usage usage : usages) {
      final UsageNode node = myUsageNodes.get(usage);

      if (node != NULL_NODE && node != null) {
        paths.add(new TreePath(node.getPath()));
      }
    }

    myTree.setSelectionPaths(paths.toArray(new TreePath[paths.size()]));
    if (!paths.isEmpty()) myTree.scrollPathToVisible(paths.get(0));
  }
 @Override
 public void removeUsage(@NotNull Usage usage) {
   final UsageNode node = myUsageNodes.remove(usage);
   if (node != NULL_NODE && node != null && !myPresentation.isDetachedMode()) {
     UIUtil.invokeLaterIfNeeded(
         new Runnable() {
           @Override
           public void run() {
             if (isDisposed) return;
             TreeModel treeModel = myTree.getModel();
             ((DefaultTreeModel) treeModel).removeNodeFromParent(node);
             ((GroupNode) myTree.getModel().getRoot()).removeUsage(node);
           }
         });
   }
 }
 public UsageNode doAppendUsage(@NotNull Usage usage) {
   // invoke in ReadAction to be be sure that usages are not invalidated while the tree is being
   // built
   ApplicationManager.getApplication().assertReadAccessAllowed();
   if (!usage.isValid()) {
     // because the view is built incrementally, the usage may be already invalid, so need to
     // filter such cases
     return null;
   }
   UsageNode node = myBuilder.appendUsage(usage);
   myUsageNodes.put(usage, node == null ? NULL_NODE : node);
   if (!myIsFirstVisibleUsageFound && node != null) { // first visible usage found;
     myIsFirstVisibleUsageFound = true;
     showNode(node);
   }
   return node;
 }
  @Override
  @NotNull
  public Set<Usage> getExcludedUsages() {
    Set<Usage> result = new THashSet<Usage>();
    for (Map.Entry<Usage, UsageNode> entry : myUsageNodes.entrySet()) {
      UsageNode node = entry.getValue();
      Usage usage = entry.getKey();
      if (node == NULL_NODE || node == null) {
        continue;
      }
      if (node.isExcluded()) {
        result.add(usage);
      }
    }

    return result;
  }
  private void reset() {
    ApplicationManager.getApplication().assertIsDispatchThread();

    myUsageNodes.clear();
    myIsFirstVisibleUsageFound = false;

    myModel.reset();
    if (!myPresentation.isDetachedMode()) {
      SwingUtilities.invokeLater(
          new Runnable() {
            @Override
            public void run() {
              if (isDisposed) return;
              TreeUtil.expand(myTree, 2);
            }
          });
    }
  }
 private void rulesChanged() {
   ApplicationManager.getApplication().assertIsDispatchThread();
   final ArrayList<UsageState> states = new ArrayList<UsageState>();
   captureUsagesExpandState(new TreePath(myTree.getModel().getRoot()), states);
   final List<Usage> allUsages = new ArrayList<Usage>(myUsageNodes.keySet());
   Collections.sort(allUsages, USAGE_COMPARATOR);
   final Set<Usage> excludedUsages = getExcludedUsages();
   reset();
   myBuilder.setGroupingRules(getActiveGroupingRules(myProject));
   myBuilder.setFilteringRules(getActiveFilteringRules(myProject));
   ApplicationManager.getApplication()
       .runReadAction(
           new Runnable() {
             @Override
             public void run() {
               for (Usage usage : allUsages) {
                 if (!usage.isValid()) {
                   continue;
                 }
                 if (usage instanceof MergeableUsage) {
                   ((MergeableUsage) usage).reset();
                 }
                 appendUsage(usage);
               }
             }
           });
   excludeUsages(excludedUsages.toArray(new Usage[excludedUsages.size()]));
   if (myCentralPanel != null) {
     setupCentralPanel();
   }
   SwingUtilities.invokeLater(
       new Runnable() {
         @Override
         public void run() {
           if (isDisposed) return;
           restoreUsageExpandState(states);
           updateImmediately();
         }
       });
 }
  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"));
      }
    }
  }
 @Override
 public int getUsagesCount() {
   return myUsageNodes.size();
 }
 @Override
 @NotNull
 public Set<Usage> getUsages() {
   return myUsageNodes.keySet();
 }