@@ -0,0 +1,1159 @@
+package jetbrains.jetpad.model.composite;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.Collections;%0Aimport java.util.List;%0A%0Apublic class TreePath%3CCompositeT extends Composite%3CCompositeT%3E%3E %7B%0A  private List%3CInteger%3E myPath = new ArrayList%3CInteger%3E();%0A%0A  public TreePath(CompositeT composite) %7B%0A    CompositeT current = composite;%0A    while (current != null) %7B%0A      CompositeT parent = current.parent().get();%0A      if (parent != null) %7B%0A        int index = parent.children().indexOf(current);%0A        if (index == -1) throw new IllegalStateException();%0A        myPath.add(index);%0A      %7D%0A      current = parent;%0A    %7D%0A%0A    Collections.reverse(myPath);%0A  %7D%0A%0A  public CompositeT get(CompositeT root) %7B%0A    CompositeT current = root;%0A    for (Integer i : myPath) %7B%0A      current = current.children().get(i);%0A    %7D%0A    return current;%0A  %7D%0A%0A  @Override%0A  public boolean equals(Object o) %7B%0A    if (!(o instanceof TreePath)) return false;%0A    TreePath path = (TreePath) o;%0A    return myPath.equals(path.myPath);%0A  %7D%0A%0A  @Override%0A  public int hashCode() %7B%0A    return myPath.hashCode();%0A  %7D%0A%0A  @Override%0A  public String toString() %7B%0A    return myPath.toString();%0A  %7D%0A%7D

generalize treePath