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();
         }
       });
 }
 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;
 }
 public boolean isVisible(@NotNull Usage usage) {
   return myBuilder != null && myBuilder.isVisible(usage);
 }