You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by dk...@apache.org on 2018/05/31 21:08:04 UTC

[18/23] tinkerpop git commit: TINKERPOP-1975 Introduced with() step and Configuring interface

TINKERPOP-1975 Introduced with() step and Configuring interface

Moved Parameterizing to the package containing the other step interfaces. Changed interface hierarchy with Parameterizing and Mutating now that Configuring is present. Both of those changes make this body of work a breaking change to existing APIs though it should really only affect graph providers and even then the fix is quite simple as described in the upgrade documentation.


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

Branch: refs/heads/shortest-path-wip
Commit: 12b84a1cdf056b35a9f286eb38db2369622b8a57
Parents: 94d0c3c
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu May 31 12:55:13 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 31 15:28:35 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  4 ++
 docs/src/reference/the-traversal.asciidoc       | 30 ++++++--
 docs/src/upgrade/release-3.4.x.asciidoc         | 49 +++++++++++++
 .../tinkerpop/gremlin/jsr223/CoreImports.java   |  2 +
 .../step/map/PageRankVertexProgramStep.java     | 75 ++++++++++++++++++--
 .../step/map/PeerPressureVertexProgramStep.java | 74 +++++++++++++++++--
 .../process/traversal/Parameterizing.java       | 37 ----------
 .../traversal/dsl/graph/GraphTraversal.java     | 24 ++++++-
 .../process/traversal/step/Configuring.java     | 41 +++++++++++
 .../process/traversal/step/Mutating.java        |  5 +-
 .../process/traversal/step/Parameterizing.java  | 39 ++++++++++
 .../process/traversal/step/filter/DropStep.java |  9 ++-
 .../traversal/step/map/AddEdgeStartStep.java    |  6 +-
 .../process/traversal/step/map/AddEdgeStep.java |  7 +-
 .../traversal/step/map/AddVertexStartStep.java  |  7 +-
 .../traversal/step/map/AddVertexStep.java       |  7 +-
 .../step/sideEffect/AddPropertyStep.java        |  9 +--
 .../process/traversal/step/util/Parameters.java |  2 +
 .../strategy/decoration/ElementIdStrategy.java  |  2 +-
 .../strategy/decoration/PartitionStrategy.java  |  6 +-
 .../traversal/dsl/graph/GraphTraversalTest.java |  2 +-
 .../Process/Traversal/GraphTraversal.cs         |  4 +-
 gremlin-javascript/glv/generate.groovy          |  3 +-
 .../lib/process/graph-traversal.js              |  2 +-
 gremlin-python/glv/generate.groovy              |  1 +
 .../gremlin_python/process/graph_traversal.py   |  2 +-
 .../traversal/step/map/PageRankTest.java        | 41 +++++++++++
 .../traversal/step/map/PeerPressureTest.java    | 31 +++++++-
 28 files changed, 427 insertions(+), 94 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 30fd966..41462fb 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,10 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 
 This release also includes changes from <<release-3-3-3, 3.3.3>>.
 
+* Moved `Parameterizing` interface to the `org.apache.tinkerpop.gremlin.process.traversal.step` package with other marker interfaces of its type.
+* Replaced `Parameterizing.addPropertyMutations()` with `Configuring.configure()`.
+* Changed interface hierarchy for `Parameterizing` and `Mutating` interfaces as they are tightly related.
+* Introduced the `with()` step modulator which can supply configuration options to `Configuring` steps.
 * Added `supportsUpsert()` option to `VertexFeatures` and `EdgeFeatures`.
 * `min()` and `max()` now support all types implementing `Comparable`.
 * Change the `toString()` of `Path` to be standardized as other graph elements are.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/docs/src/reference/the-traversal.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index e28090a..4ded43e 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -1705,11 +1705,15 @@ g = graph.traversal().withComputer()
 g.V().pageRank().by('pageRank').values('pageRank')
 g.V().hasLabel('person').
   pageRank().
-    by(outE('knows')).
-    by('friendRank').
+    with(PageRank.EDGES, __.outE('knows')).
+    with(PageRank.PROPERTY_NAME, 'friendRank').
   order().by('friendRank',desc).valueMap('name','friendRank')
 ----
 
+Note the use of the `with()` modulating step which provides configuration options to the algorithm. It takes
+configuration keys from the static `PageRank` inner class on `PageRankVertexProgramStep` and is automatically
+imported to the Gremlin Console.
+
 The <<explain-step,`explain()`>>-step can be used to understand how the traversal is compiled into multiple `GraphComputer` jobs.
 
 [gremlin-groovy,modern]
@@ -1717,8 +1721,8 @@ The <<explain-step,`explain()`>>-step can be used to understand how the traversa
 g = graph.traversal().withComputer()
 g.V().hasLabel('person').
   pageRank().
-    by(outE('knows')).
-    by('friendRank').
+    with(PageRank.EDGES, __.outE('knows')).
+    with(PageRank.PROPERTY_NAME, 'friendRank').
   order().by('friendRank',desc).valueMap('name','friendRank').explain()
 ----
 
@@ -1812,10 +1816,17 @@ IMPORTANT: The `peerPressure()`-step is a `VertexComputing`-step and as such, ca
 g = graph.traversal().withComputer()
 g.V().peerPressure().by('cluster').values('cluster')
 g.V().hasLabel('person').
-  peerPressure().by('cluster').
-  group().by('cluster').by('name')
+  peerPressure().
+    with(PeerPressure.PROPERTY_NAME, 'cluster').
+  group().
+    by('cluster').
+    by('name')
 ----
 
+Note the use of the `with()` modulating step which provides configuration options to the algorithm. It takes
+configuration keys from the static `PeerPressure` inner class on `PeerPressureVertexProgramStep` and is automatically
+imported to the Gremlin Console.
+
 *Additional References*
 
 link:++http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#peerPressure--++[`peerPressure()`]
@@ -2970,6 +2981,13 @@ link:++http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/grem
 link:++http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#where-org.apache.tinkerpop.gremlin.process.traversal.Traversal-++[`where(Traversal)`],
 link:++http://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`]
 
+[[with-step]]
+=== With Step
+
+The `with()`-step is not an actual step, but is instead a "step modulator" which modifies the behavior of the step
+prior to it. The `with()`-step provides additional "configuration" information to steps that implement the `Configuring`
+interface. Steps that allow for this type of modulation will explicitly state so in their documentation.
+
 [[a-note-on-predicates]]
 == A Note on Predicates
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/docs/src/upgrade/release-3.4.x.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.4.x.asciidoc b/docs/src/upgrade/release-3.4.x.asciidoc
index 3c881c3..f99a6d5 100644
--- a/docs/src/upgrade/release-3.4.x.asciidoc
+++ b/docs/src/upgrade/release-3.4.x.asciidoc
@@ -29,6 +29,42 @@ Please see the link:https://github.com/apache/tinkerpop/blob/3.4.0/CHANGELOG.asc
 
 === Upgrading for Users
 
+==== with() Step
+
+This version of TinkerPop introduces the `with()` step to Gremlin. It isn't really a step but is instead a step
+modulator. This modulator allows the step it is modifying to accept configurations that can be used to alter the
+behavior of the step itself. A good example of its usage is shown with the revised syntax of the `pageRank()` step
+which now uses `with()` to replace the old `by()` options:
+
+[groovy]
+----
+g.V().hasLabel('person').
+  pageRank().
+    with(PageRank.EDGES, __.outE('knows')).
+    with(PageRank.PROPERTY_NAME, 'friendRank').
+  order().
+    by('friendRank',desc).
+  valueMap('name','friendRank')
+----
+
+A similar change was made for `peerPressure()` step:
+
+[groovy]
+----
+g.V().hasLabel('person').
+  peerPressure().
+    with(PeerPressure.PROPERTY_NAME, 'cluster').
+  group().
+    by('cluster').
+    by('name')
+----
+
+Note that the `by()` modulators still work, but should be considered deprecated and open for removal in a future
+release where breaking changes are allowed.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1975[TINKERPOP-1975],
+link:http://tinkerpop.apache.org/docs/current/reference/#with-step[Reference Documentation]
+
 ==== Removal of Giraph Support
 
 Support for Giraph has been removed as of this version. There were a number of reasons for this decision which were
@@ -198,6 +234,19 @@ See: link:https://issues.apache.org/jira/browse/TINKERPOP-1522[TINKERPOP-1522]
 
 ==== Graph Database Providers
 
+===== Configuring Interface
+
+There were some changes to interfaces that were related to `Step`. A new `Configuring` interface was added that was
+helpful in the implementation of the `with()` step modulator. This new interface extends the `Parameterizing` interface
+(which moved to the `org.apache.tinkerpop.gremlin.process.traversal.step` package with the other step interfaces) and
+in turn is extended by the `Mutating` interface. Making this change meant that the `Mutating.addPropertyMutations()`
+method could be removed in favor of the new `Configuring.configure()` method.
+
+All of the changes above basically mean, that if the `Mutating` interface was being used in prior versions, the
+`addPropertyMutations()` method simply needs to be changed to `configure()`.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1975[TINKERPOP-1975]
+
 ===== Removed hadoop-gremlin Test Artifact
 
 The `hadoop-gremlin` module no longer generates a test jar that can be used as a test dependency in other modules.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
index 8839dcd..368b92d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/CoreImports.java
@@ -48,6 +48,7 @@ import org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankMa
 import org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankVertexProgram;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.MemoryTraversalSideEffects;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.PageRankVertexProgramStep;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.decoration.VertexProgramStrategy;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.optimization.GraphFilterStrategy;
 import org.apache.tinkerpop.gremlin.process.remote.RemoteConnection;
@@ -260,6 +261,7 @@ public final class CoreImports {
         CLASS_IMPORTS.add(PeerPressureVertexProgram.class);
         CLASS_IMPORTS.add(PageRankMapReduce.class);
         CLASS_IMPORTS.add(PageRankVertexProgram.class);
+        CLASS_IMPORTS.add(PageRankVertexProgramStep.PageRank.class);
         CLASS_IMPORTS.add(GraphFilterStrategy.class);
         CLASS_IMPORTS.add(TraversalVertexProgram.class);
         CLASS_IMPORTS.add(VertexProgramStrategy.class);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PageRankVertexProgramStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PageRankVertexProgramStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PageRankVertexProgramStep.java
index 2f67aeb..1c5b364 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PageRankVertexProgramStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PageRankVertexProgramStep.java
@@ -23,12 +23,16 @@ import org.apache.tinkerpop.gremlin.process.computer.GraphFilter;
 import org.apache.tinkerpop.gremlin.process.computer.Memory;
 import org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankVertexProgram;
 import org.apache.tinkerpop.gremlin.process.computer.traversal.lambda.HaltedTraversersCountTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Configuring;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TimesModulating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import org.apache.tinkerpop.gremlin.process.traversal.util.PureTraversal;
 import org.apache.tinkerpop.gremlin.structure.Edge;
@@ -42,9 +46,12 @@ import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-public final class PageRankVertexProgramStep extends VertexProgramStep implements TraversalParent, ByModulating, TimesModulating {
+public final class PageRankVertexProgramStep extends VertexProgramStep
+        implements TraversalParent, ByModulating, TimesModulating, Configuring {
 
+    private Parameters parameters = new Parameters();
     private PureTraversal<Vertex, Edge> edgeTraversal;
     private String pageRankProperty = PageRankVertexProgram.PAGE_RANK;
     private int times = 20;
@@ -53,23 +60,59 @@ public final class PageRankVertexProgramStep extends VertexProgramStep implement
     public PageRankVertexProgramStep(final Traversal.Admin traversal, final double alpha) {
         super(traversal);
         this.alpha = alpha;
-        this.modulateBy(__.<Vertex>outE().asAdmin());
+        this.configure(PageRank.EDGES, __.<Vertex>outE().asAdmin());
     }
 
     @Override
+    public void configure(final Object... keyValues) {
+        if (keyValues[0].equals(PageRank.EDGES)) {
+            if (!(keyValues[1] instanceof Traversal))
+                throw new IllegalArgumentException("PageRank.EDGES requires a Traversal as its argument");
+            this.edgeTraversal = new PureTraversal<>(((Traversal<Vertex,Edge>) keyValues[1]).asAdmin());
+            this.integrateChild(this.edgeTraversal.get());
+        } else if (keyValues[0].equals(PageRank.PROPERTY_NAME)) {
+            if (!(keyValues[1] instanceof String))
+                throw new IllegalArgumentException("PageRank.PROPERTY_NAME requires a String as its argument");
+            this.pageRankProperty = (String) keyValues[1];
+        } else if (keyValues[0].equals(PageRank.TIMES)) {
+            if (!(keyValues[1] instanceof Integer))
+                throw new IllegalArgumentException("PageRank.TIMES requires an Integer as its argument");
+            this.times = (int) keyValues[1];
+        }else {
+            this.parameters.set(this, keyValues);
+        }
+    }
+
+    @Override
+    public Parameters getParameters() {
+        return parameters;
+    }
+
+    /**
+     * @deprecated As of release 3.4.0, replaced by {@link #configure(Object...)}
+     */
+    @Deprecated
+    @Override
     public void modulateBy(final Traversal.Admin<?, ?> edgeTraversal) {
-        this.edgeTraversal = new PureTraversal<>((Traversal.Admin<Vertex, Edge>) edgeTraversal);
-        this.integrateChild(this.edgeTraversal.get());
+        configure(PageRank.EDGES, edgeTraversal);
     }
 
+    /**
+     * @deprecated As of release 3.4.0, replaced by {@link #configure(Object...)}
+     */
+    @Deprecated
     @Override
     public void modulateBy(final String pageRankProperty) {
-        this.pageRankProperty = pageRankProperty;
+        configure(PageRank.PROPERTY_NAME, pageRankProperty);
     }
 
+    /**
+     * @deprecated As of release 3.4.0, replaced by {@link #configure(Object...)}
+     */
+    @Deprecated
     @Override
     public void modulateTimes(int times) {
-        this.times = times;
+        configure(PageRank.TIMES, times);
     }
 
     @Override
@@ -118,4 +161,24 @@ public final class PageRankVertexProgramStep extends VertexProgramStep implement
     public int hashCode() {
         return super.hashCode() ^ this.edgeTraversal.hashCode() ^ this.pageRankProperty.hashCode() ^ this.times;
     }
+
+    /**
+     * Configuration options to be passed to the {@link GraphTraversal#with(String, Object)} step.
+     */
+    public static class PageRank {
+        /**
+         * Configures number of iterations that the algorithm should run.
+         */
+        public static final String TIMES = Graph.Hidden.hide("tinkerpop.pageRank.times");
+
+        /**
+         * Configures the edge to traverse when calculating the pagerank.
+         */
+        public static final String EDGES = Graph.Hidden.hide("tinkerpop.pageRank.edges");
+
+        /**
+         * Configures the name of the property within which to store the pagerank value.
+         */
+        public static final String PROPERTY_NAME = Graph.Hidden.hide("tinkerpop.pageRank.propertyName");
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PeerPressureVertexProgramStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PeerPressureVertexProgramStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PeerPressureVertexProgramStep.java
index 47d4160..be65f42 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PeerPressureVertexProgramStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/traversal/step/map/PeerPressureVertexProgramStep.java
@@ -25,10 +25,13 @@ import org.apache.tinkerpop.gremlin.process.computer.clustering.peerpressure.Pee
 import org.apache.tinkerpop.gremlin.process.computer.traversal.lambda.HaltedTraversersCountTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Configuring;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TimesModulating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import org.apache.tinkerpop.gremlin.process.traversal.util.PureTraversal;
 import org.apache.tinkerpop.gremlin.structure.Edge;
@@ -42,16 +45,44 @@ import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-public final class PeerPressureVertexProgramStep extends VertexProgramStep implements TraversalParent, ByModulating, TimesModulating {
+public final class PeerPressureVertexProgramStep extends VertexProgramStep
+        implements TraversalParent, ByModulating, TimesModulating, Configuring {
 
+    private Parameters parameters = new Parameters();
     private PureTraversal<Vertex, Edge> edgeTraversal;
     private String clusterProperty = PeerPressureVertexProgram.CLUSTER;
     private int times = 30;
 
     public PeerPressureVertexProgramStep(final Traversal.Admin traversal) {
         super(traversal);
-        this.modulateBy(__.<Vertex>outE().asAdmin());
+        this.configure(PeerPressure.EDGES, __.<Vertex>outE().asAdmin());
+    }
+
+    @Override
+    public void configure(final Object... keyValues) {
+        if (keyValues[0].equals(PeerPressureVertexProgramStep.PeerPressure.EDGES)) {
+            if (!(keyValues[1] instanceof Traversal))
+                throw new IllegalArgumentException("PeerPressure.EDGES requires a Traversal as its argument");
+            this.edgeTraversal = new PureTraversal<>(((Traversal<Vertex,Edge>) keyValues[1]).asAdmin());
+            this.integrateChild(this.edgeTraversal.get());
+        } else if (keyValues[0].equals(PeerPressureVertexProgramStep.PeerPressure.PROPERTY_NAME)) {
+            if (!(keyValues[1] instanceof String))
+                throw new IllegalArgumentException("PeerPressure.PROPERTY_NAME requires a String as its argument");
+            this.clusterProperty = (String) keyValues[1];
+        } else if (keyValues[0].equals(PeerPressureVertexProgramStep.PeerPressure.TIMES)) {
+            if (!(keyValues[1] instanceof Integer))
+                throw new IllegalArgumentException("PeerPressure.TIMES requires an Integer as its argument");
+            this.times = (int) keyValues[1];
+        }else {
+            this.parameters.set(this, keyValues);
+        }
+    }
+
+    @Override
+    public Parameters getParameters() {
+        return parameters;
     }
 
     @Override
@@ -59,20 +90,31 @@ public final class PeerPressureVertexProgramStep extends VertexProgramStep imple
         return super.hashCode() ^ this.edgeTraversal.hashCode() ^ this.clusterProperty.hashCode() ^ this.times;
     }
 
+    /**
+     * @deprecated As of release 3.4.0, replaced by {@link #configure(Object...)}
+     */
+    @Deprecated
     @Override
     public void modulateBy(final Traversal.Admin<?, ?> edgeTraversal) {
-        this.edgeTraversal = new PureTraversal<>((Traversal.Admin<Vertex, Edge>) edgeTraversal);
-        this.integrateChild(this.edgeTraversal.get());
+        configure(PeerPressure.EDGES, edgeTraversal);
     }
 
+    /**
+     * @deprecated As of release 3.4.0, replaced by {@link #configure(Object...)}
+     */
+    @Deprecated
     @Override
     public void modulateBy(final String clusterProperty) {
-        this.clusterProperty = clusterProperty;
+        configure(PeerPressure.PROPERTY_NAME, clusterProperty);
     }
 
+    /**
+     * @deprecated As of release 3.4.0, replaced by {@link #configure(Object...)}
+     */
+    @Deprecated
     @Override
     public void modulateTimes(int times) {
-        this.times = times;
+        configure(PeerPressure.TIMES, times);
     }
 
     @Override
@@ -115,4 +157,24 @@ public final class PeerPressureVertexProgramStep extends VertexProgramStep imple
         super.setTraversal(parentTraversal);
         this.integrateChild(this.edgeTraversal.get());
     }
+
+    /**
+     * Configuration options to be passed to the {@link GraphTraversal#with(String, Object)} step.
+     */
+    public static class PeerPressure {
+        /**
+         * Configures number of iterations that the algorithm should run.
+         */
+        public static final String TIMES = Graph.Hidden.hide("tinkerpop.peerPressure.times");
+
+        /**
+         * Configures the edge to traverse when determining clusters.
+         */
+        public static final String EDGES = Graph.Hidden.hide("tinkerpop.peerPressure.edges");
+
+        /**
+         * Configures the name of the property within which to store the cluster value.
+         */
+        public static final String PROPERTY_NAME = Graph.Hidden.hide("tinkerpop.peerPressure.propertyName");
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Parameterizing.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Parameterizing.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Parameterizing.java
deleted file mode 100644
index 9b7e088..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Parameterizing.java
+++ /dev/null
@@ -1,37 +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;
-
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
-
-/**
- * An interface for {@link Step} implementations that hold a {@link Parameters} object, which fold in arguments from
- * other steps. It is typically used on mutating steps, such as {@code addV()}, where calls to {@code property(k,v)}
- * are folded in as parameters to that add vertex step.
- *
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public interface Parameterizing {
-
-    /**
-     * Gets the parameters on the step.
-     */
-    public Parameters getParameters();
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index 0fd3599..7d1e7e4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -36,6 +36,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.lambda.LoopTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.lambda.PredicateTraverser;
 import org.apache.tinkerpop.gremlin.process.traversal.lambda.TrueTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Configuring;
 import org.apache.tinkerpop.gremlin.process.traversal.step.FromToModulating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Mutating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TimesModulating;
@@ -2074,10 +2075,10 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
         final Step endStep = this.asAdmin().getEndStep();
         if ((endStep instanceof AddVertexStep || endStep instanceof AddEdgeStep || endStep instanceof AddVertexStartStep || endStep instanceof AddEdgeStartStep) &&
                 keyValues.length == 0 && null == cardinality) {
-            ((Mutating) endStep).addPropertyMutations(key, value);
+            ((Mutating) endStep).configure(key, value);
         } else {
             this.asAdmin().addStep(new AddPropertyStep(this.asAdmin(), cardinality, key, value));
-            ((AddPropertyStep) this.asAdmin().getEndStep()).addPropertyMutations(keyValues);
+            ((AddPropertyStep) this.asAdmin().getEndStep()).configure(keyValues);
         }
         return this;
     }
@@ -2496,6 +2497,24 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
         return this.asAdmin().addStep(new LambdaCollectingBarrierStep<>(this.asAdmin(), (Consumer) barrierConsumer, Integer.MAX_VALUE));
     }
 
+    //// WITH-MODULATOR
+
+    /**
+     * Provides a configuration to a step in the form of a key and value pair. The key of the configuration must be
+     * step specific and therefore a configuration could be supplied that is not known to be valid until execution.
+     *
+     * @param key the key of the configuration to apply to a step
+     * @param value the value of the configuration to apply to a step
+     * @return the traversal with a modulated step
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#with-step" target="_blank">Reference Documentation - With Step</a>
+     * @since 3.4.0
+     */
+    public default GraphTraversal<S,E> with(final String key, final Object value) {
+        this.asAdmin().getBytecode().addStep(Symbols.with, key, value);
+        final Object[] configPair = { key, value };
+        ((Configuring) this.asAdmin().getEndStep()).configure(configPair);
+        return this;
+    }
 
     //// BY-MODULATORS
 
@@ -2801,6 +2820,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
         public static final String program = "program";
 
         public static final String by = "by";
+        public static final String with = "with";
         public static final String times = "times";
         public static final String as = "as";
         public static final String option = "option";

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Configuring.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Configuring.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Configuring.java
new file mode 100644
index 0000000..4ac6280
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Configuring.java
@@ -0,0 +1,41 @@
+/*
+ * 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.step;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
+
+/**
+ * Identifies a {@link Step} as one that can accept configurations via the {@link GraphTraversal#with(String, Object)}
+ * step modulator. The nature of the configuration allowed is specific to the implementation.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public interface Configuring extends Parameterizing {
+
+    /**
+     * Accept a configuration to the {@link Step}. Note that this interface extends {@link Parameterizing} and so
+     * there is an expectation that the {@link Step} implementation will have a {@link Parameters} instance that will
+     * house any values passed to this method. Storing these configurations in {@link Parameters} is not a requirement
+     * however, IF the configuration is an expected option for the step and can be stored on a member field that can
+     * be accessed on the step by more direct means (i.e. like a getter method).
+     */
+    public void configure(final Object... keyValues);
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Mutating.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Mutating.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Mutating.java
index 50e415a..14553d9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Mutating.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Mutating.java
@@ -28,13 +28,10 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.event.Event;
  * @author Stephen Mallette (http://stephen.genoprime.com)
  * @author Matt Frantz (http://github.com/mhfrantz)
  */
-public interface Mutating<E extends Event> {
+public interface Mutating<E extends Event> extends Configuring {
 
     /**
      * Gets the callback registry for events that the step raises.
      */
     public CallbackRegistry<E> getMutatingCallbackRegistry();
-
-    public void addPropertyMutations(final Object... keyValues);
-
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Parameterizing.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Parameterizing.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Parameterizing.java
new file mode 100644
index 0000000..9d8dc22
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Parameterizing.java
@@ -0,0 +1,39 @@
+/*
+ * 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.step;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
+
+/**
+ * An interface for {@link Step} implementations that hold a {@link Parameters} object, which fold in arguments from
+ * other steps. It is typically used on mutating steps, such as {@code addV()}, where calls to {@code property(k,v)}
+ * are folded in as parameters to that add vertex step, but it may be used for any step that could benefit from
+ * modulation.
+ *
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public interface Parameterizing {
+
+    /**
+     * Gets the parameters on the step.
+     */
+    public Parameters getParameters();
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DropStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DropStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DropStep.java
index cd95e48..e7e14bb 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DropStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DropStep.java
@@ -21,6 +21,7 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Mutating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.event.CallbackRegistry;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.event.Event;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.event.ListCallbackRegistry;
@@ -94,7 +95,13 @@ public final class DropStep<S> extends FilterStep<S> implements Mutating<Event>
     /**
      * This method doesn't do anything as {@code drop()} doesn't take property mutation arguments.
      */
-    public void addPropertyMutations(final Object... keyValues) {
+    @Override
+    public void configure(final Object... keyValues) {
         // do nothing
     }
+
+    @Override
+    public Parameters getParameters() {
+        return Parameters.EMPTY;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
index 73f69a0..c6a2ef1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
@@ -19,7 +19,7 @@
 
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
-import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
@@ -51,7 +51,7 @@ import java.util.Set;
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class AddEdgeStartStep extends AbstractStep<Edge, Edge>
-        implements Mutating<Event.EdgeAddedEvent>, TraversalParent, Parameterizing, Scoping, FromToModulating {
+        implements Mutating<Event.EdgeAddedEvent>, TraversalParent, Scoping, FromToModulating {
 
     private static final String FROM = Graph.Hidden.hide("from");
     private static final String TO = Graph.Hidden.hide("to");
@@ -86,7 +86,7 @@ public final class AddEdgeStartStep extends AbstractStep<Edge, Edge>
     }
 
     @Override
-    public void addPropertyMutations(final Object... keyValues) {
+    public void configure(final Object... keyValues) {
         this.parameters.set(this, keyValues);
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
index 81afd03..27197f4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
-import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.FromToModulating;
@@ -37,7 +37,6 @@ import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
 import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 
 import java.util.List;
@@ -48,7 +47,7 @@ import java.util.Set;
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public final class AddEdgeStep<S> extends MapStep<S, Edge>
-        implements Mutating<Event.EdgeAddedEvent>, TraversalParent, Parameterizing, Scoping, FromToModulating {
+        implements Mutating<Event.EdgeAddedEvent>, TraversalParent, Scoping, FromToModulating {
 
     private static final String FROM = Graph.Hidden.hide("from");
     private static final String TO = Graph.Hidden.hide("to");
@@ -82,7 +81,7 @@ public final class AddEdgeStep<S> extends MapStep<S, Edge>
     }
 
     @Override
-    public void addPropertyMutations(final Object... keyValues) {
+    public void configure(final Object... keyValues) {
         this.parameters.set(this, keyValues);
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
index 920fa45..f47e631 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
-import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
@@ -37,7 +37,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementExce
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
 
 import java.util.List;
 import java.util.Set;
@@ -47,7 +46,7 @@ import java.util.Set;
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public final class AddVertexStartStep extends AbstractStep<Vertex, Vertex>
-        implements Mutating<Event.VertexAddedEvent>, TraversalParent, Parameterizing, Scoping {
+        implements Mutating<Event.VertexAddedEvent>, TraversalParent, Scoping {
 
     private Parameters parameters = new Parameters();
     private boolean first = true;
@@ -79,7 +78,7 @@ public final class AddVertexStartStep extends AbstractStep<Vertex, Vertex>
     }
 
     @Override
-    public void addPropertyMutations(final Object... keyValues) {
+    public void configure(final Object... keyValues) {
         this.parameters.set(this, keyValues);
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
index 13e2fc8..e555277 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
-import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Mutating;
@@ -33,7 +33,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequire
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
 
 import java.util.List;
 import java.util.Set;
@@ -43,7 +42,7 @@ import java.util.Set;
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public final class AddVertexStep<S> extends MapStep<S, Vertex>
-        implements Mutating<Event.VertexAddedEvent>, TraversalParent, Parameterizing, Scoping {
+        implements Mutating<Event.VertexAddedEvent>, TraversalParent, Scoping {
 
     private Parameters parameters = new Parameters();
     private CallbackRegistry<Event.VertexAddedEvent> callbackRegistry;
@@ -74,7 +73,7 @@ public final class AddVertexStep<S> extends MapStep<S, Vertex>
     }
 
     @Override
-    public void addPropertyMutations(final Object... keyValues) {
+    public void configure(final Object... keyValues) {
         this.parameters.set(this, keyValues);
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
index 7509f86..04a8414 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
 
-import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Mutating;
@@ -37,9 +37,6 @@ import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
 
 import java.util.List;
 import java.util.Set;
@@ -48,7 +45,7 @@ import java.util.Set;
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class AddPropertyStep<S extends Element> extends SideEffectStep<S>
-        implements Mutating<Event.ElementPropertyChangedEvent>, TraversalParent, Parameterizing, Scoping {
+        implements Mutating<Event.ElementPropertyChangedEvent>, TraversalParent, Scoping {
 
     private Parameters parameters = new Parameters();
     private final VertexProperty.Cardinality cardinality;
@@ -76,7 +73,7 @@ public final class AddPropertyStep<S extends Element> extends SideEffectStep<S>
     }
 
     @Override
-    public void addPropertyMutations(final Object... keyValues) {
+    public void configure(final Object... keyValues) {
         this.parameters.set(this, keyValues);
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java
index d368322..40d9330 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java
@@ -48,6 +48,8 @@ import java.util.function.Supplier;
  */
 public final class Parameters implements Cloneable, Serializable {
 
+    public static final Parameters EMPTY = new Parameters();
+
     private static final Object[] EMPTY_ARRAY = new Object[0];
 
     private Map<Object, List<Object>> parameters = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
index c8f9d22..25a2833 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
@@ -21,7 +21,7 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
-import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/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
index 438d8b2..877c2df 100644
--- 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
@@ -21,7 +21,7 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
-import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
@@ -203,7 +203,7 @@ public final class PartitionStrategy extends AbstractTraversalStrategy<Traversal
             // ends up being a Vertex or not.  AddPropertyStep currently chooses to simply not bother
             // to use the additional "property mutations" if the Element being mutated is a Edge or
             // VertexProperty
-            ((Mutating) step).addPropertyMutations(partitionKey, writePartition);
+            ((Mutating) step).configure(partitionKey, writePartition);
 
             if (includeMetaProperties) {
                 // GraphTraversal folds g.addV().property('k','v') to just AddVertexStep/AddVertexStartStep so this
@@ -216,7 +216,7 @@ public final class PartitionStrategy extends AbstractTraversalStrategy<Traversal
                         final VertexProperty.Cardinality cardinality = vertexFeatures.getCardinality((String) k);
                         v.forEach(o -> {
                             final AddPropertyStep addPropertyStep = new AddPropertyStep(traversal, cardinality, k, o);
-                            addPropertyStep.addPropertyMutations(partitionKey, writePartition);
+                            addPropertyStep.configure(partitionKey, writePartition);
                             addPropertyStepsToAppend.add(addPropertyStep);
 
                             // need to remove the parameter from the AddVertex/StartStep because it's now being added

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
index 6decbe0..9009d0b 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
@@ -42,7 +42,7 @@ import static org.junit.Assert.assertEquals;
 public class GraphTraversalTest {
     private static final Logger logger = LoggerFactory.getLogger(GraphTraversalTest.class);
 
-    private static Set<String> NO_GRAPH = new HashSet<>(Arrays.asList("asAdmin", "by", "option", "iterate", "to", "from", "profile", "pageRank", "peerPressure", "program", "none"));
+    private static Set<String> NO_GRAPH = new HashSet<>(Arrays.asList("asAdmin", "by", "with", "option", "iterate", "to", "from", "profile", "pageRank", "peerPressure", "program", "none"));
     private static Set<String> NO_ANONYMOUS = new HashSet<>(Arrays.asList("start", "__"));
     private static Set<String> IGNORES_BYTECODE = new HashSet<>(Arrays.asList("asAdmin", "iterate", "mapValues", "mapKeys"));
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index bb3d5d8..537cdbe 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -1679,9 +1679,9 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Adds the with step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
-        public GraphTraversal<S, E> With (StepConfiguration modulation)
+        public GraphTraversal<S, E> With (string key, object value)
         {
-            Bytecode.AddStep("with", modulation);
+            Bytecode.AddStep("with", key, value);
             return Wrap<S, E>(this);
         }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-javascript/glv/generate.groovy
----------------------------------------------------------------------
diff --git a/gremlin-javascript/glv/generate.groovy b/gremlin-javascript/glv/generate.groovy
index 8fd22e3..8778e89 100644
--- a/gremlin-javascript/glv/generate.groovy
+++ b/gremlin-javascript/glv/generate.groovy
@@ -28,7 +28,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__
 import java.lang.reflect.Modifier
 
 def toJsMap = ["in": "in_",
-               "from": "from_"]
+               "from": "from_",
+               "with": "with_"]
 
 def toJs = { symbol -> toJsMap.getOrDefault(symbol, symbol) }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
index 901f9b0..f143542 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
@@ -1137,7 +1137,7 @@ class GraphTraversal extends Traversal {
    * @param {...Object} args
    * @returns {GraphTraversal}
    */
-  with(...args) {
+  with_(...args) {
     this.bytecode.addStep('with', args);
     return this;
   }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-python/glv/generate.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/glv/generate.groovy b/gremlin-python/glv/generate.groovy
index 58d0cd3..57cc9c9 100644
--- a/gremlin-python/glv/generate.groovy
+++ b/gremlin-python/glv/generate.groovy
@@ -30,6 +30,7 @@ def toPythonMap = ["global": "global_",
                    "as": "as_",
                    "in": "in_",
                    "and": "and_",
+                   "with": "with_",
                    "or": "or_",
                    "is": "is_",
                    "not": "not_",

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
index a492f9c..bb81d87 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
@@ -505,7 +505,7 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("where", *args)
         return self
 
-    def with(self, *args):
+    def with_(self, *args):
         self.bytecode.add_step("with", *args)
         return self
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
index 07a2b04..325621e 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PageRankTest.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
 import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
 import org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.PageRankVertexProgramStep.PageRank;
 import org.apache.tinkerpop.gremlin.process.traversal.Order;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
@@ -63,6 +64,8 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasLabelXsoftwareX_hasXname_rippleX_pageRankX1X_byXinEXcreatedXX_timesX1X_byXpriorsX_inXcreatedX_unionXboth__identityX_valueMapXname_priorsX();
 
+    public abstract Traversal<Vertex, Map<Object, List<Vertex>>> get_g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_withXPROPERTY_NAME_pageRankXX_withXEDGES_inEXX_withXTIMES_1X_inXcreatedX_groupXmX_byXpageRankX_capXmX();
+
     public abstract Traversal<Vertex, Map<Object, List<Vertex>>> get_g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_byXpageRankX_byXinEX_timesX1X_inXcreatedX_groupXmX_byXpageRankX_capXmX();
 
     @Test
@@ -238,6 +241,39 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
         });
     }
 
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_withXPROPERTY_NAME_pageRankXX_withXEDGES_inEXX_withXTIMES_1X_inXcreatedX_groupXmX_byXpageRankX_capXmX() {
+        // [{2.0=[v[4], v[4], v[4], v[4]], 1.0=[v[6], v[6], v[6], v[1], v[1], v[1]], software=[v[5], v[3], v[3], v[3]]}]
+        final Traversal<Vertex, Map<Object, List<Vertex>>> traversal = get_g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_withXPROPERTY_NAME_pageRankXX_withXEDGES_inEXX_withXTIMES_1X_inXcreatedX_groupXmX_byXpageRankX_capXmX();
+        printTraversalForm(traversal);
+        final Map<Object, List<Vertex>> map = traversal.next();
+        assertFalse(traversal.hasNext());
+        assertEquals(3, map.size());
+        assertTrue(map.containsKey("software"));
+        map.forEach((k, v) -> {
+            boolean found = false;
+            if (!k.equals("software") && v.size() == 4) {
+                assertEquals(2.0d, ((Number) k).doubleValue(), 0.01d);
+                assertEquals(4, v.stream().filter(vertex -> vertex.id().equals(convertToVertexId(graph, "josh"))).count());
+                found = true;
+            } else if (v.size() == 6) {
+                assertEquals(1.0d, ((Number) k).doubleValue(), 0.01d);
+                assertEquals(3, v.stream().filter(vertex -> vertex.id().equals(convertToVertexId(graph, "peter"))).count());
+                assertEquals(3, v.stream().filter(vertex -> vertex.id().equals(convertToVertexId(graph, "marko"))).count());
+                found = true;
+            } else if (v.size() == 4) {
+                assertEquals("software", k);
+                assertEquals(3, v.stream().filter(vertex -> vertex.id().equals(convertToVertexId(graph, "lop"))).count());
+                assertEquals(1, v.stream().filter(vertex -> vertex.id().equals(convertToVertexId(graph, "ripple"))).count());
+                found = true;
+            }
+
+            if (!found)
+                fail("There are too many key/values: " + k + "--" + v);
+        });
+    }
+
     public static class Traversals extends PageRankTest {
 
         @Override
@@ -284,5 +320,10 @@ public abstract class PageRankTest extends AbstractGremlinProcessTest {
         public Traversal<Vertex, Map<Object, List<Vertex>>> get_g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_byXpageRankX_byXinEX_timesX1X_inXcreatedX_groupXmX_byXpageRankX_capXmX() {
             return g.V().out("created").group("m").by(T.label).pageRank(1.0).by("pageRank").by(__.inE()).times(1).in("created").group("m").by("pageRank").cap("m");
         }
+
+        @Override
+        public Traversal<Vertex, Map<Object, List<Vertex>>> get_g_V_outXcreatedX_groupXmX_byXlabelX_pageRankX1X_withXPROPERTY_NAME_pageRankXX_withXEDGES_inEXX_withXTIMES_1X_inXcreatedX_groupXmX_byXpageRankX_capXmX() {
+            return g.V().out("created").group("m").by(T.label).pageRank(1.0).with(PageRank.PROPERTY_NAME, "pageRank").with(PageRank.EDGES, __.inE()).with(PageRank.TIMES, 1).in("created").group("m").by("pageRank").cap("m");
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12b84a1c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
index f9615d5..c76941b 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PeerPressureTest.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.TestHelper;
 import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
 import org.apache.tinkerpop.gremlin.process.computer.clustering.peerpressure.PeerPressureVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.PeerPressureVertexProgramStep.PeerPressure;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -50,6 +51,8 @@ public abstract class PeerPressureTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasXname_rippleX_inXcreatedX_peerPressure_byXoutEX_byXclusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX();
 
+    public abstract Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXEDGES_outEX_withXPROPERTY_NAME_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX();
+
     @Test
     @LoadGraphWith(MODERN)
     public void g_V_peerPressure() {
@@ -100,7 +103,28 @@ public abstract class PeerPressureTest extends AbstractGremlinProcessTest {
         assertTrue(ids.contains(convertToVertexId("peter")));
     }
 
-
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXEDGES_outEX_withXPROPERTY_NAME_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX() {
+        TestHelper.assumeNonDeterministic();
+        final Traversal<Vertex, Map<String, List<Object>>> traversal = get_g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXEDGES_outEX_withXPROPERTY_NAME_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX();
+        printTraversalForm(traversal);
+        final List<Map<String, List<Object>>> results = traversal.toList();
+        assertEquals(6, results.size());
+        final Map<String, Object> clusters = new HashMap<>();
+        results.forEach(m -> clusters.put((String) m.get("name").get(0), m.get("cluster").get(0)));
+        assertEquals(2, results.get(0).size());
+        assertEquals(6, clusters.size());
+        assertEquals(clusters.get("josh"), clusters.get("ripple"));
+        assertEquals(clusters.get("josh"), clusters.get("lop"));
+        final Set<Object> ids = new HashSet<>(clusters.values());
+        assertEquals(4, ids.size());
+        assertTrue(ids.contains(convertToVertexId("marko")));
+        assertTrue(ids.contains(convertToVertexId("vadas")));
+        assertTrue(ids.contains(convertToVertexId("josh")));
+        assertTrue(ids.contains(convertToVertexId("peter")));
+    }
+    
     public static class Traversals extends PeerPressureTest {
 
         @Override
@@ -117,5 +141,10 @@ public abstract class PeerPressureTest extends AbstractGremlinProcessTest {
         public Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasXname_rippleX_inXcreatedX_peerPressure_byXoutEX_byXclusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX() {
             return g.V().has("name", "ripple").in("created").peerPressure().by(__.outE()).by("cluster").repeat(__.union(__.identity(), __.both())).times(2).dedup().valueMap("name", "cluster");
         }
+
+        @Override
+        public Traversal<Vertex, Map<String, List<Object>>> get_g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXEDGES_outEX_withXPROPERTY_NAME_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX() {
+            return g.V().has("name", "ripple").in("created").peerPressure().with(PeerPressure.EDGES,__.outE()).with(PeerPressure.PROPERTY_NAME, "cluster").repeat(__.union(__.identity(), __.both())).times(2).dedup().valueMap("name", "cluster");
+        }
     }
 }
\ No newline at end of file