@Override
    public Object findElement(String s) {
      List<ObjectWithWeight> elements = new ArrayList<ObjectWithWeight>();
      s = s.trim();
      final ListIterator<Object> it = getElementIterator(0);
      while (it.hasNext()) {
        final ObjectWithWeight o = new ObjectWithWeight(it.next(), s, getComparator());
        if (!o.weights.isEmpty()) {
          elements.add(o);
        }
      }
      ObjectWithWeight cur = null;
      ArrayList<ObjectWithWeight> current = new ArrayList<ObjectWithWeight>();
      for (ObjectWithWeight element : elements) {
        if (cur == null) {
          cur = element;
          current.add(cur);
          continue;
        }

        final int i = element.compareWith(cur);
        if (i == 0) {
          current.add(element);
        } else if (i < 0) {
          cur = element;
          current.clear();
          current.add(cur);
        }
      }

      return current.isEmpty() ? null : findClosestTo(myInitialPsiElement, current);
    }
    @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;
    }
 private List<InjInfo> getSelectedInjections() {
   final ArrayList<InjInfo> toRemove = new ArrayList<InjInfo>();
   for (int row : myInjectionsTable.getSelectedRows()) {
     toRemove.add(myInjectionsTable.getItems().get(myInjectionsTable.convertRowIndexToModel(row)));
   }
   return toRemove;
 }
 public void selectElements(ClassMember[] elements) {
   ArrayList<TreePath> selectionPaths = new ArrayList<TreePath>();
   for (ClassMember element : elements) {
     MemberNode treeNode = myElementToNodeMap.get(element);
     if (treeNode != null) {
       selectionPaths.add(new TreePath(((DefaultMutableTreeNode) treeNode).getPath()));
     }
   }
   myTree.setSelectionPaths(selectionPaths.toArray(new TreePath[selectionPaths.size()]));
 }
  private static void sortNode(ParentNode node, final Comparator<ElementNode> sortComparator) {
    ArrayList<MemberNode> arrayList = new ArrayList<MemberNode>();
    Enumeration<MemberNode> children = node.children();
    while (children.hasMoreElements()) {
      arrayList.add(children.nextElement());
    }

    Collections.sort(arrayList, sortComparator);

    replaceChildren(node, arrayList);
  }
  protected void restoreTree() {
    Pair<ElementNode, List<ElementNode>> selection = storeSelection();

    DefaultMutableTreeNode root = getRootNode();
    if (!myShowClasses || myContainerNodes.isEmpty()) {
      List<ParentNode> otherObjects = new ArrayList<ParentNode>();
      Enumeration<ParentNode> children = getRootNodeChildren();
      ParentNode newRoot =
          new ParentNode(
              null, new MemberChooserObjectBase(getAllContainersNodeName()), new Ref<Integer>(0));
      while (children.hasMoreElements()) {
        final ParentNode nextElement = children.nextElement();
        if (nextElement instanceof ContainerNode) {
          final ContainerNode containerNode = (ContainerNode) nextElement;
          Enumeration<MemberNode> memberNodes = containerNode.children();
          List<MemberNode> memberNodesList = new ArrayList<MemberNode>();
          while (memberNodes.hasMoreElements()) {
            memberNodesList.add(memberNodes.nextElement());
          }
          for (MemberNode memberNode : memberNodesList) {
            newRoot.add(memberNode);
          }
        } else {
          otherObjects.add(nextElement);
        }
      }
      replaceChildren(root, otherObjects);
      sortNode(newRoot, myComparator);
      if (newRoot.children().hasMoreElements()) root.add(newRoot);
    } else {
      Enumeration<ParentNode> children = getRootNodeChildren();
      while (children.hasMoreElements()) {
        ParentNode allClassesNode = children.nextElement();
        Enumeration<MemberNode> memberNodes = allClassesNode.children();
        ArrayList<MemberNode> arrayList = new ArrayList<MemberNode>();
        while (memberNodes.hasMoreElements()) {
          arrayList.add(memberNodes.nextElement());
        }
        Collections.sort(arrayList, myComparator);
        for (MemberNode memberNode : arrayList) {
          myNodeToParentMap.get(memberNode).add(memberNode);
        }
      }
      replaceChildren(root, myContainerNodes);
    }
    myTreeModel.nodeStructureChanged(root);

    defaultExpandTree();

    restoreSelection(selection);
  }
  private void restoreSelection(Pair<ElementNode, List<ElementNode>> pair) {
    List<ElementNode> selectedNodes = pair.second;

    DefaultMutableTreeNode root = getRootNode();

    ArrayList<TreePath> toSelect = new ArrayList<TreePath>();
    for (ElementNode node : selectedNodes) {
      DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
      if (root.isNodeDescendant(treeNode)) {
        toSelect.add(new TreePath(treeNode.getPath()));
      }
    }

    if (!toSelect.isEmpty()) {
      myTree.setSelectionPaths(toSelect.toArray(new TreePath[toSelect.size()]));
    }

    ElementNode leadNode = pair.first;
    if (leadNode != null) {
      myTree.setLeadSelectionPath(new TreePath(((DefaultMutableTreeNode) leadNode).getPath()));
    }
  }