@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;
    }