public UsageNode doAppendUsage(@NotNull Usage usage) {
    ApplicationManager.getApplication().assertIsNonDispatchThread();
    // invoke in ReadAction to 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;
    }

    for (UsageViewElementsListener listener : UsageViewElementsListener.EP_NAME.getExtensionList()) {
      if (listener.skipUsage(this, usage)) {
        return null;
      }
      listener.beforeUsageAdded(this, usage);
    }

    if (usage instanceof PsiElementUsage) {
      reportToFUS((PsiElementUsage)usage);
    }

    UsageNode recentNode = myBuilder.appendOrGet(usage, isFilterDuplicateLines(), edtModelToSwingNodeChangesQueue);
    myUsageNodes.put(usage, recentNode == null ? NULL_NODE : recentNode);
    if (myAutoSelectedGroupNode == null && usage instanceof SimilarUsage && recentNode != null && !myPresentation.isDetachedMode()) {
      UIUtil.invokeLaterIfNeeded(() -> {
        GroupNode groupNode = ObjectUtils.tryCast(TreeUtil.getPath(myRoot, recentNode).getPath()[1], GroupNode.class);
        if (groupNode != null && getSelectedNode() instanceof UsageViewTreeModelBuilder.TargetsRootNode) {
          myAutoSelectedGroupNode = groupNode;
          showNode(groupNode);
        }
      });
    }
    if (recentNode != null && getPresentation().isExcludeAvailable()) {
      for (UsageViewElementsListener listener : UsageViewElementsListener.EP_NAME.getExtensionList()) {
        if (listener.isExcludedByDefault(this, usage)) {
          myExclusionHandler.excludeNodeSilently(recentNode);
        }
      }
    }

    for (Node node = recentNode; node != myRoot && node != null; node = (Node)node.getParent()) {
      node.update(edtFireTreeNodesChangedQueue);
    }

    return recentNode;
  }
public UsageNode doAppendUsage(@NotNull Usage usage)