public FileStructurePopup(
      StructureViewModel structureViewModel,
      @Nullable Editor editor,
      Project project,
      @NotNull final Disposable auxDisposable,
      final boolean applySortAndFilter) {
    myProject = project;
    myEditor = editor;

    // Stop code analyzer to speedup EDT
    final DaemonCodeAnalyzer analyzer = DaemonCodeAnalyzer.getInstance(myProject);
    if (analyzer != null) {
      myDaemonUpdateEnabled = ((DaemonCodeAnalyzerImpl) analyzer).isUpdateByTimerEnabled();
      analyzer.setUpdateByTimerEnabled(false);
    } else {
      myDaemonUpdateEnabled = false;
    }

    IdeFocusManager.getInstance(myProject).typeAheadUntil(myTreeHasBuilt);
    myBaseTreeModel = structureViewModel;
    Disposer.register(this, auxDisposable);
    if (applySortAndFilter) {
      myTreeActionsOwner = new TreeStructureActionsOwner(myBaseTreeModel);
      myTreeModel = new TreeModelWrapper(structureViewModel, myTreeActionsOwner);
    } else {
      myTreeActionsOwner = null;
      myTreeModel = structureViewModel;
    }

    myTreeStructure =
        new SmartTreeStructure(project, myTreeModel) {
          public void rebuildTree() {
            if (ApplicationManager.getApplication().isUnitTestMode() || !myPopup.isDisposed()) {
              super.rebuildTree();
            }
          }

          public boolean isToBuildChildrenInBackground(final Object element) {
            return getRootElement() == element;
          }

          protected TreeElementWrapper createTree() {
            return new StructureViewComponent.StructureViewTreeElementWrapper(
                myProject, myModel.getRoot(), myModel);
          }

          @Override
          public String toString() {
            return "structure view tree structure(model=" + myTreeModel + ")";
          }
        };

    myTree =
        new FileStructureTree(
            myTreeStructure.getRootElement(), Registry.is("fast.tree.expand.in.structure.view"));

    myTree.setCellRenderer(
        new NodeRenderer() {
          @Override
          protected void doAppend(
              @NotNull @Nls String fragment,
              @NotNull SimpleTextAttributes attributes,
              boolean isMainText,
              boolean selected) {
            SpeedSearchUtil.appendFragmentsForSpeedSearch(
                myTree, fragment, attributes, selected, this);
          }

          @Override
          public void doAppend(
              @NotNull String fragment,
              @NotNull SimpleTextAttributes attributes,
              boolean selected) {
            SpeedSearchUtil.appendFragmentsForSpeedSearch(
                myTree, fragment, attributes, selected, this);
          }

          @Override
          public void doAppend(String fragment, boolean selected) {
            SpeedSearchUtil.appendFragmentsForSpeedSearch(
                myTree, fragment, SimpleTextAttributes.REGULAR_ATTRIBUTES, selected, this);
          }
        });

    mySpeedSearch = new MyTreeSpeedSearch();
    mySpeedSearch.setComparator(new SpeedSearchComparator(false, true));

    final FileStructurePopupFilter filter = new FileStructurePopupFilter();
    myFilteringStructure =
        new FilteringTreeStructure(
            filter, myTreeStructure, ApplicationManager.getApplication().isUnitTestMode());
    myAbstractTreeBuilder =
        new FilteringTreeBuilder(myTree, filter, myFilteringStructure, null) {
          @Override
          public void initRootNode() {}

          @Override
          protected boolean validateNode(Object child) {
            return StructureViewComponent.isValid(child);
          }

          @Override
          public void revalidateTree() {
            // myTree.revalidate();
            // myTree.repaint();
          }

          @Override
          public boolean isToEnsureSelectionOnFocusGained() {
            return false;
          }
        };

    myTreeExpander = new DefaultTreeExpander(myTree);

    // myAbstractTreeBuilder.getUi().setPassthroughMode(true);
    myAbstractTreeBuilder.getUi().getUpdater().setDelay(1);
    myInitialPsiElement = getCurrentElement(getPsiFile(myProject));
    // myAbstractTreeBuilder.setCanYieldUpdate(true);
    Disposer.register(this, myAbstractTreeBuilder);
  }
  public StructureViewComponent(
      final FileEditor editor,
      final StructureViewModel structureViewModel,
      final Project project,
      final boolean showRootNode) {
    super(true, true);

    myProject = project;
    myFileEditor = editor;
    myTreeModel = structureViewModel;
    myTreeModelWrapper = new TreeModelWrapper(myTreeModel, this);

    SmartTreeStructure treeStructure =
        new SmartTreeStructure(project, myTreeModelWrapper) {
          public void rebuildTree() {
            if (!isDisposed()) {
              super.rebuildTree();
            }
          }

          public boolean isToBuildChildrenInBackground(final Object element) {
            return getRootElement() == element;
          }

          protected TreeElementWrapper createTree() {
            return new StructureViewTreeElementWrapper(myProject, myModel.getRoot(), myModel);
          }

          @Override
          public String toString() {
            return "structure view tree structure(model=" + myTreeModel + ")";
          }
        };

    final DefaultTreeModel model =
        new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.getRootElement()));
    myTree = new Tree(model);
    myTree.setRootVisible(showRootNode);
    myTree.setShowsRootHandles(true);

    myAbstractTreeBuilder =
        new StructureTreeBuilder(
            project,
            myTree,
            (DefaultTreeModel) myTree.getModel(),
            treeStructure,
            myTreeModelWrapper) {
          @Override
          protected boolean validateNode(Object child) {
            return isValid(child);
          }
        };
    Disposer.register(this, myAbstractTreeBuilder);
    Disposer.register(
        myAbstractTreeBuilder,
        new Disposable() {
          public void dispose() {
            storeState();
          }
        });

    setContent(ScrollPaneFactory.createScrollPane(myAbstractTreeBuilder.getTree()));

    myAbstractTreeBuilder.getTree().setCellRenderer(new NodeRenderer());

    myAutoScrollToSourceHandler = new MyAutoScrollToSourceHandler();
    myAutoScrollFromSourceHandler = new MyAutoScrollFromSourceHandler(myProject, this);

    JComponent toolbarComponent =
        ActionManager.getInstance()
            .createActionToolbar(ActionPlaces.STRUCTURE_VIEW_TOOLBAR, createActionGroup(), true)
            .getComponent();
    setToolbar(toolbarComponent);

    installTree();

    myCopyPasteDelegator =
        new CopyPasteDelegator(myProject, getTree()) {
          @NotNull
          protected PsiElement[] getSelectedElements() {
            return getSelectedPsiElements();
          }
        };
  }