// Path: src/main/java/com/tinkerpop/furnace/algorithms/vertexcentric/GraphMemory.java
// public interface GraphMemory {
// 
//     public <R> R get(final String key);
// 
//     public void setIfAbsent(String key, Object value);
// 
//     public long increment(String key, long delta);
// 
//     public long decrement(String key, long delta);
// 
//     public int getIteration();
// 
//     public long getRuntime();
// 
//     public boolean isInitialIteration();
// 
//     /*public void min(String key, double value);
// 
//     public void max(String key, double value);
// 
//     public void avg(String key, double value);
// 
//     public <V> void update(String key, Function<V, V> update, V defaultValue);*/
// 
//     // public Map<String, Object> getCurrentState();
// }
// 
// Path: src/main/java/com/tinkerpop/furnace/algorithms/vertexcentric/programs/AbstractVertexProgram.java
// public abstract class AbstractVertexProgram implements VertexProgram {
// 
//     protected final Map<String, KeyType> computeKeys = new HashMap<String, KeyType>();
// 
//     public Map<String, KeyType> getComputeKeys() {
//         return computeKeys;
//     }
// 
//     public void setup(final GraphMemory graphMemory) {
// 
//     }
// 
//     public String toString() {
//         return this.getClass().getSimpleName() + "[" + computeKeys.keySet() + "]";
//     }
// }
// 
// Path: src/main/java/com/tinkerpop/furnace/util/VertexQueryBuilder.java
// public class VertexQueryBuilder extends DefaultVertexQuery {
// 
//     public VertexQueryBuilder() {
//         super(null);
//     }
// 
//     public VertexQueryBuilder has(final String key) {
//         super.has(key);
//         return this;
//     }
// 
//     public VertexQueryBuilder hasNot(final String key) {
//         super.hasNot(key);
//         return this;
//     }
// 
//     public VertexQueryBuilder has(final String key, final Object value) {
//         super.has(key, value);
//         return this;
//     }
// 
//     public VertexQueryBuilder hasNot(final String key, final Object value) {
//         super.hasNot(key, value);
//         return this;
//     }
// 
//     @Deprecated
//     public <T extends Comparable<T>> VertexQueryBuilder has(final String key, final T value, final Query.Compare compare) {
//         return this.has(key, compare, value);
//     }
// 
//     public VertexQueryBuilder has(final String key, final Predicate compare, final Object value) {
//         super.has(key, compare, value);
//         return this;
//     }
// 
//     public <T extends Comparable<?>> VertexQueryBuilder interval(final String key, final T startValue, final T endValue) {
//         super.interval(key, startValue, endValue);
//         return this;
//     }
// 
//     public VertexQueryBuilder direction(final Direction direction) {
//         super.direction(direction);
//         return this;
//     }
// 
//     public VertexQueryBuilder labels(final String... labels) {
//         super.labels(labels);
//         return this;
//     }
// 
//     public VertexQueryBuilder limit(final int limit) {
//         super.limit(limit);
//         return this;
//     }
// 
//     public Iterable<Edge> edges() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public Iterable<Vertex> vertices() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public Object vertexIds() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public long count() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public VertexQuery build(final Vertex vertex) {
//         VertexQuery query = vertex.query();
//         for (final HasContainer hasContainer : this.hasContainers) {
//             query = query.has(hasContainer.key, hasContainer.predicate, hasContainer.value);
//         }
//         return query.limit(this.limit).labels(this.labels).direction(this.direction);
//     }
// }


import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.furnace.algorithms.vertexcentric.GraphMemory;
import com.tinkerpop.furnace.algorithms.vertexcentric.programs.AbstractVertexProgram;
import com.tinkerpop.furnace.util.VertexQueryBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
            vertex.setProperty(LIVE_PATHS, paths);
            vertex.setProperty(DEAD_PATHS, new HashMap<Object, List<Vertex>>());
        } else {

            final Map<Object, List<Object>> deadPaths = vertex.getProperty(DEAD_PATHS);
            final List<List<Object>> livePaths = new ArrayList<List<Object>>();

            for (final Vertex adjacent : this.incomingQuery.build(vertex).vertices()) {
                final List<List<Object>> paths = adjacent.getProperty(LIVE_PATHS);
                for (final List<Object> path : paths) {
                    final List<Object> appendedPath = new ArrayList<Object>();
                    appendedPath.addAll(path);
                    appendedPath.add(vertex.getId());
                    if (isSimple(appendedPath)) {
                        if (!deadPaths.containsKey(path.get(0))) {
                            deadPaths.put(path.get(0), appendedPath);
                        }
                        livePaths.add(appendedPath);
                    }
                }
            }
            vertex.setProperty(LIVE_PATHS, livePaths);
            vertex.setProperty(DEAD_PATHS, deadPaths);
        }
    }

    private boolean isSimple(final List list) {
        return new HashSet(list).size() == list.size();
    }

// Path: src/main/java/com/tinkerpop/furnace/algorithms/vertexcentric/GraphMemory.java
// public interface GraphMemory {
// 
//     public <R> R get(final String key);
// 
//     public void setIfAbsent(String key, Object value);
// 
//     public long increment(String key, long delta);
// 
//     public long decrement(String key, long delta);
// 
//     public int getIteration();
// 
//     public long getRuntime();
// 
//     public boolean isInitialIteration();
// 
//     /*public void min(String key, double value);
// 
//     public void max(String key, double value);
// 
//     public void avg(String key, double value);
// 
//     public <V> void update(String key, Function<V, V> update, V defaultValue);*/
// 
//     // public Map<String, Object> getCurrentState();
// }
// 
// Path: src/main/java/com/tinkerpop/furnace/algorithms/vertexcentric/programs/AbstractVertexProgram.java
// public abstract class AbstractVertexProgram implements VertexProgram {
// 
//     protected final Map<String, KeyType> computeKeys = new HashMap<String, KeyType>();
// 
//     public Map<String, KeyType> getComputeKeys() {
//         return computeKeys;
//     }
// 
//     public void setup(final GraphMemory graphMemory) {
// 
//     }
// 
//     public String toString() {
//         return this.getClass().getSimpleName() + "[" + computeKeys.keySet() + "]";
//     }
// }
// 
// Path: src/main/java/com/tinkerpop/furnace/util/VertexQueryBuilder.java
// public class VertexQueryBuilder extends DefaultVertexQuery {
// 
//     public VertexQueryBuilder() {
//         super(null);
//     }
// 
//     public VertexQueryBuilder has(final String key) {
//         super.has(key);
//         return this;
//     }
// 
//     public VertexQueryBuilder hasNot(final String key) {
//         super.hasNot(key);
//         return this;
//     }
// 
//     public VertexQueryBuilder has(final String key, final Object value) {
//         super.has(key, value);
//         return this;
//     }
// 
//     public VertexQueryBuilder hasNot(final String key, final Object value) {
//         super.hasNot(key, value);
//         return this;
//     }
// 
//     @Deprecated
//     public <T extends Comparable<T>> VertexQueryBuilder has(final String key, final T value, final Query.Compare compare) {
//         return this.has(key, compare, value);
//     }
// 
//     public VertexQueryBuilder has(final String key, final Predicate compare, final Object value) {
//         super.has(key, compare, value);
//         return this;
//     }
// 
//     public <T extends Comparable<?>> VertexQueryBuilder interval(final String key, final T startValue, final T endValue) {
//         super.interval(key, startValue, endValue);
//         return this;
//     }
// 
//     public VertexQueryBuilder direction(final Direction direction) {
//         super.direction(direction);
//         return this;
//     }
// 
//     public VertexQueryBuilder labels(final String... labels) {
//         super.labels(labels);
//         return this;
//     }
// 
//     public VertexQueryBuilder limit(final int limit) {
//         super.limit(limit);
//         return this;
//     }
// 
//     public Iterable<Edge> edges() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public Iterable<Vertex> vertices() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public Object vertexIds() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public long count() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public VertexQuery build(final Vertex vertex) {
//         VertexQuery query = vertex.query();
//         for (final HasContainer hasContainer : this.hasContainers) {
//             query = query.has(hasContainer.key, hasContainer.predicate, hasContainer.value);
//         }
//         return query.limit(this.limit).labels(this.labels).direction(this.direction);
//     }
// }


// Path: src/main/java/com/tinkerpop/furnace/algorithms/vertexcentric/programs/paths/ShortestPathProgram.java
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.furnace.algorithms.vertexcentric.GraphMemory;
import com.tinkerpop.furnace.algorithms.vertexcentric.programs.AbstractVertexProgram;
import com.tinkerpop.furnace.util.VertexQueryBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

            vertex.setProperty(LIVE_PATHS, paths);
            vertex.setProperty(DEAD_PATHS, new HashMap<Object, List<Vertex>>());
        } else {

            final Map<Object, List<Object>> deadPaths = vertex.getProperty(DEAD_PATHS);
            final List<List<Object>> livePaths = new ArrayList<List<Object>>();

            for (final Vertex adjacent : this.incomingQuery.build(vertex).vertices()) {
                final List<List<Object>> paths = adjacent.getProperty(LIVE_PATHS);
                for (final List<Object> path : paths) {
                    final List<Object> appendedPath = new ArrayList<Object>();
                    appendedPath.addAll(path);
                    appendedPath.add(vertex.getId());
                    if (isSimple(appendedPath)) {
                        if (!deadPaths.containsKey(path.get(0))) {
                            deadPaths.put(path.get(0), appendedPath);
                        }
                        livePaths.add(appendedPath);
                    }
                }
            }
            vertex.setProperty(LIVE_PATHS, livePaths);
            vertex.setProperty(DEAD_PATHS, deadPaths);
        }
    }

    private boolean isSimple(final List list) {
        return new HashSet(list).size() == list.size();
    }

    public boolean terminate(final GraphMemory memory) {