package se.fnord.jamon;

import java.util.Arrays;

public class Path {
	private final Node[] path;

	private Path(Node[] path) {
		this.path = path;
    }

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof Path))
			return false;
		final Path other = (Path) obj;
		if (path.length != other.path.length)
			return false;
		for (int i = 0; i < path.length; i++)
			if (!path[i].shallowEquals(other.path[i]))
				return false;
		return true;
	}

	@Override
	public int hashCode() {
		int n = 0;
		for (int i = 0; i < path.length; i++)
			n = n + 31 * path[i].hashCode();
		return n;
	}

	public Node root() {
		return path[0];
	}

	public Node leaf() {
		return path[path.length - 1];
	}

	public Path forChild(Node n) {
		if (!leaf().children().contains(n))
			throw new IllegalStateException("Provided node is not a child of the last node in the path");

		final Node[] newPath = Arrays.copyOf(path, path.length + 1);
		newPath[newPath.length - 1] = n;
		return new Path(newPath);
	}

	public Path forParent() {
		final Node[] newPath = Arrays.copyOf(path, path.length - 1);
		return new Path(newPath);
	}

	private static void checkPath(Node[] path) {
		if (path.length == 0)
			throw new IllegalStateException("Broken path");

		Node parent = path[0];
		for (int i = 1; i < path.length; i++) {
			Node current = path[i];
			if (!parent.children().contains(current))
				throw new IllegalStateException("Broken path");
			parent = current;
		}
	}

    public static Path path(Node ...nodes) {
    	nodes = nodes.clone();
    	checkPath(nodes);
    	return new Path(nodes);
    }

    @Override
    public String toString() {
    	StringBuilder sb = new StringBuilder();
    	sb.append(path[0].value());
    	for (int i = 1; i < path.length; i++) {
    		sb.append("/").append(path[i].value());
    	}
    	return sb.toString();
    }
}

@@ -47,26 +47,120 @@
 ys;%0A
-%0Apublic class Path
+import java.util.Iterator;%0Aimport java.util.NoSuchElementException;%0A%0Apublic class Path implements Iterable%3CNode%3E
  %7B%0A%09
@@ -1976,11 +1976,508 @@
 );%0A    %7D
+%0A%0A%09@Override%0A    public Iterator%3CNode%3E iterator() %7B%0A%09    return new Iterator%3CNode%3E() %7B%0A%09    %09private int i = 0;%0A%09%09%09@Override%0A            public boolean hasNext() %7B%0A%09            return i %3C path.length;%0A            %7D%0A%0A%09%09%09@Override%0A            public Node next() %7B%0A%09%09%09%09if (i == path.length)%0A%09%09%09%09%09throw new NoSuchElementException();%0A%09            return path%5Bi++%5D;%0A            %7D%0A%0A%09%09%09@Override%0A            public void remove() %7B%0A%09%09%09%09throw new UnsupportedOperationException();%0A            %7D%0A%09    %7D;%0A    %7D
 %0A%7D%0A

Make Path implement Iterable<Node>