// Path: src/main/java/com/tinkerpop/pipes/IdentityPipe.java
// public class IdentityPipe<S> extends AbstractPipe<S, S> {  // does not implement TransformPipe
// 
//     protected S processNextStart() {
//         return this.starts.next();
//     }
// }
// 
// Path: src/main/java/com/tinkerpop/pipes/Pipe.java
// public interface Pipe<S, E> extends Iterator<E>, Iterable<E> {
// 
//     public static final String NO_PATH_MESSAGE = "Path calculations are not enabled";
// 
//     /**
//      * Set an iterator of S objects to the head (start) of the pipe.
//      *
//      * @param starts the iterator of incoming objects
//      */
//     public void setStarts(Iterator<S> starts);
// 
//     /**
//      * Set an iterable of S objects to the head (start) of the pipe.
//      *
//      * @param starts the iterable of incoming objects
//      */
//     public void setStarts(Iterable<S> starts);
// 
//     /**
//      * Returns the transformation path to arrive at the current object of the pipe.
//      *
//      * @return a List of all of the objects traversed for the current iterator position of the pipe.
//      */
//     public List getCurrentPath();
// 
//     /**
//      * Calculating paths can be an expensive operation for some pipes.
//      * This method is used to activate or deactivate the calculation of paths.
//      * The default state of a newly constructed pipe should have its path calculations disabled.
//      * An implementation of this method should be recursive whereby the starts (if a Pipe) should have this method called on it.
//      *
//      * @param enable enable path calculations
//      */
//     public void enablePath(boolean enable);
// 
//     /**
//      * A pipe may maintain state. Reset is used to remove state.
//      * The general use case for reset() is to reuse a pipe in another computation without having to create a new Pipe object.
//      * An implementation of this method should be recursive whereby the starts (if a Pipe) should have this method called on it.
//      */
//     public void reset();
// }
// 
// Path: src/main/java/com/tinkerpop/pipes/PipeFunction.java
// public interface PipeFunction<A, B> {
// 
//     /**
//      * A function that takes an argument of type A and returns a result of type B.
//      *
//      * @param argument An argument of type A
//      * @return the result of computing the function on the argument
//      */
//     public B compute(A argument);
// }


import com.tinkerpop.pipes.AbstractPipe;
import com.tinkerpop.pipes.IdentityPipe;
import com.tinkerpop.pipes.Pipe;
import com.tinkerpop.pipes.PipeFunction;
import com.tinkerpop.pipes.branch.LoopPipe;
import com.tinkerpop.pipes.util.Pipeline;
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.List;
            } else if (counter == 1) {
                assertEquals(path.get(0), "josh");
                assertEquals(path.get(1), "4");
            } else {
                assertEquals(path.get(0), "pup");
                assertEquals(path.get(1), "3");
            }
            counter++;
        }
        assertEquals(counter, 3);
    }

    public void testPathSelfLoop() {

        Pipe a = new TransformFunctionPipe(new PipeFunction<String, String>() {
            public String compute(String s) {
                return s;
            }
        });
        Pipe b = new IdentityPipe();
        Pipe c = new PathPipe();

        Pipe<String, List<String>> p = new Pipeline<String, List<String>>(a, b, c);
        p.setStarts(Arrays.asList("a", "b", "c"));
        while (p.hasNext()) {
            assertEquals(p.next().size(), 2);
        }
    }

    public void testPathSelfLoopLoop() {
// Path: src/main/java/com/tinkerpop/pipes/IdentityPipe.java
// public class IdentityPipe<S> extends AbstractPipe<S, S> {  // does not implement TransformPipe
// 
//     protected S processNextStart() {
//         return this.starts.next();
//     }
// }
// 
// Path: src/main/java/com/tinkerpop/pipes/Pipe.java
// public interface Pipe<S, E> extends Iterator<E>, Iterable<E> {
// 
//     public static final String NO_PATH_MESSAGE = "Path calculations are not enabled";
// 
//     /**
//      * Set an iterator of S objects to the head (start) of the pipe.
//      *
//      * @param starts the iterator of incoming objects
//      */
//     public void setStarts(Iterator<S> starts);
// 
//     /**
//      * Set an iterable of S objects to the head (start) of the pipe.
//      *
//      * @param starts the iterable of incoming objects
//      */
//     public void setStarts(Iterable<S> starts);
// 
//     /**
//      * Returns the transformation path to arrive at the current object of the pipe.
//      *
//      * @return a List of all of the objects traversed for the current iterator position of the pipe.
//      */
//     public List getCurrentPath();
// 
//     /**
//      * Calculating paths can be an expensive operation for some pipes.
//      * This method is used to activate or deactivate the calculation of paths.
//      * The default state of a newly constructed pipe should have its path calculations disabled.
//      * An implementation of this method should be recursive whereby the starts (if a Pipe) should have this method called on it.
//      *
//      * @param enable enable path calculations
//      */
//     public void enablePath(boolean enable);
// 
//     /**
//      * A pipe may maintain state. Reset is used to remove state.
//      * The general use case for reset() is to reuse a pipe in another computation without having to create a new Pipe object.
//      * An implementation of this method should be recursive whereby the starts (if a Pipe) should have this method called on it.
//      */
//     public void reset();
// }
// 
// Path: src/main/java/com/tinkerpop/pipes/PipeFunction.java
// public interface PipeFunction<A, B> {
// 
//     /**
//      * A function that takes an argument of type A and returns a result of type B.
//      *
//      * @param argument An argument of type A
//      * @return the result of computing the function on the argument
//      */
//     public B compute(A argument);
// }


// Path: src/test/java/com/tinkerpop/pipes/transform/PathPipeTest.java
import com.tinkerpop.pipes.AbstractPipe;
import com.tinkerpop.pipes.IdentityPipe;
import com.tinkerpop.pipes.Pipe;
import com.tinkerpop.pipes.PipeFunction;
import com.tinkerpop.pipes.branch.LoopPipe;
import com.tinkerpop.pipes.util.Pipeline;
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.List;

            } else if (counter == 1) {
                assertEquals(path.get(0), "josh");
                assertEquals(path.get(1), "4");
            } else {
                assertEquals(path.get(0), "pup");
                assertEquals(path.get(1), "3");
            }
            counter++;
        }
        assertEquals(counter, 3);
    }

    public void testPathSelfLoop() {

        Pipe a = new TransformFunctionPipe(new PipeFunction<String, String>() {
            public String compute(String s) {
                return s;
            }
        });
        Pipe b = new IdentityPipe();
        Pipe c = new PathPipe();

        Pipe<String, List<String>> p = new Pipeline<String, List<String>>(a, b, c);
        p.setStarts(Arrays.asList("a", "b", "c"));
        while (p.hasNext()) {
            assertEquals(p.next().size(), 2);
        }
    }

    public void testPathSelfLoopLoop() {
        Pipe a = new TransformFunctionPipe(new PipeFunction<String, String>() {