@Nullable
  public FilteringTreeStructure.FilteringNode selectPsiElement(PsiElement element) {
    Set<PsiElement> parents = getAllParents(element);

    FilteringTreeStructure.FilteringNode node =
        (FilteringTreeStructure.FilteringNode) myAbstractTreeBuilder.getRootElement();
    while (node != null) {
      boolean changed = false;
      for (FilteringTreeStructure.FilteringNode n : node.children()) {
        final PsiElement psiElement = getPsi(n);
        if (psiElement != null && parents.contains(psiElement)) {
          node = n;
          changed = true;
          break;
        }
      }
      if (!changed) {
        myAbstractTreeBuilder.select(node);
        if (myAbstractTreeBuilder.getSelectedElements().isEmpty()) {
          TreeUtil.selectFirstNode(myTree);
        }
        myInitialNodeIsLeaf = node.getChildren().length == 0;
        return node;
      }
    }
    TreeUtil.selectFirstNode(myTree);
    return null;
  }
    @Nullable
    private Object findClosestTo(PsiElement path, ArrayList<ObjectWithWeight> paths) {
      if (path == null || myInitialPsiElement == null) {
        return paths.get(0).node;
      }
      final Set<PsiElement> parents = getAllParents(myInitialPsiElement);
      ArrayList<ObjectWithWeight> cur = new ArrayList<ObjectWithWeight>();
      int max = -1;
      for (ObjectWithWeight p : paths) {
        final Object last = ((TreePath) p.node).getLastPathComponent();
        final List<PsiElement> elements = new ArrayList<PsiElement>();
        final Object object = ((DefaultMutableTreeNode) last).getUserObject();
        if (object instanceof FilteringTreeStructure.FilteringNode) {
          FilteringTreeStructure.FilteringNode node = (FilteringTreeStructure.FilteringNode) object;
          FilteringTreeStructure.FilteringNode candidate = node;

          while (node != null) {
            elements.add(getPsi(node));
            node = node.getParentNode();
          }
          final int size = ContainerUtil.intersection(parents, elements).size();
          if (size == elements.size() - 1
              && size == parents.size() - (myInitialNodeIsLeaf ? 1 : 0)
              && candidate.children().isEmpty()) {
            return p.node;
          }
          if (size > max) {
            max = size;
            cur.clear();
            cur.add(p);
          } else if (size == max) {
            cur.add(p);
          }
        }
      }

      Collections.sort(
          cur,
          new Comparator<ObjectWithWeight>() {
            @Override
            public int compare(ObjectWithWeight o1, ObjectWithWeight o2) {
              final int i = o1.compareWith(o2);
              return i != 0
                  ? i
                  : ((TreePath) o2.node).getPathCount() - ((TreePath) o1.node).getPathCount();
            }
          });
      return cur.isEmpty() ? null : cur.get(0).node;
    }
 @Nullable
 private PsiElement getPsi(FilteringTreeStructure.FilteringNode n) {
   final Object delegate = n.getDelegate();
   if (delegate instanceof StructureViewComponent.StructureViewTreeElementWrapper) {
     final TreeElement value =
         ((StructureViewComponent.StructureViewTreeElementWrapper) delegate).getValue();
     if (value instanceof StructureViewTreeElement) {
       final Object element = ((StructureViewTreeElement) value).getValue();
       if (element instanceof PsiElement) {
         return (PsiElement) element;
       }
     }
   }
   return null;
 }