public HierarchyBrowserBaseEx(@NotNull Project project, @NotNull PsiElement element) {
    super(project);

    setHierarchyBase(element);

    myCardLayout = new CardLayout();
    myTreePanel = new JPanel(myCardLayout);

    createTrees(myType2TreeMap);

    final HierarchyBrowserManager.State state =
        HierarchyBrowserManager.getInstance(project).getState();
    for (String type : myType2TreeMap.keySet()) {
      myType2ScopeMap.put(type, state.SCOPE != null ? state.SCOPE : SCOPE_ALL);
    }

    final Enumeration<String> keys = myType2TreeMap.keys();
    while (keys.hasMoreElements()) {
      final String key = keys.nextElement();
      final JTree tree = myType2TreeMap.get(key);
      myOccurrenceNavigators.put(
          key,
          new OccurenceNavigatorSupport(tree) {
            @Override
            @Nullable
            protected Navigatable createDescriptorForNode(DefaultMutableTreeNode node) {
              final HierarchyNodeDescriptor descriptor = getDescriptor(node);
              if (descriptor == null) return null;
              PsiElement psiElement = getOpenFileElementFromDescriptor(descriptor);
              if (psiElement == null || !psiElement.isValid()) return null;
              final VirtualFile virtualFile = psiElement.getContainingFile().getVirtualFile();
              if (virtualFile == null) return null;
              return new OpenFileDescriptor(
                  psiElement.getProject(), virtualFile, psiElement.getTextOffset());
            }

            @Override
            public String getNextOccurenceActionName() {
              return getNextOccurenceActionNameImpl();
            }

            @Override
            public String getPreviousOccurenceActionName() {
              return getPrevOccurenceActionNameImpl();
            }
          });
      myTreePanel.add(ScrollPaneFactory.createScrollPane(tree), key);
    }

    final JPanel legendPanel = createLegendPanel();
    final JPanel contentPanel;
    if (legendPanel != null) {
      contentPanel = new JPanel(new BorderLayout());
      contentPanel.add(myTreePanel, BorderLayout.CENTER);
      contentPanel.add(legendPanel, BorderLayout.SOUTH);
    } else {
      contentPanel = myTreePanel;
    }
    buildUi(createToolbar(getActionPlace(), HELP_ID).getComponent(), contentPanel);
  }
 private void disposeBuilders() {
   final Collection<HierarchyTreeBuilder> builders =
       new ArrayList<HierarchyTreeBuilder>(myBuilders.values());
   for (final HierarchyTreeBuilder builder : builders) {
     Disposer.dispose(builder);
   }
   myBuilders.clear();
 }
  public final void changeView(@NotNull final String typeName) {
    myCurrentViewType = typeName;

    final PsiElement element = mySmartPsiElementPointer.getElement();
    if (element == null || !isApplicableElement(element)) {
      return;
    }

    if (myContent != null) {
      final String displayName = getContentDisplayName(typeName, element);
      if (displayName != null) {
        myContent.setDisplayName(displayName);
      }
    }

    myCardLayout.show(myTreePanel, typeName);

    if (!myBuilders.containsKey(typeName)) {
      try {
        setWaitCursor();
        // create builder
        final JTree tree = myType2TreeMap.get(typeName);
        final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode(""));
        tree.setModel(model);

        final HierarchyTreeStructure structure = createHierarchyTreeStructure(typeName, element);
        if (structure == null) {
          return;
        }
        final Comparator<NodeDescriptor> comparator = getComparator();
        final HierarchyTreeBuilder builder =
            new HierarchyTreeBuilder(myProject, tree, model, structure, comparator);

        myBuilders.put(typeName, builder);
        Disposer.register(this, builder);
        Disposer.register(builder, () -> myBuilders.remove(typeName));

        final HierarchyNodeDescriptor descriptor = structure.getBaseDescriptor();
        builder.select(descriptor, () -> builder.expand(descriptor, null));
      } finally {
        restoreCursor();
      }
    }

    getCurrentTree().requestFocus();
  }
 @Override
 protected JTree getCurrentTree() {
   if (myCurrentViewType == null) return null;
   return myType2TreeMap.get(myCurrentViewType);
 }
 @Override
 protected HierarchyTreeBuilder getCurrentBuilder() {
   return myBuilders.get(myCurrentViewType);
 }