@NotNull
 public String calculateNodeIdentifier() {
   if (getNode() == null) {
     return "null";
   }
   String name;
   if (myHierarchyTree.overridesNodeIdentifierCalculation()) {
     name = myHierarchyTree.calculateNodeIdentifier(this);
   } else {
     name = getNode().getName();
   }
   return (name == null ? "no name" : name);
 }
  @Override
  protected void createTool() {
    myHierarchyTree = createHierarchyTree(false);
    myOccurenceNavigator =
        new OccurenceNavigatorSupport(myHierarchyTree) {
          @Nullable
          @Override
          protected Navigatable createDescriptorForNode(DefaultMutableTreeNode node) {
            if (!(node instanceof HierarchyTreeNode)) {
              return null;
            }

            SNodeReference ptr = ((HierarchyTreeNode) node).getNodeReference();

            Navigatable n = new NodeNavigatable(getMPSProject(), ptr);
            return (n.canNavigate() ? n : null);
          }

          @Override
          public String getPreviousOccurenceActionName() {
            return UsageViewBundle.message("action.previous.occurrence");
          }

          @Override
          public String getNextOccurenceActionName() {
            return UsageViewBundle.message("action.next.occurrence");
          }
        };
    myHierarchyTree.setRootVisible(true);
    this.myComponent = new AbstractHierarchyView.RootPanel();
    myScrollPane = ScrollPaneFactory.createScrollPane(myHierarchyTree, true);
    myComponent.setContent(myScrollPane);
    showItemInHierarchy(null);
    createControlPanel();
  }
 @Override
 public void disposeComponent() {
   if (myHierarchyTree == null) {
     return;
   }
   myHierarchyTree.dispose();
 }
 public void showItemInHierarchy(SNode node) {
   myHierarchyTree.setHierarchyNode(node);
   final jetbrains.mps.project.Project mpsProject = getMPSProject();
   mpsProject
       .getModelAccess()
       .runReadInEDT(
           new Runnable() {
             @Override
             public void run() {
               Project project = getProject();
               if (project == null || project.isDisposed()) {
                 return;
               }
               myHierarchyTree.rebuildNow();
               if (myHierarchyTree.getActiveTreeNode() != null) {
                 myHierarchyTree.setRootNodeText(
                     "<html>Hierarchy for <font color=\"#400090\"><b>"
                         + StringUtil.escapeXml(
                             myHierarchyTree.getActiveTreeNode().calculateNodeIdentifier())
                         + "</b></font>",
                     getIcon());
                 myHierarchyTree.selectNode(myHierarchyTree.getActiveTreeNode());
               }
               if (!(isTreeInfinite())) {
                 myHierarchyTree.expandAll();
               }
             }
           });
 }
 @Override
 public void doubleClick() {
   if (myHierarchyTree.doubleClick(HierarchyTreeNode.this)) {
     return;
   }
   ModelAccess.instance()
       .runWriteInEDT(
           new Runnable() {
             @Override
             public void run() {
               if (jetbrains.mps.util.SNodeOperations.isDisposed(myNode)
                   || !(myNode.getModel() != null)
                   || myNode.getModel() == null) {
                 return;
               }
               AbstractHierarchyView hierarchyView = myHierarchyTree.getHierarchyView();
               if (hierarchyView != null) {
                 // TODO: use node pointers here
                 hierarchyView.openNode(myNode, getOperationContext());
               }
             }
           });
 }