You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2015/03/17 19:42:43 UTC

[6/6] incubator-tinkerpop git commit: Add PartitionStrategy and related tests as a TraversalStrategy.

Add PartitionStrategy and related tests as a TraversalStrategy.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/85dfcc79
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/85dfcc79
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/85dfcc79

Branch: refs/heads/master
Commit: 85dfcc79acf51f00a3fdd4e742c6b6b7d25b58c3
Parents: f896de1
Author: Stephen Mallette <sp...@apache.org>
Authored: Tue Mar 17 14:42:11 2015 -0400
Committer: Stephen Mallette <sp...@apache.org>
Committed: Tue Mar 17 14:42:11 2015 -0400

----------------------------------------------------------------------
 .../process/graph/traversal/step/Mutating.java  |   9 +
 .../graph/traversal/step/map/AddEdgeStep.java   |  33 ++-
 .../traversal/step/map/AddVertexStartStep.java  |   3 +
 .../graph/traversal/step/map/AddVertexStep.java |   4 +
 .../strategy/decoration/PartitionStrategy.java  | 100 +++++++++
 .../decoration/PartitionStrategyTest.java       | 130 +++++++++++
 .../gremlin/process/ProcessComputerSuite.java   |   7 +-
 .../gremlin/process/ProcessStandardSuite.java   |   6 +-
 .../PartitionStrategyProcessTest.java           | 218 +++++++++++++++++++
 .../decoration/ReadOnlyStrategyProcessTest.java | 116 ++++++++++
 .../decoration/ReadOnlyStrategyTest.java        | 116 ----------
 11 files changed, 613 insertions(+), 129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/Mutating.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/Mutating.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/Mutating.java
new file mode 100644
index 0000000..2a2ac16
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/Mutating.java
@@ -0,0 +1,9 @@
+package org.apache.tinkerpop.gremlin.process.graph.traversal.step;
+
+/**
+ * A marker interface for steps that modify the graph.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public interface Mutating {
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddEdgeStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddEdgeStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddEdgeStep.java
index b413c0a..6c5dc6d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddEdgeStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddEdgeStep.java
@@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.process.graph.traversal.step.map;
 
 import org.apache.tinkerpop.gremlin.process.Traversal;
 import org.apache.tinkerpop.gremlin.process.Traverser;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.Mutating;
 import org.apache.tinkerpop.gremlin.process.traverser.TraverserRequirement;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
@@ -34,32 +35,48 @@ import java.util.Set;
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
-public final class AddEdgeStep extends FlatMapStep<Vertex, Edge> {
+public final class AddEdgeStep extends FlatMapStep<Vertex, Edge> implements Mutating {
 
     private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT);
 
-    private final String label;
+    private final String edgeLabel;
     private final Object[] keyValues;
     private final List<Vertex> vertices;
     private final Direction direction;
 
-    public AddEdgeStep(final Traversal.Admin traversal, final Direction direction, final String label, final Vertex vertex, final Object... keyValues) {
-        this(traversal, direction, label, IteratorUtils.of(vertex), keyValues);
+    public AddEdgeStep(final Traversal.Admin traversal, final Direction direction, final String edgeLabel, final Vertex vertex, final Object... keyValues) {
+        this(traversal, direction, edgeLabel, IteratorUtils.of(vertex), keyValues);
     }
 
-    public AddEdgeStep(final Traversal.Admin traversal, final Direction direction, final String label, final Iterator<Vertex> vertices, final Object... keyValues) {
+    public AddEdgeStep(final Traversal.Admin traversal, final Direction direction, final String edgeLabel, final Iterator<Vertex> vertices, final Object... keyValues) {
         super(traversal);
         this.direction = direction;
-        this.label = label;
+        this.edgeLabel = edgeLabel;
         this.vertices = IteratorUtils.list(vertices);
         this.keyValues = keyValues;
     }
 
+    public Direction getDirection() {
+        return direction;
+    }
+
+    public String getEdgeLabel() {
+        return edgeLabel;
+    }
+
+    public Object[] getKeyValues() {
+        return keyValues;
+    }
+
+    public List<Vertex> getVertices() {
+        return vertices;
+    }
+
     @Override
     protected Iterator<Edge> flatMap(final Traverser.Admin<Vertex> traverser) {
         return IteratorUtils.map(this.vertices.iterator(), this.direction.equals(Direction.OUT) ?
-                vertex -> traverser.get().addEdge(this.label, vertex, this.keyValues) :
-                vertex -> vertex.addEdge(this.label, traverser.get(), this.keyValues));
+                vertex -> traverser.get().addEdge(this.edgeLabel, vertex, this.keyValues) :
+                vertex -> vertex.addEdge(this.edgeLabel, traverser.get(), this.keyValues));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStartStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStartStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStartStep.java
index debd910..3b54d3a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStartStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStartStep.java
@@ -37,6 +37,9 @@ public final class AddVertexStartStep extends AbstractStep<Vertex, Vertex> {
         this.keyValues = keyValues;
     }
 
+    public Object[] getKeyValues() {
+        return keyValues;
+    }
 
     @Override
     protected Traverser<Vertex> processNextStart() {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStep.java
index 5b5eadd..ef5cb57 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/graph/traversal/step/map/AddVertexStep.java
@@ -37,6 +37,10 @@ public final class AddVertexStep<S> extends MapStep<S, Vertex> {
         this.graph = this.getTraversal().getGraph().get();
     }
 
+    public Object[] getKeyValues() {
+        return keyValues;
+    }
+
     @Override
     protected Vertex map(final Traverser.Admin<S> traverser) {
         return this.graph.addVertex(this.keyValues);

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
new file mode 100644
index 0000000..00cb44e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
@@ -0,0 +1,100 @@
+package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
+
+import org.apache.tinkerpop.gremlin.process.Step;
+import org.apache.tinkerpop.gremlin.process.Traversal;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.filter.HasStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.map.AddVertexStartStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.map.AddVertexStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.map.EdgeOtherVertexStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.map.EdgeVertexStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.map.VertexStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.map.AddEdgeStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.sideEffect.GraphStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.graph.util.HasContainer;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.structure.Contains;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class PartitionStrategy extends AbstractTraversalStrategy {
+    private String writePartition;
+    private final String partitionKey;
+    private final Set<String> readPartitions = new HashSet<>();
+
+    public PartitionStrategy(final String partitionKey, final String partition) {
+        this.writePartition = partition;
+        this.addReadPartition(partition);
+        this.partitionKey = partitionKey;
+    }
+
+    public String getWritePartition() {
+        return this.writePartition;
+    }
+
+    public void setWritePartition(final String writePartition) {
+        this.writePartition = writePartition;
+        this.readPartitions.add(writePartition);
+    }
+
+    public String getPartitionKey() {
+        return this.partitionKey;
+    }
+
+    public Set<String> getReadPartitions() {
+        return Collections.unmodifiableSet(this.readPartitions);
+    }
+
+    public void removeReadPartition(final String readPartition) {
+        this.readPartitions.remove(readPartition);
+    }
+
+    public void addReadPartition(final String readPartition) {
+        this.readPartitions.add(readPartition);
+    }
+
+    public void clearReadPartitions() {
+        this.readPartitions.clear();
+    }
+
+    @Override
+    public void apply(final Traversal.Admin<?, ?> traversal) {
+        // todo: what about "add vertex"
+        final List<Step> stepsToInsertHasAfter = new ArrayList<>();
+        stepsToInsertHasAfter.addAll(TraversalHelper.getStepsOfAssignableClass(GraphStep.class, traversal));
+        stepsToInsertHasAfter.addAll(TraversalHelper.getStepsOfAssignableClass(VertexStep.class, traversal));
+        stepsToInsertHasAfter.addAll(TraversalHelper.getStepsOfAssignableClass(EdgeOtherVertexStep.class, traversal));
+        stepsToInsertHasAfter.addAll(TraversalHelper.getStepsOfAssignableClass(AddEdgeStep.class, traversal));
+        stepsToInsertHasAfter.addAll(TraversalHelper.getStepsOfAssignableClass(EdgeVertexStep.class, traversal));
+        stepsToInsertHasAfter.addAll(TraversalHelper.getStepsOfAssignableClass(AddVertexStep.class, traversal));
+
+        // all steps that return a vertex need to have has(paritionKey,within,partitionValues) injected after it
+        stepsToInsertHasAfter.forEach(s -> TraversalHelper.insertAfterStep(
+                new HasStep(traversal, new HasContainer(partitionKey, Contains.within, new ArrayList<>(readPartitions))), s, traversal));
+
+        // all write edge steps need to have partition keys tossed into the property key/value list after mutating steps
+        TraversalHelper.getStepsOfAssignableClass(AddEdgeStep.class, traversal).forEach(s -> {
+            final Object[] keyValues = Stream.concat(Stream.of(s.getKeyValues()), Stream.of(partitionKey, writePartition)).toArray();
+            TraversalHelper.replaceStep(s, new AddEdgeStep(traversal, s.getDirection(), s.getEdgeLabel(), s.getVertices().iterator(), keyValues), traversal);
+        });
+
+        // all write vertex steps need to have partition keys tossed into the property key/value list after mutating steps
+        TraversalHelper.getStepsOfAssignableClass(AddVertexStep.class, traversal).forEach(s -> {
+            final Object[] keyValues = Stream.concat(Stream.of(s.getKeyValues()), Stream.of(partitionKey, writePartition)).toArray();
+            TraversalHelper.replaceStep(s, new AddVertexStep(traversal, keyValues), traversal);
+        });
+
+        TraversalHelper.getStepsOfAssignableClass(AddVertexStartStep.class, traversal).forEach(s -> {
+            final Object[] keyValues = Stream.concat(Stream.of(s.getKeyValues()), Stream.of(partitionKey, writePartition)).toArray();
+            TraversalHelper.replaceStep(s, new AddVertexStartStep(traversal, keyValues), traversal);
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategyTest.java
new file mode 100644
index 0000000..e06dbdd
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategyTest.java
@@ -0,0 +1,130 @@
+package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
+
+import org.apache.tinkerpop.gremlin.process.Traversal;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.DefaultGraphTraversal;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.__;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.filter.HasStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.map.AddEdgeStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.map.AddVertexStep;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.step.sideEffect.GraphStep;
+import org.apache.tinkerpop.gremlin.process.graph.util.HasContainer;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.structure.Contains;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
+import org.javatuples.Pair;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class PartitionStrategyTest {
+    private static Traversal traversalWithAddV;
+    static {
+        final Graph mockedGraph = mock(Graph.class);
+        final DefaultGraphTraversal t = new DefaultGraphTraversal<>(mockedGraph);
+        t.asAdmin().addStep(new GraphStep<>(t.asAdmin(), Vertex.class));
+        traversalWithAddV = t.addV();
+    }
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"bothV()", __.bothV(), 1, false},
+                {"inV()", __.inV(), 1, false},
+                {"outV()", __.outV(), 1, false},
+                {"in()", __.in(), 1, false},
+                {"in(args)", __.in("test"), 1, false},
+                {"both()", __.both(), 1, false},
+                {"both(args)", __.both("test"), 1, false},
+                {"out()", __.out(), 1, false},
+                {"out(args)", __.out("test"), 1, false},
+                {"out().inE().otherV", __.out().inE().otherV(), 3, false},
+                {"addV()", traversalWithAddV, 2, true},
+                {"addInE()", __.addInE("test", "x"), 1, true},
+                {"addOutE()", __.addOutE("test", "x"), 1, true},
+                {"addInE()", __.addInE("test", "x", "other", "args"), 1, true},
+                {"addOutE()", __.addOutE("test", "x", "other", "args"), 1, true},
+                {"addBothE(OUT)", __.addE(Direction.OUT, "test", "x"), 1, true},
+                {"addBothE(IN)", __.addE(Direction.IN, "test", "x"), 1, true},
+                {"in().out()", __.in().out(), 2, false},
+                {"out().out().out()", __.out().out().out(), 3, false},
+                {"in().out().in()", __.in().out().in(), 3, false},
+                {"inE().outV().inE().outV()", __.inE().outV().inE().outV(), 4, false}});
+    }
+
+    @Parameterized.Parameter(value = 0)
+    public String name;
+
+    @Parameterized.Parameter(value = 1)
+    public Traversal traversal;
+
+    @Parameterized.Parameter(value = 2)
+    public int expectedInsertedSteps;
+
+    @Parameterized.Parameter(value = 3)
+    public boolean hasMutatingStep;
+
+    @Test
+    public void shouldIncludeAdditionalHasStepsAndAppendPartitionOnMutatingSteps() {
+        final PartitionStrategy strategy = new PartitionStrategy("p", "a");
+
+        if (hasMutatingStep) {
+            if (TraversalHelper.hasStepOfAssignableClass(AddEdgeStep.class, traversal.asAdmin())) {
+                final Direction d = TraversalHelper.getStepsOfClass(AddEdgeStep.class, traversal.asAdmin()).get(0).getDirection();
+                strategy.apply(traversal.asAdmin());
+
+                final List<AddEdgeStep> addEdgeSteps = TraversalHelper.getStepsOfAssignableClass(AddEdgeStep.class, traversal.asAdmin());
+                assertEquals(1, addEdgeSteps.size());
+
+                addEdgeSteps.forEach(s -> {
+                    final Object[] keyValues = s.getKeyValues();
+                    final List<Pair<String, Object>> pairs = ElementHelper.asPairs(keyValues);
+                    assertEquals("test", s.getEdgeLabel());
+                    assertEquals(d, s.getDirection());
+                    assertTrue(pairs.stream().anyMatch(p -> p.getValue0().equals("p") && p.getValue1().equals("a")));
+                });
+            } else if (TraversalHelper.hasStepOfAssignableClass(AddVertexStep.class, traversal.asAdmin())) {
+                strategy.apply(traversal.asAdmin());
+
+                final List<AddVertexStep> addVertexSteps = TraversalHelper.getStepsOfAssignableClass(AddVertexStep.class, traversal.asAdmin());
+                assertEquals(1, addVertexSteps.size());
+
+                addVertexSteps.forEach(s -> {
+                    final Object[] keyValues = s.getKeyValues();
+                    final List<Pair<String, Object>> pairs = ElementHelper.asPairs(keyValues);
+                    assertTrue(pairs.stream().anyMatch(p -> p.getValue0().equals("p") && p.getValue1().equals("a")));
+                });
+            } else
+                fail("This test should not be marked as having a mutating step or there is something else amiss.");
+        } else {
+            strategy.apply(traversal.asAdmin());
+        }
+
+        final List<HasStep> steps = TraversalHelper.getStepsOfClass(HasStep.class, traversal.asAdmin());
+        assertEquals(expectedInsertedSteps, steps.size());
+
+        final List<String> keySet = new ArrayList<>(strategy.getReadPartitions());
+        steps.forEach(s -> {
+            assertEquals(1, s.getHasContainers().size());
+            final HasContainer hasContainer = (HasContainer) s.getHasContainers().get(0);
+            assertEquals("p", hasContainer.key);
+            assertEquals(keySet, hasContainer.value);
+            assertEquals(Contains.within, hasContainer.predicate);
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
index 74c4275..4257c7c 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessComputerSuite.java
@@ -67,8 +67,8 @@ import org.apache.tinkerpop.gremlin.process.graph.traversal.step.sideEffect.Side
 import org.apache.tinkerpop.gremlin.process.graph.traversal.step.sideEffect.StoreTest;
 import org.apache.tinkerpop.gremlin.process.graph.traversal.step.sideEffect.TreeTest;
 import org.apache.tinkerpop.gremlin.process.graph.traversal.strategy.TraversalVerificationStrategyTest;
-import org.apache.tinkerpop.gremlin.process.traversal.engine.StandardTraversalEngine;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ReadOnlyStrategyTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ReadOnlyStrategyProcessTest;
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.RunnerBuilder;
 
@@ -177,7 +177,8 @@ public class ProcessComputerSuite extends AbstractGremlinSuite {
             TraversalVerificationStrategyTest.ComputerTraversals.class,
 
             // decorations
-            ReadOnlyStrategyTest.class
+            ReadOnlyStrategyProcessTest.class,
+            PartitionStrategyProcessTest.class
     };
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
index 0a10ace..5cd74b1 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
@@ -72,7 +72,8 @@ import org.apache.tinkerpop.gremlin.process.graph.traversal.step.sideEffect.Tree
 import org.apache.tinkerpop.gremlin.process.graph.traversal.step.util.TraversalSideEffectsTest;
 import org.apache.tinkerpop.gremlin.process.graph.traversal.strategy.TraversalVerificationStrategyTest;
 import org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ReadOnlyStrategyTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ReadOnlyStrategyProcessTest;
 import org.apache.tinkerpop.gremlin.process.util.PathTest;
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.RunnerBuilder;
@@ -186,7 +187,8 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
             // PageRankVertexProgramTest.class
 
             // decorations
-            ReadOnlyStrategyTest.class
+            ReadOnlyStrategyProcessTest.class,
+            PartitionStrategyProcessTest.class
     };
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategyProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategyProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategyProcessTest.java
new file mode 100644
index 0000000..c707f30
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategyProcessTest.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
+
+import org.apache.tinkerpop.gremlin.FeatureRequirementSet;
+import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.TraversalEngine;
+import org.apache.tinkerpop.gremlin.process.UseEngine;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@UseEngine(TraversalEngine.Type.STANDARD)
+@UseEngine(TraversalEngine.Type.COMPUTER)
+public class PartitionStrategyProcessTest extends AbstractGremlinProcessTest {
+    private static final String partition = "gremlin.partitionGraphStrategy.partition";
+    private final PartitionStrategy partitionStrategy = new PartitionStrategy(partition, "A");
+
+    @Test
+    @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
+    public void shouldAppendPartitionToVertex() {
+        final Vertex v = create().addV("any", "thing").next();
+
+        assertNotNull(v);
+        assertEquals("thing", v.property("any").value());
+        assertEquals("A", v.property(partition).value());
+    }
+
+    @Test
+    @FeatureRequirementSet(FeatureRequirementSet.Package.SIMPLE)
+    public void shouldAppendPartitionToEdge() {
+        final GraphTraversalSource source = create();
+        final Vertex v1 = source.addV("any", "thing").next();
+        final Vertex v2 = source.addV("some", "thing").next();
+        final Edge e = source.V(v1.id()).addInE("connectsTo", v2, "every", "thing").next();
+
+        assertNotNull(v1);
+        assertEquals("thing", v1.property("any").value());
+        assertEquals("A", v2.property(partition).value());
+
+        assertNotNull(v2);
+        assertEquals("thing", v2.property("some").value());
+        assertEquals("A", v2.property(partition).value());
+
+        assertNotNull(e);
+        assertEquals("thing", e.property("every").value());
+        assertEquals("connectsTo", e.label());
+        assertEquals("A", e.property(partition).value());
+    }
+
+    @Test
+    @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
+    public void shouldWriteVerticesToMultiplePartitions() {
+        final GraphTraversalSource source = create();
+        final Vertex vA = source.addV("any", "a").next();
+        partitionStrategy.setWritePartition("B");
+        final Vertex vB = source.addV("any", "b").next();
+
+        assertNotNull(vA);
+        assertEquals("a", vA.property("any").value());
+        assertEquals("A", vA.property(partition).value());
+
+        assertNotNull(vB);
+        assertEquals("b", vB.property("any").value());
+        assertEquals("B", vB.property(partition).value());
+
+        partitionStrategy.removeReadPartition("B");
+        source.V().forEachRemaining(v -> assertEquals("a", v.property("any").value()));
+
+        partitionStrategy.removeReadPartition("A");
+        partitionStrategy.addReadPartition("B");
+
+        source.V().forEachRemaining(v -> assertEquals("b", v.property("any").value()));
+
+        partitionStrategy.addReadPartition("A");
+        assertEquals(new Long(2), source.V().count().next());
+    }
+
+    @Test
+    @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
+    public void shouldThrowExceptionOnVInDifferentPartition() {
+        final GraphTraversalSource source = create();
+        final Vertex vA = source.addV("any", "a").next();
+        assertEquals(vA.id(), source.V(vA.id()).id().next());
+
+        partitionStrategy.clearReadPartitions();
+
+        try {
+            g.V(vA.id());
+        } catch (Exception ex) {
+            final Exception expected = Graph.Exceptions.elementNotFound(Vertex.class, vA.id());
+            assertEquals(expected.getClass(), ex.getClass());
+            assertEquals(expected.getMessage(), ex.getMessage());
+        }
+    }
+
+    @Test
+    @FeatureRequirementSet(FeatureRequirementSet.Package.SIMPLE)
+    public void shouldThrowExceptionOnEInDifferentPartition() {
+        final GraphTraversalSource source = create();
+        final Vertex vA = source.addV("any", "a").next();
+        final Edge e = source.V(vA.id()).addOutE("knows", vA).next();
+        assertEquals(e.id(), g.E(e.id()).id().next());
+
+        partitionStrategy.clearReadPartitions();
+
+        try {
+            g.E(e.id());
+        } catch (Exception ex) {
+            final Exception expected = Graph.Exceptions.elementNotFound(Edge.class, e.id());
+            assertEquals(expected.getClass(), ex.getClass());
+            assertEquals(expected.getMessage(), ex.getMessage());
+        }
+    }
+
+    @Test
+    @FeatureRequirementSet(FeatureRequirementSet.Package.SIMPLE)
+    public void shouldWriteToMultiplePartitions() {
+        final GraphTraversalSource source = create();
+        final Vertex vA = source.addV("any", "a").next();
+        final Vertex vAA = source.addV("any", "aa").next();
+        final Edge eAtoAA = source.V(vA.id()).addOutE("a->a", vAA).next();
+
+        partitionStrategy.setWritePartition("B");
+        final Vertex vB = source.addV("any", "b").next();
+        boolean x = source.V(vA.id()).hasNext();
+        source.V(vA.id()).addOutE("a->b", vB).next();
+
+        partitionStrategy.setWritePartition("C");
+        final Vertex vC = source.addV("any", "c").next();
+        final Edge eBtovC = source.V(vB.id()).addOutE("b->c", vC).next();
+        final Edge eAtovC = source.V(vA.id()).addOutE("a->c", vC).next();
+
+        partitionStrategy.clearReadPartitions();
+        assertEquals(0, IteratorUtils.count(source.V()));
+        assertEquals(0, IteratorUtils.count(source.E()));
+
+        partitionStrategy.addReadPartition("A");
+        assertEquals(new Long(2), source.V().count().next());
+        assertEquals(new Long(1), source.E().count().next());
+        assertEquals(new Long(1), source.V(vA.id()).outE().count().next());
+        assertEquals(eAtoAA.id(), source.V(vA.id()).outE().next().id());
+        assertEquals(new Long(1), source.V(vA.id()).out().count().next());
+        assertEquals(vAA.id(), source.V(vA.id()).out().next().id());
+
+        final Vertex vA1 = source.V(vA.id()).next();
+        assertEquals(new Long(1), source.V(vA1).outE().count().next());
+        assertEquals(eAtoAA.id(), source.V(vA1).outE().next().id());
+        assertEquals(new Long(1), source.V(vA1).out().count().next());
+        assertEquals(vAA.id(), source.V(vA1).out().next().id());
+
+        partitionStrategy.addReadPartition("B");
+        assertEquals(new Long(3), source.V().count().next());
+        assertEquals(new Long(2), source.E().count().next());
+
+        partitionStrategy.addReadPartition("C");
+        assertEquals(new Long(4), source.V().count().next());
+        assertEquals(new Long(4), source.E().count().next());
+
+        partitionStrategy.removeReadPartition("A");
+        partitionStrategy.removeReadPartition("B");
+
+        assertEquals(1, IteratorUtils.count(source.V()));
+        // two edges are in the "C" partition, but one each of their incident vertices are not
+        assertEquals(2, IteratorUtils.count(source.E()));
+
+        // two edges are in the "C" partition, but one each of their incident vertices are not
+        assertEquals(new Long(2), source.V(vC.id()).inE().count().next());
+        assertEquals(new Long(0), source.V(vC.id()).in().count().next());
+
+        partitionStrategy.addReadPartition("B");
+
+        // excluded vertices; vA is not in {B,C}
+        assertEquals(new Long(2), source.V(vC.id()).inE().count().next());
+        assertEquals(new Long(1), source.V(vC.id()).in().count().next());
+        assertEquals(vC.id(), source.E(eBtovC.id()).inV().id().next());
+        assertEquals(vB.id(), source.E(eBtovC.id()).outV().id().next());
+        assertEquals(vC.id(), source.E(eAtovC.id()).inV().id().next());
+        assertFalse(source.E(eAtovC.id()).outV().hasNext());
+    }
+
+    private GraphTraversalSource create() {
+        resetPartitionStrategy();
+        return graphProvider.traversal(graph, partitionStrategy);
+    }
+
+    private void resetPartitionStrategy() {
+        partitionStrategy.clearReadPartitions();
+        partitionStrategy.setWritePartition("A");
+        partitionStrategy.addReadPartition("A");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ReadOnlyStrategyProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ReadOnlyStrategyProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ReadOnlyStrategyProcessTest.java
new file mode 100644
index 0000000..b031db7
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ReadOnlyStrategyProcessTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
+
+import org.apache.tinkerpop.gremlin.FeatureRequirement;
+import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.Traversal;
+import org.apache.tinkerpop.gremlin.process.TraversalEngine;
+import org.apache.tinkerpop.gremlin.process.UseEngine;
+import org.apache.tinkerpop.gremlin.process.graph.traversal.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@UseEngine(TraversalEngine.Type.STANDARD)
+@UseEngine(TraversalEngine.Type.COMPUTER)
+public class ReadOnlyStrategyProcessTest extends AbstractGremlinProcessTest {
+    @Test
+    public void shouldTraverseV() {
+        assertTraversal(create().V(), false);
+    }
+
+    @Test
+    public void shouldTraverseV_out() {
+        assertTraversal(create().V().out(), false);
+    }
+
+    @Test
+    public void shouldTraverseV_in() {
+        assertTraversal(create().V().in(), false);
+    }
+
+    @Test
+    public void shouldTraverseV_in_in() {
+        assertTraversal(create().V().in(), false);
+    }
+
+    @Test
+    public void shouldTraverseE() {
+        assertTraversal(create().E(), false);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    public void shouldNotTraverseV_out_addInE() {
+        assertTraversal(create().V().as("a").out().addInE("test", "a"), true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    public void shouldNotTraverseV_out_addOutE() {
+        assertTraversal(create().V().as("a").out().addOutE("test", "a"), true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    public void shouldNotTraverseV_In_addInE() {
+        assertTraversal(create().V().as("a").in().addInE("test", "a"), true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    public void shouldNotTraverseV_In_addOutE() {
+        assertTraversal(create().V().as("a").in().addOutE("test", "a"), true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    public void shouldNotTraverseV_In_addEXINX() {
+        assertTraversal(create().V().as("a").in().addE(Direction.IN, "test", "a"), true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    public void shouldNotTraverseV_In_addEXOUTX() {
+        assertTraversal(create().V().as("a").in().addE(Direction.OUT, "test", "a"), true);
+    }
+
+    private GraphTraversalSource create() {
+        return graphProvider.traversal(graph, ReadOnlyStrategy.instance());
+    }
+
+    private void assertTraversal(final Traversal t, final boolean hasMutatingStep) {
+        try {
+            t.asAdmin().applyStrategies();
+            if (hasMutatingStep) fail("The strategy should have found a mutating step.");
+        } catch (IllegalStateException ise) {
+            if (!hasMutatingStep)
+                fail("The traversal should not have failed as there is no mutating step.");
+            else
+                assertEquals("The provided traversal has a mutating step and thus is not read only", ise.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85dfcc79/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ReadOnlyStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ReadOnlyStrategyTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ReadOnlyStrategyTest.java
deleted file mode 100644
index 43a38d5..0000000
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ReadOnlyStrategyTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
-
-import org.apache.tinkerpop.gremlin.FeatureRequirement;
-import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
-import org.apache.tinkerpop.gremlin.process.Traversal;
-import org.apache.tinkerpop.gremlin.process.TraversalEngine;
-import org.apache.tinkerpop.gremlin.process.UseEngine;
-import org.apache.tinkerpop.gremlin.process.graph.traversal.GraphTraversalSource;
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-@UseEngine(TraversalEngine.Type.STANDARD)
-@UseEngine(TraversalEngine.Type.COMPUTER)
-public class ReadOnlyStrategyTest extends AbstractGremlinProcessTest {
-    @Test
-    public void shouldTraverseV() {
-        assertTraversal(create().V(), false);
-    }
-
-    @Test
-    public void shouldTraverseV_out() {
-        assertTraversal(create().V().out(), false);
-    }
-
-    @Test
-    public void shouldTraverseV_in() {
-        assertTraversal(create().V().in(), false);
-    }
-
-    @Test
-    public void shouldTraverseV_in_in() {
-        assertTraversal(create().V().in(), false);
-    }
-
-    @Test
-    public void shouldTraverseE() {
-        assertTraversal(create().E(), false);
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    public void shouldNotTraverseV_out_addInE() {
-        assertTraversal(create().V().as("a").out().addInE("test", "a"), true);
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    public void shouldNotTraverseV_out_addOutE() {
-        assertTraversal(create().V().as("a").out().addOutE("test", "a"), true);
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    public void shouldNotTraverseV_In_addInE() {
-        assertTraversal(create().V().as("a").in().addInE("test", "a"), true);
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    public void shouldNotTraverseV_In_addOutE() {
-        assertTraversal(create().V().as("a").in().addOutE("test", "a"), true);
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    public void shouldNotTraverseV_In_addEXINX() {
-        assertTraversal(create().V().as("a").in().addE(Direction.IN, "test", "a"), true);
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    public void shouldNotTraverseV_In_addEXOUTX() {
-        assertTraversal(create().V().as("a").in().addE(Direction.OUT, "test", "a"), true);
-    }
-
-    private GraphTraversalSource create() {
-        return graphProvider.traversal(graph, ReadOnlyStrategy.instance());
-    }
-
-    private void assertTraversal(final Traversal t, final boolean hasMutatingStep) {
-        try {
-            t.asAdmin().applyStrategies();
-            if (hasMutatingStep) fail("The strategy should have found a mutating step.");
-        } catch (IllegalStateException ise) {
-            if (!hasMutatingStep)
-                fail("The traversal should not have failed as there is no mutating step.");
-            else
-                assertEquals("The provided traversal has a mutating step and thus is not read only", ise.getMessage());
-        }
-    }
-}