You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ke...@apache.org on 2023/10/18 06:49:11 UTC

[tinkerpop] branch TINKERPOP-2978-3 created (now 77cde1445e)

This is an automated email from the ASF dual-hosted git repository.

kenhuuu pushed a change to branch TINKERPOP-2978-3
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


      at 77cde1445e Implement list functions.

This branch includes the following new commits:

     new 77cde1445e Implement list functions.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[tinkerpop] 01/01: Implement list functions.

Posted by ke...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kenhuuu pushed a commit to branch TINKERPOP-2978-3
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 77cde1445ed06ab369a21dea37edfbf7002b1abf
Author: Ken Hu <10...@users.noreply.github.com>
AuthorDate: Mon Sep 18 13:25:56 2023 -0700

    Implement list functions.
---
 .../dev/future/proposal-3-remove-closures.asciidoc |  34 ++-
 docs/src/dev/provider/gremlin-semantics.asciidoc   | 250 +++++++++++++++++-
 docs/src/reference/the-traversal.asciidoc          | 137 +++++++++-
 docs/src/upgrade/release-3.7.x.asciidoc            |  28 +-
 .../grammar/DefaultGremlinBaseVisitor.java         |  52 ++++
 .../language/grammar/TraversalMethodVisitor.java   | 104 ++++++++
 .../traversal/dsl/graph/GraphTraversal.java        | 177 ++++++++++++-
 .../gremlin/process/traversal/dsl/graph/__.java    | 102 +++++++-
 .../process/traversal/step/map/CombineStep.java    |  96 +++++++
 .../process/traversal/step/map/DifferenceStep.java |  99 +++++++
 .../process/traversal/step/map/DisjunctStep.java   | 109 ++++++++
 .../process/traversal/step/map/IntersectStep.java  | 100 ++++++++
 .../process/traversal/step/map/JoinStep.java       |  80 ++++++
 .../process/traversal/step/map/ProductStep.java    | 103 ++++++++
 .../process/traversal/step/map/ReverseStep.java    |  36 ++-
 .../traversal/step/map/TraversalMergeStep.java     | 131 ++++++++++
 .../process/traversal/util/BytecodeHelper.java     |  14 +
 .../process/traversal/util/ListFunction.java       | 199 ++++++++++++++
 .../tinkerpop/gremlin/util/CollectionUtil.java     |   2 +
 .../gremlin/util/iterator/IteratorUtils.java       |   4 +
 .../grammar/TraversalMethodVisitorTest.java        |  78 ++++++
 ...{ReverseStepTest.java => DisjunctStepTest.java} |  18 +-
 .../traversal/step/map/ReverseLocalStepTest.java   |  79 ++++++
 .../traversal/step/map/ReverseStepTest.java        |  20 +-
 .../Process/Traversal/GraphTraversal.cs            | 121 ++++++++-
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 134 +++++++++-
 gremlin-go/driver/anonymousTraversal.go            |  49 ++++
 gremlin-go/driver/cucumber/gremlin.go              | 134 +++++++++-
 gremlin-go/driver/graphTraversal.go                |  43 ++++
 .../lib/process/graph-traversal.js                 |  70 +++++
 .../gremlin-javascript/test/cucumber/gremlin.js    | 134 +++++++++-
 gremlin-language/src/main/antlr4/Gremlin.g4        |  61 ++++-
 .../gremlin_python/process/graph_traversal.py      |  52 ++++
 gremlin-python/src/main/python/radish/gremlin.py   | 134 +++++++++-
 gremlin-server/src/assembly/standalone.xml         |   8 -
 .../tinkerpop/gremlin/features/StepDefinition.java |  23 +-
 .../gremlin/test/features/map/Combine.feature      | 213 +++++++++++++++
 .../gremlin/test/features/map/Difference.feature   | 226 ++++++++++++++++
 .../gremlin/test/features/map/Disjunct.feature     | 204 +++++++++++++++
 .../gremlin/test/features/map/Intersect.feature    | 204 +++++++++++++++
 .../gremlin/test/features/map/Join.feature         | 152 +++++++++++
 .../gremlin/test/features/map/Merge.feature        | 271 ++++++++++++++++++++
 .../gremlin/test/features/map/Product.feature      | 285 +++++++++++++++++++++
 .../gremlin/test/features/map/Reverse.feature      | 112 +++++++-
 .../tinkergraph/TinkerGraphFeatureTest.java        |   2 +-
 45 files changed, 4566 insertions(+), 118 deletions(-)

diff --git a/docs/src/dev/future/proposal-3-remove-closures.asciidoc b/docs/src/dev/future/proposal-3-remove-closures.asciidoc
index 90d1ed60c8..a86a0a65af 100644
--- a/docs/src/dev/future/proposal-3-remove-closures.asciidoc
+++ b/docs/src/dev/future/proposal-3-remove-closures.asciidoc
@@ -905,6 +905,7 @@ below:
 * <<union_list, union()>>
 * <<difference_list, difference()>>
 * <<disjunct_list, disjunct()>>
+* <<join_list, join()>>
 
 === Gremlin Language Variant Function Names
 
@@ -939,6 +940,8 @@ below:
 
 |disjunct() |disjunct() |disjunct() |disjunct() |Disjunct()
 |Disjunct()
+
+|join() |join() |join() |join() |Join() |Join()
 |===
 
 '''''
@@ -1305,8 +1308,6 @@ g.V().has('age', 29).values('age').dedup().fold().difference(V().has('age', 30).
 ==>[29, 30]
 ....
 
-....
-
 === `disjunct()` [[disjunct_list]]
 
 Returns the disjunct set of the incoming array and the traversal or array
@@ -1337,8 +1338,37 @@ g.inject([1,2]).disjunct([1])
 ==>[2]
 g.inject([1,2,4]).disjunct([1, 2, 3])
 ==>[3, 4]
+....
+
+=== `join()` [[join_list]]
+
+Returns the join of the incoming array and delimiter passed as a
+parameter. This will return a String of the values joined together with
+the delimiter.
+
+==== Signature(s)
+
+`join(delimiter)`
+
+==== Parameters
+
+* delimiter - A string delimiter used to join the values
+
+==== Allowed incoming traverser types
+
+String data types. If non-array data types are passed in then an
+`IllegalArgumentException` will be thrown
+
+==== Expected Output
 
+A string of the values joined together with the delimiter
 
+....
+g.inject([1,2]).join("5")
+==>152
+g.inject([1,2,3]).join(";")
+==>1;2;3
+....
 
 == Date Manipulation functions in TinkerPop [[date-function-syntax]]
 
diff --git a/docs/src/dev/provider/gremlin-semantics.asciidoc b/docs/src/dev/provider/gremlin-semantics.asciidoc
index 74b69e5329..6e90ec120d 100644
--- a/docs/src/dev/provider/gremlin-semantics.asciidoc
+++ b/docs/src/dev/provider/gremlin-semantics.asciidoc
@@ -725,6 +725,43 @@ link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/o
 link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/service/ServiceRegistry.java[ServiceRegistry],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#call-step[reference]
 
+[[combine-step]]
+=== combine()
+
+*Description:* Appends one list to the other and returns the result to the Traversal Stream.
+
+*Syntax:* `combine(Object)` | `combine(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A list is returned after the combine operation is applied so duplicates are allowed. `Merge` can be used instead if
+duplicates aren't wanted. This step only applies to list types which means that non-iterable types (including null)
+will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/CombineStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#combine-step[reference],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#merge-step[reference],
+
 [[concat-step]]
 === concat()
 
@@ -871,6 +908,77 @@ can return any of:
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#dedup-step[reference]
 
+[[difference-step]]
+=== difference()
+
+*Description:* Adds the difference of two lists to the Traversal Stream. 
+
+*Syntax:* `difference(Object)` | `difference(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+Set difference (`A-B`) is an ordered operation. The incoming traverser is treated as `A` and the provided argument is
+treated as `B`. A set is returned after the difference operation is applied so there won't be duplicates. This step only
+applies to list types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DifferenceStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#difference-step[reference]
+
+[[disjunct-step]]
+=== disjunct()
+
+*Description:* Adds the disjunct set to the Traversal Stream.
+
+*Syntax:* `disjunct(Object)` | `disjunct(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A set is returned after the disjunct operation is applied so there won't be duplicates. This step only applies to list
+types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DisjunctStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#disjunct-step[reference]
+
 [[element-step]]
 === element()
 
@@ -917,6 +1025,76 @@ Null values from the incoming traverser are not processed and remain as null whe
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LengthStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#length-step[reference]
 
+[[intersect-step]]
+=== intersect()
+
+*Description:* Adds the intersection to the Traversal Stream.
+
+*Syntax:* `intersect(Object)` | `intersect(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A set is returned after the intersect operation is applied so there won't be duplicates. This step only applies to list
+types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IntersectStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#intersect-step[reference]
+
+[[join-step]]
+=== join()
+
+*Description:* Joins every element in a list together into a String. 
+
+*Syntax:* `join(String)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`String`
+|=========================================================
+
+*Arguments:*
+
+* `String` - A delimiter to use to join the elements together. Can't be null.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+Every element in the list (including nulls) is converted to a String. The delimiter is inserted between neighboring
+elements to form the final result. This step only applies to list types which means that non-iterable types (including
+null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/JoinStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#join-step[reference]
+
 [[lTrim-step]]
 === lTrim()
 
@@ -943,6 +1121,41 @@ Null values from the incoming traverser are not processed and remain as null whe
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LTrimStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#lTrim-step[reference]
 
+[[merge-step]]
+=== merge()
+
+*Description:* Adds the union of two sets to the Traversal Stream.
+
+*Syntax:* `merge(Object)` | `merge(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A set is returned after the merge operation is applied so there won't be duplicates. This step only applies to list
+types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/MergeStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#merge-step[reference]
+
 [[merge-e-step]]
 === mergeE()
 
@@ -1085,6 +1298,41 @@ resolve to a `Map`.
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeVertexStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#mergev-step[reference]
 
+[[product-step]]
+=== product()
+
+*Description:* Adds the cartesian product to the Traversal Stream.
+
+*Syntax:* `product(Object)` | `product(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`List(List)`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A list of lists is returned after the product operation is applied with the inner list being a result pair. This step only
+applies to list types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/ProductStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#product-step[reference]
+
 [[replace-step]]
 === replace()
 
@@ -1113,7 +1361,7 @@ Null values from the incoming traverser are not processed and remain as null whe
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReplaceStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#replace-step[reference]
 
-
+[[reverse-step]]
 === reverse()
 
 *Description:* Returns a reversed string of the incoming string traverser
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index 76eb708543..54f1931144 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -1140,6 +1140,25 @@ g.V().coin(1.0)
 
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#coin-double-++[`coin(double)`]
 
+[[combine-step]]
+=== Combine Step
+
+The `combine()`-step (*map*) combines the elements of the incoming list traverser and the provided list argument into
+one list. This is also known as appending or concatenating. This step only expects list data (array or Iterable) and
+will throw an `IllegalArgumentException` if any other type is encountered (including null). This differs from the
+`merge` step in that it allows duplicates to exist.
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().combine(["james","jen","marko","vadas"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#combine-Object++[`combine(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#combine-Traversal++[`combine(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#combine-step++[`Semantics`]
+
 [[concat-step]]
 === Concat Step
 
@@ -1382,6 +1401,45 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`],
 link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#dedup-step++[`Semantics`]
 
+[[difference-step]]
+=== Difference Step
+
+The `difference()`-step (*map*) calculates the difference between the incoming list traverser and the provided list
+argument. More specifically, this provides the set operation A-B where A is the traverser and B is the argument. This
+step only expects list data (array or Iterable) and will throw an `IllegalArgumentException` if any other type is
+encountered (including null).
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().difference(["lop","ripple"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#difference-Object++[`difference(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#difference-Traversal++[`difference(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#difference-step++[`Semantics`]
+
+[[disjunct-step]]
+=== Disjunct Step
+
+The `disjunct()`-step (*map*) calculates the disjunct set between the incoming list traverser and the provided list
+argument. This step only expects list data (array or Iterable) and will throw an `IllegalArgumentException` if any other
+type is encountered (including null).
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().disjunct(["lop","peter","sam"]) <1>
+----
+
+<1> Find the unique names between two group of names
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#disjunct-Object++[`disjunct(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#disjunct-Traversal++[`disjunct(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#disjunct-step++[`Semantics`]
+
 [[drop-step]]
 === Drop Step
 
@@ -1881,6 +1939,24 @@ inject(1,2).map {it.get() + 1}.map {g.V(it.get()).next()}.values('name')
 
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#inject-E...-++[`inject(Object)`]
 
+[[intersect-step]]
+=== Intersect Step
+
+The `intersect()`-step (*map*) calculates the intersection between the incoming list traverser and the provided list
+argument. This step only expects list data (array or Iterable) and will throw an `IllegalArgumentException` if any other
+type is encountered (including null).
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().intersect(["marko","josh","james","jen"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#intersect-Object++[`intersect(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#intersect-Traversal++[`intersect(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#intersect-step++[`Semantics`]
+
 anchor:_gremlin_i_o[]
 [[io-step]]
 === IO Step
@@ -2089,6 +2165,24 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#is-org.apache.tinkerpop.gremlin.process.traversal.P-++[`is(P)`],
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`]
 
+[[join-step]]
+=== Join Step
+
+The `join()`-step (*map*) joins together the elements in the incoming list traverser together with the provided argument
+as a delimiter. The resulting `String` is added to the Traversal Stream. This step only expects list data (array or
+Iterable) in the incoming traverser and will throw an `IllegalArgumentException` if any other type is encountered
+(including null). However, null is allowed as an element within the list and is converted to "null".
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().join("+")
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#join-String++[`join(String)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#join-step++[`Semantics`]
+
 [[key-step]]
 === Key Step
 
@@ -2614,6 +2708,25 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#mean-org.apache.tinkerpop.gremlin.process.traversal.Scope-++[`mean(Scope)`],
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`]
 
+[[merge-step]]
+=== Merge Step
+
+The `merge()`-step (*map*) merges the elements of the incoming list traverser and the provided list argument into one
+list. This is also known as the union operation. This step only expects list data (array or Iterable) and will throw
+an `IllegalArgumentException` if any other type is encountered (including null). This differs from the `combine`
+step in that it doesn't allow duplicates.
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().merge(["james","jen","marko","vadas"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#merge-Object++[`merge(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#merge-Traversal++[`merge(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#merge-step++[`Semantics`]
+
 [[mergeedge-step]]
 === MergeEdge Step
 
@@ -3347,6 +3460,24 @@ configuration keys from the `PeerPressure` class and is automatically imported t
 
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#peerPressure--++[`peerPressure()`]
 
+[[product-step]]
+=== Product Step
+
+The `product()`-step (*map*) calculates the cartesian product between the incoming list traverser and the provided list
+argument. This step only expects list data (array or Iterable) and will throw an `IllegalArgumentException` if any
+other type is encountered (including null).
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().product(["james","jen"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#product-Object++[`product(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#product-Traversal++[`product(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#product-step++[`Semantics`]
+
 [[profile-step]]
 === Profile Step
 
@@ -3759,12 +3890,14 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
 [[reverse-step]]
 === Reverse Step
 
-The `reverse()`-step (*map*) returns a reversed string of the incoming string traverser. Null values are not processed and remain
-as null when returned. If the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown.
+The `reverse()`-step (*map*) returns a reversed of the incoming list traverser. Single values (including null) are not
+processed and are added back to the Traversal Stream unchanged. If the incoming traverser is a String value then the
+reversed String will be returned.
 
 [gremlin-groovy,modern]
 ----
 g.V().values("name").reverse()
+g.V().values("name").fold().reverse()
 ----
 
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#reverse--++[`reverse()`]
diff --git a/docs/src/upgrade/release-3.7.x.asciidoc b/docs/src/upgrade/release-3.7.x.asciidoc
index 75206c7076..01155a2eca 100644
--- a/docs/src/upgrade/release-3.7.x.asciidoc
+++ b/docs/src/upgrade/release-3.7.x.asciidoc
@@ -233,7 +233,8 @@ See: link:https://tinkerpop.apache.org/docs/x.y.z/reference/#substring-step[subs
 See: link:https://issues.apache.org/jira/browse/TINKERPOP-2672[TINKERPOP-2672]
 
 ==== List Traverser based Steps
-Additional List manipulation/filter steps have been added to replace the use of closures: `any()` and `all()`.
+Additional List manipulation/filter steps have been added to replace the use of closures: `any()`, `all()`, `product()`,
+`merge()`, `intersect()`, `combine()`, `join()`, `difference()`,`disjunct()` and `reverse()`.
 
 The following example demonstrates usage of the newly introduced steps:
 
@@ -243,11 +244,34 @@ gremlin> g.V().values("age").fold().all(P.gt(10))
 ==>[29,27,32,35]
 gremlin> g.V().values("age").fold().any(P.eq(32))
 ==>[29,27,32,35]
+gremlin> g.V().values("age").fold().product(__.V().values("age").limit(2).fold())
+==>[[29,29],[29,27],[27,29],[27,27],[32,29],[32,27],[35,29],[35,27]]
+gremlin> g.V().values("age").fold().merge([32,30,50])
+==>[32,50,35,27,29,30]
+gremlin> g.V().values("age").fold().combine([32,30,50])
+==>[29,27,32,35,32,30,50]
+gremlin> g.V().values("age").fold().intersect([32,30,50])
+==>[32]
+gremlin> g.V().values("age").fold().disjunct([32,30,50])
+==>[50,35,27,29,30]
+gremlin> g.V().values("age").fold().difference([32,30,50])
+==>[35,27,29]
+gremlin> g.V().values("age").order().by(desc).fold().reverse()
+==>[27,29,32,35]
+gremlin> g.V().values("age").fold().join("-")
+==>29-27-32-35
 ----
 
 See: link:https://issues.apache.org/jira/browse/TINKERPOP-2978[TINKERPOP-2978],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#all-step[all()-step],
-link:https://tinkerpop.apache.org/docs/x.y.z/reference/#any-step[any()-step]
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#any-step[any()-step],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#product-step[product()-step],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#merge-step[merge()-step],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#intersect-step[intersect()-step],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#combine-step[combine()-step],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#join-step[join()-step],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#difference-step[difference()-step],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#disjunct-step[disjunct()-step]
 
 === Upgrading for Providers
 
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
index eca310f6aa..7de72da57e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
@@ -315,6 +315,14 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
 	 * {@inheritDoc}
 	 */
 	@Override public T visitTraversalMethod_coin(final GremlinParser.TraversalMethod_coinContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_combine_Object(final GremlinParser.TraversalMethod_combine_ObjectContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_combine_Traversal(final GremlinParser.TraversalMethod_combine_TraversalContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
@@ -343,6 +351,22 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
 	 * {@inheritDoc}
 	 */
 	@Override public T visitTraversalMethod_dedup_String(final GremlinParser.TraversalMethod_dedup_StringContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_difference_Object(final GremlinParser.TraversalMethod_difference_ObjectContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_difference_Traversal(final GremlinParser.TraversalMethod_difference_TraversalContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_disjunct_Object(final GremlinParser.TraversalMethod_disjunct_ObjectContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_disjunct_Traversal(final GremlinParser.TraversalMethod_disjunct_TraversalContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
@@ -507,6 +531,14 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
 	 * {@inheritDoc}
 	 */
 	@Override public T visitTraversalMethod_inE(final GremlinParser.TraversalMethod_inEContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_intersect_Object(final GremlinParser.TraversalMethod_intersect_ObjectContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_intersect_Traversal(final GremlinParser.TraversalMethod_intersect_TraversalContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
@@ -527,6 +559,10 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
 	 * {@inheritDoc}
 	 */
 	@Override public T visitTraversalMethod_is_P(final GremlinParser.TraversalMethod_is_PContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_join_String(final GremlinParser.TraversalMethod_join_StringContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
@@ -583,6 +619,14 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
 	 * {@inheritDoc}
 	 */
 	@Override public T visitTraversalMethod_mean_Scope(final GremlinParser.TraversalMethod_mean_ScopeContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_merge_Object(final GremlinParser.TraversalMethod_merge_ObjectContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_merge_Traversal(final GremlinParser.TraversalMethod_merge_TraversalContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
@@ -651,6 +695,14 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
 	 * {@inheritDoc}
 	 */
 	@Override public T visitTraversalMethod_peerPressure(final GremlinParser.TraversalMethod_peerPressureContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_product_Object(final GremlinParser.TraversalMethod_product_ObjectContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_product_Traversal(final GremlinParser.TraversalMethod_product_TraversalContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
index dc42e84598..6508d6f70a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
@@ -432,6 +432,22 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
                 antlr.tListVisitor.visitNestedTraversalList(ctx.nestedTraversalList()));
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_combine_Object(final GremlinParser.TraversalMethod_combine_ObjectContext ctx) {
+        return graphTraversal.combine(antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_combine_Traversal(final GremlinParser.TraversalMethod_combine_TraversalContext ctx) {
+        return graphTraversal.combine(antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal()));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -490,6 +506,38 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
         return graphTraversal.dedup(antlr.genericVisitor.parseStringVarargs(ctx.stringLiteralVarargs()));
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_difference_Object(final GremlinParser.TraversalMethod_difference_ObjectContext ctx) {
+        return graphTraversal.difference(antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_difference_Traversal(final GremlinParser.TraversalMethod_difference_TraversalContext ctx) {
+        return graphTraversal.difference(antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_disjunct_Object(final GremlinParser.TraversalMethod_disjunct_ObjectContext ctx) {
+        return graphTraversal.disjunct(antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_disjunct_Traversal(final GremlinParser.TraversalMethod_disjunct_TraversalContext ctx) {
+        return graphTraversal.disjunct(antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal()));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -826,6 +874,22 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
         return graphTraversal.inE(antlr.genericVisitor.parseStringVarargs(ctx.stringLiteralVarargs()));
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_intersect_Object(final GremlinParser.TraversalMethod_intersect_ObjectContext ctx) {
+        return graphTraversal.intersect(antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_intersect_Traversal(final GremlinParser.TraversalMethod_intersect_TraversalContext ctx) {
+        return graphTraversal.intersect(antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal()));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -863,6 +927,14 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
         return graphTraversal.is(antlr.traversalPredicateVisitor.visitTraversalPredicate(ctx.traversalPredicate()));
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_join_String(final GremlinParser.TraversalMethod_join_StringContext ctx) {
+        return graphTraversal.join(antlr.argumentVisitor.parseString(ctx.stringArgument()));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -1018,6 +1090,22 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
         return graphTraversal.mean(antlr.argumentVisitor.parseScope(ctx.traversalScopeArgument()));
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_merge_Object(final GremlinParser.TraversalMethod_merge_ObjectContext ctx) {
+        return graphTraversal.merge(antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_merge_Traversal(final GremlinParser.TraversalMethod_merge_TraversalContext ctx) {
+        return graphTraversal.merge(antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal()));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -1193,6 +1281,22 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
         return graphTraversal.peerPressure();
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_product_Object(final GremlinParser.TraversalMethod_product_ObjectContext ctx) {
+        return graphTraversal.product(antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_product_Traversal(final GremlinParser.TraversalMethod_product_TraversalContext ctx) {
+        return graphTraversal.product(antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal()));
+    }
+
     /**
      * {@inheritDoc}
      */
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 be9674e507..b5165ed753 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
@@ -86,6 +86,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsDateStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsStringStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CallStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CoalesceStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.CombineStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConcatStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConstantStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
@@ -93,6 +94,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DateAddStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DateDiffStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DedupLocalStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.DifferenceStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.DisjunctStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeOtherVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ElementMapStep;
@@ -103,7 +106,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IdStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IndexStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.IntersectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LTrimStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.JoinStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LabelStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaCollectingBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaFlatMapStep;
@@ -124,6 +129,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProductStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProjectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyKeyStep;
@@ -146,6 +152,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.ToLowerStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ToUpperStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalFlatMapStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMapStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMergeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalSelectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TreeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TrimStep;
@@ -197,6 +204,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -1549,15 +1557,13 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     /**
-     * Returns a reversed string of the incoming string traverser. Null values are not processed and
-     * remain as null when returned. If the incoming traverser is a non-String value then an
-     * {@code IllegalArgumentException} will be thrown.
+     * Returns the reverse of the incoming traverser. Null values are not processed and remain as null when returned.
      *
      * @return the traversal with an appended {@link ReverseStep}.
      * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#reverse-step" target="_blank">Reference Documentation - Reverse Step</a>
      * @since 3.7.1
      */
-    public default GraphTraversal<S, String> reverse() {
+    public default GraphTraversal<S, E> reverse() {
         this.asAdmin().getBytecode().addStep(Symbols.reverse);
         return this.asAdmin().addStep(new ReverseStep<>(this.asAdmin()));
     }
@@ -1672,6 +1678,162 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
         return this.asAdmin().addStep(new DateDiffStep<>(this.asAdmin(), dateTraversal));
     }
 
+    /**
+     * Calculates the difference between the list traverser and list argument.
+     *
+     * @return the traversal with an appended {@link DifferenceStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#difference-step" target="_blank">Reference Documentation - Difference Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, Set<?>> difference(final Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.difference);
+        return this.asAdmin().addStep(new DifferenceStep<>(this.asAdmin(), values));
+    }
+
+    /**
+     * Calculates the difference between the list traverser and list argument.
+     *
+     * @return the traversal with an appended {@link DifferenceStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#difference-step" target="_blank">Reference Documentation - Difference Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, Set<?>> difference(final Traversal<?, ?> valuesTraversal) {
+        this.asAdmin().getBytecode().addStep(Symbols.difference);
+        return this.asAdmin().addStep(new DifferenceStep<>(this.asAdmin(), valuesTraversal));
+    }
+
+    /**
+     * Calculates the disjunction between the list traverser and list argument.
+     *
+     * @return the traversal with an appended {@link DisjunctStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#disjunct-step" target="_blank">Reference Documentation - Disjunct Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, Set<?>> disjunct(final Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.disjunct);
+        return this.asAdmin().addStep(new DisjunctStep<>(this.asAdmin(), values));
+    }
+
+    /**
+     * Calculates the disjunction between the list traverser and list argument.
+     *
+     * @return the traversal with an appended {@link DisjunctStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#disjunct-step" target="_blank">Reference Documentation - Disjunct Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, Set<?>> disjunct(final Traversal<?, ?> valuesTraversal) {
+        this.asAdmin().getBytecode().addStep(Symbols.disjunct);
+        return this.asAdmin().addStep(new DisjunctStep<>(this.asAdmin(), valuesTraversal));
+    }
+
+    /**
+     * Calculates the intersection between the list traverser and list argument.
+     *
+     * @return the traversal with an appended {@link IntersectStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#intersect-step" target="_blank">Reference Documentation - Intersect Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, Set<?>> intersect(final Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.intersect);
+        return this.asAdmin().addStep(new IntersectStep<>(this.asAdmin(), values));
+    }
+
+    /**
+     * Calculates the intersection between the list traverser and list argument.
+     *
+     * @return the traversal with an appended {@link IntersectStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#intersect-step" target="_blank">Reference Documentation - Intersect Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, Set<?>> intersect(final Traversal<?, ?> valuesTraversal) {
+        this.asAdmin().getBytecode().addStep(Symbols.intersect);
+        return this.asAdmin().addStep(new IntersectStep<>(this.asAdmin(), valuesTraversal));
+    }
+
+    /**
+     * Joins together the elements of the incoming list traverser together with the provided delimiter.
+     *
+     * @return the traversal with an appended {@link JoinStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#join-step" target="_blank">Reference Documentation - Join Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, String> join(final String delimiter) {
+        this.asAdmin().getBytecode().addStep(Symbols.join);
+        return this.asAdmin().addStep(new JoinStep<>(this.asAdmin(), delimiter));
+    }
+
+    /**
+     * Merges the list traverser and list argument. Also known as union.
+     *
+     * @return the traversal with an appended {@link TraversalMergeStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#merge-step" target="_blank">Reference Documentation - Merge Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, E> merge(final Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.merge);
+        return this.asAdmin().addStep(new TraversalMergeStep<>(this.asAdmin(), values));
+    }
+
+    /**
+     * Merges the list traverser and list argument. Also known as union.
+     *
+     * @return the traversal with an appended {@link TraversalMergeStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#merge-step" target="_blank">Reference Documentation - Merge Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, ?> merge(final Traversal<?, ?> valuesTraversal) {
+        this.asAdmin().getBytecode().addStep(Symbols.merge);
+        return this.asAdmin().addStep(new TraversalMergeStep<>(this.asAdmin(), valuesTraversal));
+    }
+
+    /**
+     * Combines the list traverser and list argument. Also known as concatenation or append.
+     *
+     * @return the traversal with an appended {@link CombineStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#combine-step" target="_blank">Reference Documentation - Combine Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, List<?>> combine(final Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.combine);
+        return this.asAdmin().addStep(new CombineStep<>(this.asAdmin(), values));
+    }
+
+    /**
+     * Combines the list traverser and list argument. Also known as concatenation or append.
+     *
+     * @return the traversal with an appended {@link CombineStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#combine-step" target="_blank">Reference Documentation - Combine Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, List<?>> combine(final Traversal<?, ?> valuesTraversal) {
+        this.asAdmin().getBytecode().addStep(Symbols.combine);
+        return this.asAdmin().addStep(new CombineStep<>(this.asAdmin(), valuesTraversal));
+    }
+
+    /**
+     * Calculates the cartesian product between the list traverser and list argument.
+     *
+     * @return the traversal with an appended {@link ProductStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#product-step" target="_blank">Reference Documentation - Product Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, List<List<?>>> product(final Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.product);
+        return this.asAdmin().addStep(new ProductStep<>(this.asAdmin(), values));
+    }
+
+    /**
+     * Calculates the cartesian product between the list traverser and list argument.
+     *
+     * @return the traversal with an appended {@link ProductStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#product-step" target="_blank">Reference Documentation - Product Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, List<List<?>>> product(final Traversal<?, ?> valuesTraversal) {
+        this.asAdmin().getBytecode().addStep(Symbols.product);
+        return this.asAdmin().addStep(new ProductStep<>(this.asAdmin(), valuesTraversal));
+    }
+
     ///////////////////// FILTER STEPS /////////////////////
 
     /**
@@ -3749,6 +3911,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
         public static final String hasKey = "hasKey";
         public static final String hasValue = "hasValue";
         public static final String is = "is";
+        public static final String join = "join";
         public static final String not = "not";
         public static final String range = "range";
         public static final String limit = "limit";
@@ -3777,6 +3940,12 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
         public static final String dateDiff = "dateDiff";
         public static final String all = "all";
         public static final String any = "any";
+        public static final String merge = "merge";
+        public static final String product = "product";
+        public static final String combine = "combine";
+        public static final String difference = "difference";
+        public static final String disjunct = "disjunct";
+        public static final String intersect = "intersect";
 
         public static final String timeLimit = "timeLimit";
         public static final String simplePath = "simplePath";
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
index f41f3506a6..7cce5f5686 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
@@ -41,6 +41,7 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -652,14 +653,20 @@ public class __ {
         return __.<A>start().rTrim();
     }
 
-
     /**
      * @see GraphTraversal#reverse()
      */
-    public static <A> GraphTraversal<A, String> reverse() {
+    public static <A> GraphTraversal<A, A> reverse() {
         return __.<A>start().reverse();
     }
 
+    /**
+     * @see GraphTraversal#reverse()
+     */
+//    public static <A> GraphTraversal<A, List<?>> reverse() {
+//        return __.<A>start().reverse();
+//    }
+
     /**
      * @see GraphTraversal#replace(String, String)
      */
@@ -716,6 +723,97 @@ public class __ {
         return __.<A>start().dateDiff(dateTraversal);
     }
 
+    /**
+     * @see GraphTraversal#difference(Traversal)
+     */
+    public static <A> GraphTraversal<A, Set<?>> difference(final Object values) {
+        return __.<A>start().difference(values);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, Set<?>> difference(final Traversal<?, Set<?>> valuesTraversal) {
+        return __.<A>start().difference(valuesTraversal);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, Set<?>> disjunct(final Object values) {
+        return __.<A>start().disjunct(values);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, Set<?>> disjunct(final Traversal<?, Set<?>> valuesTraversal) {
+        return __.<A>start().disjunct(valuesTraversal);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, Set<?>> intersect(final Object values) {
+        return __.<A>start().intersect(values);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, Set<?>> intersect(final Traversal<?, Set<?>> valuesTraversal) {
+        return __.<A>start().intersect(valuesTraversal);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, String> join(final String values) {
+        return __.<A>start().join(values);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, A> merge(final Object values) {
+        return __.<A>start().merge(values);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, ?> merge(final Traversal<?, ?> valuesTraversal) {
+        return __.<A>start().merge(valuesTraversal);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, List<?>> combine(final Object values) {
+        return __.<A>start().combine(values);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, List<?>> combine(final Traversal<?, List<?>> valuesTraversal) {
+        return __.<A>start().combine(valuesTraversal);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, List<List<?>>> product(final Object values) {
+        return __.<A>start().product(values);
+    }
+
+    /**
+     * @see GraphTraversal#concat(String...)
+     */
+    public static <A> GraphTraversal<A, List<List<?>>> product(final Traversal<?, List<List<?>>> valuesTraversal) {
+        return __.<A>start().product(valuesTraversal);
+    }
+
     ///////////////////// FILTER STEPS /////////////////////
 
     /**
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CombineStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CombineStep.java
new file mode 100644
index 0000000000..9bf9161ed0
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CombineStep.java
@@ -0,0 +1,96 @@
+/*
+ * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the combination of the traverser and the provided arguments. This is also commonly known as
+ * concatenation or append.
+ */
+public final class CombineStep<S, E> extends ScalarMapStep<S, List<?>> implements TraversalParent, ListFunction {
+    private Traversal.Admin<S, E> valueTraversal;
+    private Object parameterItems;
+
+    public CombineStep(final Traversal.Admin traversal, final Object values) {
+        super(traversal);
+        parameterItems = values;
+    }
+
+    public CombineStep(final Traversal.Admin traversal, final Traversal<S, E> value) {
+        super(traversal);
+        valueTraversal = integrateChild(value.asAdmin());
+    }
+
+    @Override
+    public String getStepName() { return "combine"; }
+
+    @Override
+    protected List<?> map(Traverser.Admin<S> traverser) {
+        final Collection listA = convertTraverserToCollection(traverser);
+        final Collection listB = (null != parameterItems) ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, valueTraversal);
+
+        final List combined = new ArrayList(listA);
+        combined.addAll(listB);
+
+        return combined;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public CombineStep<S, E> clone() {
+        final CombineStep<S, E> clone = (CombineStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStep.java
new file mode 100644
index 0000000000..e78c6290c5
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStep.java
@@ -0,0 +1,99 @@
+/*
+ * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the difference of the traverser and the provided arguments without duplicates.
+ */
+public final class DifferenceStep<S, E> extends ScalarMapStep<S, Set<?>> implements TraversalParent, ListFunction {
+    private Traversal.Admin<S, E> valueTraversal;
+    private Object parameterItems;
+    public DifferenceStep(final Traversal.Admin traversal, final Object values) {
+        super(traversal);
+        parameterItems = values;
+    }
+
+    public DifferenceStep(final Traversal.Admin traversal, final Traversal<S, E> value) {
+        super(traversal);
+        valueTraversal = this.integrateChild(value.asAdmin());
+    }
+
+    @Override
+    public String getStepName() { return "difference"; }
+
+    @Override
+    protected Set<?> map(Traverser.Admin<S> traverser) {
+        final Collection setA = convertTraverserToCollection(traverser);
+        final Collection setB = (null != parameterItems) ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, valueTraversal);
+        final Set differenceSet = new HashSet();
+
+        for (Object element : setA) {
+            if (!setB.contains(element)) {
+                differenceSet.add(element);
+            }
+        }
+
+        return differenceSet;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public DifferenceStep<S, E> clone() {
+        final DifferenceStep<S, E> clone = (DifferenceStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStep.java
new file mode 100644
index 0000000000..f4d7cec433
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStep.java
@@ -0,0 +1,109 @@
+/*
+ * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the disjunction of the traverser and the provided arguments without duplicates.
+ */
+public final class DisjunctStep<S, E> extends ScalarMapStep<S, Set<?>> implements TraversalParent, ListFunction {
+    private Traversal.Admin<S, E> valueTraversal;
+    private Object parameterItems;
+    public DisjunctStep(final Traversal.Admin traversal, final Object values) {
+        super(traversal);
+        parameterItems = values;
+    }
+
+    public DisjunctStep(final Traversal.Admin traversal, final Traversal<S, E> value) {
+        super(traversal);
+        this.valueTraversal = this.integrateChild(value.asAdmin());
+    }
+
+    @Override
+    public String getStepName() { return "disjunct"; }
+
+    @Override
+    protected Set<?> map(Traverser.Admin<S> traverser) {
+        final Set setA = convertTraverserToSet(traverser);
+        final Set setB = (null != parameterItems) ? convertArgumentToSet(parameterItems) : convertTraversalToSet(traverser, this.valueTraversal);
+        final Set disjunctSet = new HashSet();
+
+        if (setA.size() == 0) {
+            return setB;
+        } else if (setB.size() == 0) {
+            return setA;
+        } else {
+            for (Object item : setA) {
+                if (!setB.contains(item)) {
+                    disjunctSet.add(item);
+                }
+            }
+
+            for (Object item : setB) {
+                if (!setA.contains(item)) {
+                    disjunctSet.add(item);
+                }
+            }
+        }
+
+        return disjunctSet;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public DisjunctStep<S, E> clone() {
+        final DisjunctStep<S, E> clone = (DisjunctStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStep.java
new file mode 100644
index 0000000000..fbabebc787
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStep.java
@@ -0,0 +1,100 @@
+/*
+ * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the intersection of the traverser and the provided arguments.
+ */
+public final class IntersectStep<S, E> extends ScalarMapStep<S, Set<?>> implements TraversalParent, ListFunction {
+    private Traversal.Admin<S, E> valueTraversal;
+    private Object parameterItems;
+
+    public IntersectStep(final Traversal.Admin traversal, final Object values) {
+        super(traversal);
+        parameterItems = values;
+    }
+
+    public IntersectStep(final Traversal.Admin traversal, final Traversal<S, E> value) {
+        super(traversal);
+        valueTraversal = integrateChild(value.asAdmin());
+    }
+
+    @Override
+    public String getStepName() { return "intersect"; }
+
+    @Override
+    protected Set<?> map(Traverser.Admin<S> traverser) {
+        final Set setA = convertTraverserToSet(traverser);
+        final Collection setB = (null != parameterItems) ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, this.valueTraversal);
+        final Set intersection = new HashSet();
+
+        for (Object element : setB) {
+            if (setA.contains(element)) {
+                intersection.add(element);
+            }
+        }
+
+        return intersection;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public IntersectStep<S, E> clone() {
+        final IntersectStep<S, E> clone = (IntersectStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/JoinStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/JoinStep.java
new file mode 100644
index 0000000000..f766353657
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/JoinStep.java
@@ -0,0 +1,80 @@
+/*
+ * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the result of joining every element in the traverser using the delimiter argument.
+ */
+public final class JoinStep<S> extends ScalarMapStep<S, String> implements ListFunction {
+    private String delimiter;
+
+    public JoinStep(final Traversal.Admin traversal, final String delimiter) {
+        super(traversal);
+        if (null == delimiter) { throw new IllegalArgumentException("Input delimiter to join step can't be null."); }
+        this.delimiter = delimiter;
+    }
+
+    @Override
+    public String getStepName() { return "join"; }
+
+    @Override
+    protected String map(Traverser.Admin<S> traverser) {
+        final Collection elements = convertTraverserToCollection(traverser);
+
+        final StringBuilder joinResult = new StringBuilder();
+
+        for (Object elem : elements) {
+            joinResult.append(String.valueOf(elem)).append(delimiter);
+        }
+
+        if (joinResult.length() != 0) {
+            joinResult.delete(joinResult.length() - delimiter.length(), joinResult.length());
+        }
+
+        return joinResult.toString();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return Collections.singleton(TraverserRequirement.OBJECT); }
+
+    @Override
+    public JoinStep<S> clone() {
+        final JoinStep<S> clone = (JoinStep<S>) super.clone();
+        clone.delimiter = this.delimiter;
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, delimiter);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStep.java
new file mode 100644
index 0000000000..a4e1ffdd82
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStep.java
@@ -0,0 +1,103 @@
+/*
+ * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the cartesian product of the traverser and the provided arguments.
+ */
+public final class ProductStep<S, E> extends ScalarMapStep<S, List<List<?>>> implements TraversalParent, ListFunction {
+    private Traversal.Admin<S, E> valueTraversal;
+    private Object parameterItems;
+
+    public ProductStep(final Traversal.Admin traversal, final Object values) {
+        super(traversal);
+        parameterItems = values;
+    }
+
+    public ProductStep(final Traversal.Admin traversal, final Traversal<S, E> value) {
+        super(traversal);
+        valueTraversal = integrateChild(value.asAdmin());
+    }
+
+    @Override
+    public String getStepName() { return "product"; }
+
+    @Override
+    protected List<List<?>> map(Traverser.Admin<S> traverser) {
+        final Collection listA = convertTraverserToCollection(traverser);
+        final Collection listB = (null != parameterItems) ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, this.valueTraversal);
+        final List elements = new ArrayList();
+
+        for (Object elementInA : listA) {
+            for (Object elementInB : listB) {
+                final List pair = new ArrayList(2);
+                pair.add(elementInA);
+                pair.add(elementInB);
+                elements.add(pair);
+            }
+        }
+
+        return elements;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public ProductStep<S, E> clone() {
+        final ProductStep<S, E> clone = (ProductStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java
index 0d7258b796..fc1a143341 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java
@@ -21,35 +21,45 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 
+import static org.apache.tinkerpop.gremlin.util.CollectionUtil.asList;
+
 /**
- * Reference implementation for reverse() step, a mid-traversal step which returns a reversed string.
- * Null values are not processed and remain as null when returned. If the incoming traverser is a non-String value
- * then an {@code IllegalArgumentException} will be thrown.
+ * Reference implementation for reverse() step, a mid-traversal step which returns the reverse value.
+ * Null values are not processed and remain as null when returned.
  *
  * @author David Bechberger (http://bechberger.com)
  * @author Yang Xia (http://github.com/xiazcy)
  */
-public final class ReverseStep<S> extends ScalarMapStep<S, String> {
+public final class ReverseStep<S, E> extends ScalarMapStep<S, E> {
 
     public ReverseStep(final Traversal.Admin traversal) {
         super(traversal);
     }
 
     @Override
-    protected String map(final Traverser.Admin<S> traverser) {
-        final S item = traverser.get();
-        // throws when incoming traverser isn't a string
-        if (null != item && !(item instanceof String)) {
-            throw new IllegalArgumentException(
-                    String.format("The reverse() step can only take string as argument, encountered %s", item.getClass()));
-        }
+    protected E map(final Traverser.Admin<S> traverser) {
+        final S items = traverser.get();
 
-        // we will pass null values to next step
-        return null == item? null : new StringBuilder(((String) item)).reverse().toString();
+        if (null == items) {
+            return null;
+        } else if (items instanceof String) {
+            return (E) new StringBuilder(((String) items)).reverse().toString();
+        } else if ((items instanceof Iterable) || (items instanceof Iterator) || items.getClass().isArray()) {
+            final List itemsAsList = IteratorUtils.asList(items);
+            Collections.reverse(itemsAsList);
+            return (E) itemsAsList;
+        } else {
+            // null traversers are passed on without throwing an exception so the same should be done with other types.
+            return (E) items;
+        }
     }
 
     @Override
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStep.java
new file mode 100644
index 0000000000..7231dcd320
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStep.java
@@ -0,0 +1,131 @@
+/*
+ * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the merger of the traverser and the provided arguments without duplicates. This is commonly
+ * known as a union.
+ */
+public final class TraversalMergeStep<S, E> extends ScalarMapStep<S, E> implements TraversalParent, ListFunction {
+    private Traversal.Admin<S, E> valueTraversal;
+    private Object parameterItems;
+    public TraversalMergeStep(final Traversal.Admin traversal, final Object values) {
+        super(traversal);
+        parameterItems = values;
+    }
+
+    public TraversalMergeStep(final Traversal.Admin traversal, final Traversal<S, E> value) {
+        super(traversal);
+        valueTraversal = integrateChild(value.asAdmin());
+    }
+
+    @Override
+    public String getStepName() { return "merge"; }
+
+    @Override
+    protected E map(final Traverser.Admin<S> traverser) {
+        S incoming = traverser.get();
+
+        Map mapA = (incoming instanceof Map) ? (Map) incoming : null;
+        if (mapA != null) {
+            final Object mapB = (parameterItems != null) ? parameterItems : TraversalUtil.apply(traverser, valueTraversal);
+            if (!(mapB instanceof Map)) {
+                throw new IllegalArgumentException(
+                        String.format(
+                                "%s step expected provided argument to evaluate to a Map, encountered %s",
+                                getStepName(),
+                                mapB.getClass()));
+            }
+
+            final Map mergedMap = new HashMap(mapA);
+            mergedMap.putAll((Map) mapB);
+            return (E) mergedMap;
+        } else {
+            final Collection listA = convertTraverserToCollection(traverser);
+
+            if (parameterItems instanceof Map) {
+                throw new IllegalArgumentException(getStepName() + " step type mismatch: expected argument to be Iterable but got Map");
+            }
+            final Collection listB =
+                    (null != parameterItems)
+                            ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, this.valueTraversal);
+
+            final Set elements = new HashSet();
+
+            elements.addAll(listA);
+            elements.addAll(listB);
+
+            return (E) elements;
+        }
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public TraversalMergeStep<S, E> clone() {
+        final TraversalMergeStep<S, E> clone = (TraversalMergeStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else if (this.parameterItems instanceof Map) {
+            clone.parameterItems = new HashMap((Map) this.parameterItems);
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
index e1b7c436af..172ec880a0 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
@@ -68,6 +68,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsDateStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsStringStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CallStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CoalesceStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.CombineStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConcatStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConstantStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
@@ -75,6 +76,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DateAddStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DateDiffStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DedupLocalStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.DifferenceStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.DisjunctStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ElementMapStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ElementStep;
@@ -84,6 +87,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IdStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IndexStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.IntersectStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.JoinStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LTrimStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LabelStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaCollectingBarrierStep;
@@ -104,6 +109,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProductStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProjectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyKeyStep;
@@ -126,6 +132,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.ToLowerStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ToUpperStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalFlatMapStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMapStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMergeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalSelectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TreeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TrimStep;
@@ -230,6 +237,13 @@ public final class BytecodeHelper {
             put(GraphTraversal.Symbols.dateDiff, Collections.singletonList(DateDiffStep.class));
             put(GraphTraversal.Symbols.all, Collections.singletonList(AllStep.class));
             put(GraphTraversal.Symbols.any, Collections.singletonList(AnyStep.class));
+            put(GraphTraversal.Symbols.combine, Collections.singletonList(CombineStep.class));
+            put(GraphTraversal.Symbols.difference, Collections.singletonList(DifferenceStep.class));
+            put(GraphTraversal.Symbols.disjunct, Collections.singletonList(DisjunctStep.class));
+            put(GraphTraversal.Symbols.merge, Collections.singletonList(TraversalMergeStep.class));
+            put(GraphTraversal.Symbols.join, Collections.singletonList(JoinStep.class));
+            put(GraphTraversal.Symbols.product, Collections.singletonList(ProductStep.class));
+            put(GraphTraversal.Symbols.intersect, Collections.singletonList(IntersectStep.class));
             put(GraphTraversal.Symbols.group, Arrays.asList(GroupStep.class, GroupSideEffectStep.class));
             put(GraphTraversal.Symbols.groupCount, Arrays.asList(GroupCountStep.class, GroupCountSideEffectStep.class));
             put(GraphTraversal.Symbols.tree, Arrays.asList(TreeStep.class, TreeSideEffectStep.class));
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ListFunction.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ListFunction.java
new file mode 100644
index 0000000000..ab693b9e29
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ListFunction.java
@@ -0,0 +1,199 @@
+/*
+ * 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.util;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * List functions are a separate paradigm for Steps as they behave in a Scope.Local manner by default. This class
+ * provides helper methods that are common amongst these steps and should be used to keep behavior consistent in terms
+ * of handling of incoming traversers and argument types.
+ */
+public interface ListFunction {
+
+    /**
+     * Turn an iterable type into a collection. Doesn't wrap any non-iterable type into an iterable (e.g. single Object
+     * into list), but will transform one iterable type to another (e.g. array to list).
+     *
+     * @param iterable an Iterable or array.
+     * @return The iterable type as a Collection or null if argument isn't iterable.
+     */
+    public static Collection asCollection(Object iterable) {
+        if (iterable instanceof Collection) {
+            return (Collection) iterable;
+        } else if ((iterable != null && iterable.getClass().isArray()) || iterable instanceof Iterable) {
+            return (Collection) IteratorUtils.asList(iterable);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Turn an iterable type into a set. Doesn't wrap any non-iterable type into an iterable (e.g. single Object
+     * into set), but will transform one iterable type to another (e.g. array to set).
+     *
+     * @param iterable an Iterable or array.
+     * @return The iterable type as a Collection or null if argument isn't iterable.
+     */
+    public static Set asSet(Object iterable) {
+        if (iterable instanceof Iterable || iterable != null && iterable.getClass().isArray()) {
+            return IteratorUtils.asSet(iterable);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Template method used for retrieving the implementing Step's name.
+     *
+     * @return this step's name.
+     */
+    public String getStepName();
+
+    public default Collection convertArgumentToCollection(Object arg) {
+        if (null == arg) {
+            throw new IllegalArgumentException(
+                    String.format("Argument provided for %s step can't be null.", getStepName()));
+        }
+
+        final Collection incoming = asCollection(arg);
+
+        if (null == incoming) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s step can only take an array or an Iterable as an argument, encountered %s",
+                            getStepName(),
+                            arg.getClass()));
+        }
+
+        return incoming;
+    }
+
+    public default <S> Collection convertTraverserToCollection(Traverser.Admin<S> traverser) {
+        final S items = traverser.get();
+
+        if (null == items) {
+            throw new IllegalArgumentException(
+                    String.format("Incoming traverser for %s step can't be null.", getStepName()));
+        }
+
+        final Collection incoming = asCollection(items);
+
+        if (null == incoming) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s step can only take an array or an Iterable type for incoming traversers, encountered %s",
+                            getStepName(),
+                            items.getClass()));
+        }
+
+        return incoming;
+    }
+
+    public default <S, E> Collection convertTraversalToCollection(Traverser.Admin<S> traverser, final Traversal.Admin<S, E> traversal) {
+        final Object array = TraversalUtil.apply(traverser, traversal);
+
+        if (null == array) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Provided traversal argument for %s step must yield an iterable type, not null",
+                            getStepName()));
+        }
+
+        final Collection input = asCollection(array);
+
+        if (null == input) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Provided traversal argument for %s step must yield an iterable type, encountered %s",
+                            getStepName(),
+                            array.getClass()));
+        }
+
+        return input;
+    }
+
+    public default Set convertArgumentToSet(Object arg) {
+        if (null == arg) {
+            throw new IllegalArgumentException(
+                    String.format("Argument provided for %s step can't be null.", getStepName()));
+        }
+
+        final Set incoming = asSet(arg);
+
+        if (null == incoming) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s step can only take an array or an Iterable as an argument, encountered %s",
+                            getStepName(),
+                            arg.getClass()));
+        }
+
+        return incoming;
+    }
+
+    public default <S> Set convertTraverserToSet(Traverser.Admin<S> traverser) {
+        final S items = traverser.get();
+
+        if (null == items) {
+            throw new IllegalArgumentException(
+                    String.format("Incoming traverser for %s step can't be null.", getStepName()));
+        }
+
+        final Set incoming = asSet(items);
+
+        if (null == incoming) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s step can only take an array or an Iterable type for incoming traversers, encountered %s",
+                            getStepName(),
+                            items.getClass()));
+        }
+
+        return incoming;
+    }
+
+    public default <S, E> Set convertTraversalToSet(Traverser.Admin<S> traverser, final Traversal.Admin<S, E> traversal) {
+        final Object array = TraversalUtil.apply(traverser, traversal);
+
+        if (null == array) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Provided traversal argument for %s step must yield an iterable type, not null",
+                            getStepName()));
+        }
+
+        final Set input = asSet(array);
+
+        if (null == input) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Provided traversal argument for %s step must yield an iterable type, encountered %s",
+                            getStepName(),
+                            array.getClass()));
+        }
+
+        return input;
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/CollectionUtil.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/CollectionUtil.java
index 1242d16af7..ff1ddad4ca 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/CollectionUtil.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/CollectionUtil.java
@@ -19,6 +19,8 @@
 
 package org.apache.tinkerpop.gremlin.util;
 
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/iterator/IteratorUtils.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/iterator/IteratorUtils.java
index d7f4b4872e..eb4073d8d2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/iterator/IteratorUtils.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/iterator/IteratorUtils.java
@@ -470,6 +470,10 @@ public final class IteratorUtils {
         return list(asIterator(o));
     }
 
+    public static Set asSet(final Object o) {
+        return set(asIterator(o));
+    }
+
     /**
      * Construct a {@link Stream} from an {@link Iterator}.
      */
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitorTest.java
index a4c4ddd33f..9825287574 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitorTest.java
@@ -276,6 +276,18 @@ public class TraversalMethodVisitorTest {
         compare(g.V().coin(2.5), eval("g.V().coin(2.5)"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_combine_Object() throws Exception {
+        compare(g.V().values("name").fold().combine(new Integer[] {1,2}),
+                eval("g.V().values(\"name\").fold().combine([1,2])"));
+    }
+
+    @Test
+    public void shouldParseTraversalMethod_combine_Traversal() throws Exception {
+        compare(g.V().values("name").fold().combine(V().fold()),
+                eval("g.V().values(\"name\").fold().combine(__.V().fold())"));
+    }
+
     @Test
     public void shouldParseTraversalMethod_constant() throws Exception {
         compare(g.V().constant("yigit"), eval("g.V().constant('yigit')"));
@@ -306,6 +318,30 @@ public class TraversalMethodVisitorTest {
         compare(g.V().dedup(), eval("g.V().dedup()"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_difference_Object() throws Exception {
+        compare(g.V().values("name").fold().difference(new Integer[] {1,2}),
+                eval("g.V().values(\"name\").fold().difference([1,2])"));
+    }
+
+    @Test
+    public void shouldParseTraversalMethod_difference_Traversal() throws Exception {
+        compare(g.V().values("name").fold().difference(V().fold()),
+                eval("g.V().values(\"name\").fold().difference(__.V().fold())"));
+    }
+
+    @Test
+    public void shouldParseTraversalMethod_disjunct_Object() throws Exception {
+        compare(g.V().values("name").fold().disjunct(new Integer[] {1,2}),
+                eval("g.V().values(\"name\").fold().disjunct([1,2])"));
+    }
+
+    @Test
+    public void shouldParseTraversalMethod_disjunct_Traversal() throws Exception {
+        compare(g.V().values("name").fold().disjunct(V().fold()),
+                eval("g.V().values(\"name\").fold().disjunct(__.V().fold())"));
+    }
+
     @Test
     public void shouldParseTraversalMethod_drop() throws Exception {
         compare(g.V().drop(), eval("g.V().drop()"));
@@ -509,6 +545,18 @@ public class TraversalMethodVisitorTest {
                 eval("g.V(4).out().values(\"name\").inject(\"daniel\")"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_intersect_Object() throws Exception {
+        compare(g.V().values("name").fold().intersect(new Integer[] {1,2}),
+                eval("g.V().values(\"name\").fold().intersect([1,2])"));
+    }
+
+    @Test
+    public void shouldParseTraversalMethod_intersect_Traversal() throws Exception {
+        compare(g.V().values("name").fold().intersect(V().fold()),
+                eval("g.V().values(\"name\").fold().intersect(__.V().fold())"));
+    }
+
     @Test
     public void shouldParseTraversalMethod_is_Object() throws Exception {
         compare(g.V().is(4), eval("g.V().is(4)"));
@@ -524,6 +572,12 @@ public class TraversalMethodVisitorTest {
         compare(g.V().iterate(), eval("g.V().iterate()"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_join_Object() throws Exception {
+        compare(g.V().values("name").fold().join(";"),
+                eval("g.V().values(\"name\").fold().join(\";\")"));
+    }
+
     @Test
     public void shouldParseTraversalMethod_key() throws Exception {
         compare(g.V().key(), eval("g.V().key()"));
@@ -589,6 +643,18 @@ public class TraversalMethodVisitorTest {
         compare(g.V().mean(global), eval("g.V().mean(global)"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_merge_Object() throws Exception {
+        compare(g.V().values("name").fold().merge(new Integer[] {1,2}),
+                eval("g.V().values(\"name\").fold().merge([1,2])"));
+    }
+
+    @Test
+    public void shouldParseTraversalMethod_merge_Traversal() throws Exception {
+        compare(g.V().values("name").fold().merge(V().fold()),
+                eval("g.V().values(\"name\").fold().merge(__.V().fold())"));
+    }
+
     @Test
     public void shouldParseTraversalMethod_min_Empty() throws Exception {
         compare(g.V().min(), eval("g.V().min()"));
@@ -675,6 +741,18 @@ public class TraversalMethodVisitorTest {
         compare(g.V().peerPressure(), eval("g.V().peerPressure()"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_product_Object() throws Exception {
+        compare(g.V().values("name").fold().product(new Integer[] {1,2}),
+                eval("g.V().values(\"name\").fold().product([1,2])"));
+    }
+
+    @Test
+    public void shouldParseTraversalMethod_product_Traversal() throws Exception {
+        compare(g.V().values("name").fold().product(V().fold()),
+                eval("g.V().values(\"name\").fold().product(__.V().fold())"));
+    }
+
     @Test
     public void shouldParseTraversalMethod_profile_Empty() throws Exception {
         compare(g.V().profile(), eval("g.V().profile()"));
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java
similarity index 66%
copy from gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
copy to gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java
index 1d508d1b1d..5b0d292cd9 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java
@@ -29,23 +29,13 @@ import java.util.List;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
-/**
- * @author Yang Xia (http://github.com/xiazcy)
- */
-public class ReverseStepTest extends StepTest {
+public class DisjunctStepTest extends StepTest {
 
     @Override
-    protected List<Traversal> getTraversals() {return Collections.singletonList(__.reverse());}
-
-    @Test
-    public void testReturnTypes() {
-        assertEquals("tset", __.__("test").reverse().next());
-        assertArrayEquals(new String[]{"dlrow olleh", "tset", "321.on", null, ""},
-                __.inject("hello world", "test", "no.123", null, "").reverse().toList().toArray());
+    protected List<Traversal> getTraversals() {
+        return Collections.singletonList(__.disjunct("test"));
     }
 
-    @Test(expected = IllegalArgumentException.class)
-    public void shouldThrowWithIncomingArrayList() {__.__(Arrays.asList("abc", "def")).reverse().next();}
-
 }
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseLocalStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseLocalStepTest.java
new file mode 100644
index 0000000000..5d73ade94a
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseLocalStepTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+public class ReverseLocalStepTest extends StepTest {
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Collections.singletonList(__.reverse());
+    }
+//
+//    @Test
+//    public void testReturnTypes() {
+//        assertTrue(__.__(new int[]{}).reverse().hasNext());
+//        assertArrayEquals(new Object[] {7, 10}, __.__(new int[] {10, 7}).reverse().next().toArray());
+//    }
+//
+//    @Test
+//    public void testSetTraverser() {
+//        final Set<Integer> numbers = new HashSet<>();
+//        numbers.add(10);
+//        numbers.add(11);
+//
+//        final Throwable thrown = assertThrows(IllegalArgumentException.class, () -> __.__(numbers).reverse().hasNext());
+//        assertEquals("Incoming traverser for reverse step must be either a list or an array.", thrown.getMessage());
+//    }
+//
+//    @Test
+//    public void testArrayTraverser() {
+//        final int[] numbers = new int[] {10, 11};
+//
+//        final List result = __.__(numbers).reverse().next();
+//        assertEquals(11, result.get(0));
+//        assertEquals(10, result.get(1));
+//    }
+//
+//    @Test
+//    public void testListTraverser() {
+//        final List<Integer> numbers = new ArrayList<>();
+//        numbers.add(10);
+//        numbers.add(11);
+//
+//        final List result = __.__(numbers).reverse().next();
+//        assertEquals(11, result.get(0));
+//        assertEquals(10, result.get(1));
+//    }
+
+}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
index 1d508d1b1d..f9cd341524 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
@@ -25,10 +26,13 @@ import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * @author Yang Xia (http://github.com/xiazcy)
@@ -40,12 +44,24 @@ public class ReverseStepTest extends StepTest {
 
     @Test
     public void testReturnTypes() {
+        assertEquals(Collections.emptyList(), __.__(Collections.emptyList()).reverse().next());
         assertEquals("tset", __.__("test").reverse().next());
         assertArrayEquals(new String[]{"dlrow olleh", "tset", "321.on", null, ""},
                 __.inject("hello world", "test", "no.123", null, "").reverse().toList().toArray());
     }
 
-    @Test(expected = IllegalArgumentException.class)
-    public void shouldThrowWithIncomingArrayList() {__.__(Arrays.asList("abc", "def")).reverse().next();}
+    @Test
+    public void shouldAcceptPrimitiveArrayTraverser() {
+        List result = (List) __.__(new long[] {10L, 7L}).reverse().next();
+        assertEquals(7L, result.get(0));
+        assertEquals(10L, result.get(1));
+        assertEquals(2, result.size());
+    }
+
+    @Test
+    public void shouldAcceptObjectArrayTraverser() {
+        List result = (List) __.__(Arrays.asList(2, "hello", 10L)).reverse().next();
+        assertArrayEquals(new Object[] {10L, "hello", 2}, result.toArray());
+    }
 
 }
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index 91df6644f7..fd6c0f2942 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -538,6 +538,24 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, TEnd>(this);
         }
 
+        /// <summary>
+        ///     Adds the combine step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Combine<TNewEnd> (ITraversal combineTraversal)
+        {
+            Bytecode.AddStep("combine", combineTraversal);
+            return Wrap<TStart, TEnd>(this);
+        }
+
+        /// <summary>
+        ///     Adds the combine step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Combine<TNewEnd> (object combineObject)
+        {
+            Bytecode.AddStep("combine", combineObject);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the concat step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -658,6 +676,42 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, TEnd>(this);
         }
 
+        /// <summary>
+        ///     Adds the difference step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Difference<TNewEnd> (ITraversal differenceTraversal)
+        {
+            Bytecode.AddStep("difference", differenceTraversal);
+            return Wrap<TStart, TEnd>(this);
+        }
+
+        /// <summary>
+        ///     Adds the difference step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Difference<TNewEnd> (object differenceObject)
+        {
+            Bytecode.AddStep("difference", differenceObject);
+            return Wrap<TStart, TEnd>(this);
+        }
+
+        /// <summary>
+        ///     Adds the disjunct step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Disjunct<TNewEnd> (ITraversal disjunctTraversal)
+        {
+            Bytecode.AddStep("disjunct", disjunctTraversal);
+            return Wrap<TStart, TEnd>(this);
+        }
+
+        /// <summary>
+        ///     Adds the disjunct step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Disjunct<TNewEnd> (object disjunctObject)
+        {
+            Bytecode.AddStep("disjunct", disjunctObject);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the drop step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -1144,6 +1198,24 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, TEnd>(this);
         }
 
+        /// <summary>
+        ///     Adds the intersect step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Intersect<TNewEnd> (ITraversal intersectTraversal)
+        {
+            Bytecode.AddStep("intersect", intersectTraversal);
+            return Wrap<TStart, TEnd>(this);
+        }
+
+        /// <summary>
+        ///     Adds the intersect step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Intersect<TNewEnd> (object intersectObject)
+        {
+            Bytecode.AddStep("intersect", intersectObject);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the is step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -1162,6 +1234,15 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, TEnd>(this);
         }
 
+        /// <summary>
+        ///     Adds the join step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Join<TNewEnd> (string delimiter)
+        {
+            Bytecode.AddStep("join", delimiter);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the key step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -1319,6 +1400,24 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, TNewEnd>(this);
         }
 
+        /// <summary>
+        ///     Adds the merge step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Merge<TNewEnd> (ITraversal mergeTraversal)
+        {
+            Bytecode.AddStep("merge", mergeTraversal);
+            return Wrap<TStart, TEnd>(this);
+        }
+
+        /// <summary>
+        ///     Adds the merge step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Merge<TNewEnd> (object mergeObject)
+        {
+            Bytecode.AddStep("merge", mergeObject);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the mergeE step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -1565,6 +1664,24 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, TEnd>(this);
         }
 
+        /// <summary>
+        ///     Adds the product step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Product<TNewEnd> (ITraversal productTraversal)
+        {
+            Bytecode.AddStep("product", productTraversal);
+            return Wrap<TStart, TEnd>(this);
+        }
+
+        /// <summary>
+        ///     Adds the product step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Product<TNewEnd> (object productObject)
+        {
+            Bytecode.AddStep("product", productObject);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the profile step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -1721,10 +1838,10 @@ namespace Gremlin.Net.Process.Traversal
         /// <summary>
         ///     Adds the reverse step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
-        public GraphTraversal<TStart, string?> Reverse ()
+        public GraphTraversal<TStart, TEnd> Reverse ()
         {
             Bytecode.AddStep("reverse");
-            return Wrap<TStart, string?>(this);
+            return Wrap<TStart, TEnd>(this);
         }
 
         /// <summary>
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 9e8f820019..6fa6055171 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -564,6 +564,22 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_coalesceXoutXlikesX_outXknowsX_inXcreatedXX_groupCount_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Coalesce<object>(__.Out("likes"),__.Out("knows"),__.Out("created")).GroupCount<object>().By("name")}}, 
                {"g_V_coalesceXoutEXknowsX_outEXcreatedXX_otherV_path_byXnameX_byXlabelX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Coalesce<object>(__.OutE("knows"),__.OutE("created")).OtherV().Path().By("name").By(T.Label)}}, 
                {"g_V_outXcreatedX_order_byXnameX_coalesceXname_constantXxXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out("created").Order().By("name").Coalesce<object>(__.Values<object>("name"),__.Constant<object>("x"))}}, 
+               {"g_injectXnullX_combineXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Combine()}}, 
+               {"g_V_valuesXnameX_combineXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Combine()}}, 
+               {"g_V_fold_combineXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Combine()}}, 
+               {"g_V_fold_combineXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Combine()}}, 
+               {"g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Combine()}}, 
+               {"g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Combine()}}, 
+               {"g_V_valuesXageX_order_byXdescX_fold_combineXV_valuesXageX_order_byXdescX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().By(Order.Desc).Fold().Combine()}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_combineXMARKOX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Combine()}}, 
+               {"g_injectXxx1X_combineXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Combine()}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_combineXseattle_vancouverX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Combine()}}, 
+               {"g_V_out_out_path_byXnameX_combineXempty_listX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Combine()}}, 
+               {"g_V_valuesXageX_fold_combineXconstantX27X_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Combine()}}, 
+               {"g_V_out_out_path_byXnameX_combineXdave_kelvinX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Combine()}}, 
+               {"g_injectXa_null_bX_combineXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Combine()}}, 
+               {"g_injectXa_null_bX_combineXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Combine()}}, 
+               {"g_injectX3_threeX_combineXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Combine()}}, 
                {"g_injectXa_bX_concat", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject("a","b").Concat<object>()}}, 
                {"g_injectXa_bX_concat_XcX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject("a","b").Concat<object>("c")}}, 
                {"g_injectXa_bX_concat_Xc_dX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject("a","b").Concat<object>("c","d")}}, 
@@ -606,6 +622,38 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_injectXdatetimeXstrXX_dateAddXday_11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1693958400000)).DateAdd(DT.Day,11)}}, 
                {"g_injectXdatetimeXstr1XX_dateDiffXdatetimeXstr2XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1690934400000)).DateDiff(DateTimeOffset.FromUnixTimeMilliseconds(1691539200000))}}, 
                {"g_injectXdatetimeXstr1XX_dateDiffXinjectXdatetimeXstr2XXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1691452800000)).DateDiff(__.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1690848000000)))}}, 
+               {"g_injectXnullX_differenceXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Difference()}}, 
+               {"g_V_valuesXnameX_differenceXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Difference()}}, 
+               {"g_V_fold_differenceXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Difference()}}, 
+               {"g_V_fold_differenceXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Difference()}}, 
+               {"g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Difference()}}, 
+               {"g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Difference()}}, 
+               {"g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Difference()}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_differenceXMARKOX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Difference()}}, 
+               {"g_injectXmarkoX_differenceXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Difference()}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_differenceXseattle_vancouverX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Difference()}}, 
+               {"g_V_out_out_path_byXnameX_differenceXrippleX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Difference()}}, 
+               {"g_V_out_out_path_byXnameX_differenceXempty_listX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Difference()}}, 
+               {"g_V_valuesXageX_fold_differenceXconstantX27X_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Difference()}}, 
+               {"g_V_out_out_path_byXnameX_differenceXdave_kelvinX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Difference()}}, 
+               {"g_injectXa_null_bX_differenceXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Difference()}}, 
+               {"g_injectXa_null_bX_differenceXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Difference()}}, 
+               {"g_injectX3_threeX_differenceXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Difference()}}, 
+               {"g_injectXnullX_disjunctXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Disjunct()}}, 
+               {"g_V_valuesXnameX_disjunctXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Disjunct()}}, 
+               {"g_V_fold_disjunctXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Disjunct()}}, 
+               {"g_V_fold_disjunctXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Disjunct()}}, 
+               {"g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Disjunct()}}, 
+               {"g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Disjunct()}}, 
+               {"g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Disjunct()}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_disjunctXMARKOX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Disjunct()}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_disjunctXseattle_vancouverX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Disjunct()}}, 
+               {"g_V_out_out_path_byXnameX_disjunctXmarkoX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Disjunct()}}, 
+               {"g_V_out_out_path_byXnameX_disjunctXstephen_markoX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Disjunct()}}, 
+               {"g_V_out_out_path_byXnameX_disjunctXdave_kelvinX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Disjunct()}}, 
+               {"g_injectXa_null_bX_disjunctXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Disjunct()}}, 
+               {"g_injectXa_null_bX_disjunctXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Disjunct()}}, 
+               {"g_injectX3_threeX_disjunctXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Disjunct()}}, 
                {"g_V_EX11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().E(p["eid11"])}}, 
                {"g_EX11X_E", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E(p["eid11"]).E()}}, 
                {"g_V_EXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().E(null)}}, 
@@ -638,10 +686,31 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_hasLabelXsoftwareX_name_fold_orderXlocalX_index_unfold_order_byXtailXlocal_1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("software").Values<object>("name").Fold().Order(Scope.Local).Index<object>().Unfold<object>().Order().By(__.Tail<object>(Scope.Local,1))}}, 
                {"g_V_hasLabelXpersonX_name_fold_orderXlocalX_index_withXmapX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("person").Values<object>("name").Fold().Order(Scope.Local).Index<object>().With("~tinkerpop.index.indexer",1)}}, 
                {"g_VX1X_valuesXageX_index_unfold_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Values<object>("age").Index<object>().Unfold<object>().Unfold<object>()}}, 
-               {"g_injectX__feature___test__nullX_lTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("  feature"," one test",null,""," ").LTrim()}}, 
-               {"g_injectX__feature__X_lTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject("  feature  ").LTrim()}}, 
-               {"g_injectXListXa_bXX_lTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).LTrim()}}, 
-               {"g_V_valuesXnameX_lTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name"," marko ").Property("age",29).As("marko").AddV("person").Property("name","  vadas  ").Property("age",27).As("vadas").AddV("software").Property("name","  lop").Property("lang","java").As("lop").AddV("person").Property("name","josh  ").Property("age",32).As("josh").AddV("software").Property("name","   ripple   ").Property("lang"," [...]
+               {"g_injectXnullX_intersectXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Intersect()}}, 
+               {"g_V_valuesXnameX_intersectXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Intersect()}}, 
+               {"g_V_fold_intersectXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Intersect()}}, 
+               {"g_V_fold_intersectXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Intersect()}}, 
+               {"g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Intersect()}}, 
+               {"g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Intersect()}}, 
+               {"g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Intersect()}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_intersectXMARKOX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Intersect()}}, 
+               {"g_injectXmarkoX_intersectX___V_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Intersect()}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_intersectXseattle_vancouverX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Intersect()}}, 
+               {"g_V_valuesXageX_fold_intersectX___constantX27X_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Intersect()}}, 
+               {"g_V_out_out_path_byXnameX_intersectXdave_kelvinX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Intersect()}}, 
+               {"g_injectXa_null_bX_intersectXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Intersect()}}, 
+               {"g_injectXa_null_bX_intersectXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Intersect()}}, 
+               {"g_injectX3_threeX_intersectXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Intersect()}}, 
+               {"g_injectXnullX_joinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Join()}}, 
+               {"g_V_valuesXnameX_joinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Join()}}, 
+               {"g_V_valuesXnonexistantX_fold_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Join()}}, 
+               {"g_V_valuesXnameX_fold_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Join()}}, 
+               {"g_V_valuesXageX_order_fold_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().Fold().Join()}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Join()}}, 
+               {"g_injectXxx1X_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Join(), (g,p) =>g.Inject(p["xx1"]).Join()}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Join()}}, 
+               {"g_V_out_out_path_byXnameX_joinXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Join()}}, 
+               {"g_injectXxx1X_joinXxyzX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Join()}}, 
                {"g_injectXfeature_test_nullX_length", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("feature","test",null).Length()}}, 
                {"g_injectXListXa_bXX_length", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Length()}}, 
                {"g_V_valuesXnameX_length", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Length()}}, 
@@ -649,6 +718,10 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_VX1X_repeatXboth_simplePathX_untilXhasXname_peterX_or_loops_isX2XX_hasXname_peterX_path_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Repeat(__.Both().SimplePath()).Until(__.Has("name","peter").Or().Loops().Is(2)).Has("name","peter").Path().By("name")}}, 
                {"g_VX1X_repeatXboth_simplePathX_untilXhasXname_peterX_and_loops_isX3XX_hasXname_peterX_path_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Repeat(__.Both().SimplePath()).Until(__.Has("name","peter").And().Loops().Is(3)).Has("name","peter").Path().By("name")}}, 
                {"g_V_emitXhasXname_markoX_or_loops_isX2XX_repeatXoutX_valuesXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Emit(__.Has("name","marko").Or().Loops().Is(2)).Repeat(__.Out()).Values<object>("name")}}, 
+               {"g_injectX__feature___test__nullX_lTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("  feature"," one test",null,""," ").LTrim()}}, 
+               {"g_injectX__feature__X_lTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject("  feature  ").LTrim()}}, 
+               {"g_injectXListXa_bXX_lTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).LTrim()}}, 
+               {"g_V_valuesXnameX_lTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name"," marko ").Property("age",29).As("marko").AddV("person").Property("name","  vadas  ").Property("age",27).As("vadas").AddV("software").Property("name","  lop").Property("lang","java").As("lop").AddV("person").Property("name","josh  ").Property("age",32).As("josh").AddV("software").Property("name","   ripple   ").Property("lang"," [...]
                {"g_VX1X_mapXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Map<object>((IFunction) p["l1"])}}, 
                {"g_VX1X_outE_label_mapXlengthX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).OutE().Label().Map<object>((IFunction) p["l1"])}}, 
                {"g_VX1X_out_mapXnameX_mapXlengthX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Out().Map<object>((IFunction) p["l1"]).Map<object>((IFunction) p["l2"])}}, 
@@ -735,6 +808,27 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_injectXnull_10_20_nullX_mean", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null,p["xx1"],p["xx2"],null).Mean<object>()}}, 
                {"g_injectXlistXnull_10_20_nullXX_meanXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Mean<object>(Scope.Local)}}, 
                {"g_VX1X_valuesXageX_meanXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Values<object>("age").Mean<object>(Scope.Local)}}, 
+               {"g_injectXnullX_mergeXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Merge()}}, 
+               {"g_V_valuesXnameX_mergeXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Merge()}}, 
+               {"g_V_fold_mergeXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Merge()}}, 
+               {"g_V_fold_mergeXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Merge()}}, 
+               {"g_V_elementMap_mergeXconstantXaXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ElementMap<object>().Merge()}}, 
+               {"g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Merge()}}, 
+               {"g_V_fold_mergeXk_vX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Merge()}}, 
+               {"g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Merge()}}, 
+               {"g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Merge()}}, 
+               {"g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Merge()}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_mergeXMARKOX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Merge()}}, 
+               {"g_injectXmarkoX_mergeXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Merge()}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_mergeXseattle_vancouverX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Merge()}}, 
+               {"g_V_out_out_path_byXnameX_mergeXempty_listX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Merge()}}, 
+               {"g_V_valuesXageX_fold_mergeXconstantX27X_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Merge()}}, 
+               {"g_V_out_out_path_byXnameX_mergeXdave_kelvinX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Merge()}}, 
+               {"g_injectXa_null_bX_mergeXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Merge()}}, 
+               {"g_injectXa_null_bX_mergeXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Merge()}}, 
+               {"g_injectX3_threeX_mergeXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Merge()}}, 
+               {"g_V_asXnameX_projectXnameX_byXnameX_mergeXother_blueprintX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().As("name").Project<object>("name").By("name").Merge()}}, 
+               {"g_V_hasXname_markoX_elementMap_mergeXV_hasXname_lopX_elementMapX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name","marko").ElementMap<object>().Merge()}}, 
                {"g_V_mergeEXlabel_selfX_optionXonMatch_emptyX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name","marko").Property("age",29).AddE("self"), (g,p) =>g.V().MergeE((IDictionary<object,object>) p["xx1"]).Option(Merge.OnMatch, (IDictionary<object,object>) new Dictionary<object,object> {}), (g,p) =>g.E(), (g,p) =>g.E().Properties<object>(), (g,p) =>g.V()}}, 
                {"g_V_mergeEXlabel_selfX_optionXonMatch_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name","marko").Property("age",29).AddE("self"), (g,p) =>g.V().MergeE((IDictionary<object,object>) p["xx1"]).Option(Merge.OnMatch, (IDictionary<object,object>) null), (g,p) =>g.E(), (g,p) =>g.E().Properties<object>(), (g,p) =>g.V()}}, 
                {"g_V_mergeEXemptyX_optionXonCreate_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name","marko").Property("age",29), (g,p) =>g.V().As("v").MergeE((IDictionary<object,object>) p["xx1"]).Option(Merge.OnCreate, (IDictionary<object,object>) null).Option(Merge.OutV, (ITraversal) __.Select<object>("v")).Option(Merge.InV, (ITraversal) __.Select<object>("v")), (g,p) =>g.E(), (g,p) =>g.V()}}, 
@@ -901,6 +995,21 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_peerPressure_hasXclusterX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().PeerPressure().Has("gremlin.peerPressureVertexProgram.cluster")}}, 
                {"g_V_peerPressure_withXpropertyName_clusterX_withXedges_outEXknowsXX_pageRankX1X_byXrankX_withXedges_outEXknowsX_withXtimes_2X_group_byXclusterX_byXrank_sumX_limitX100X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().PeerPressure().With("~tinkerpop.peerPressure.propertyName","cluster").With("~tinkerpop.peerPressure.edges",__.OutE("knows")).PageRank(1.0).With("~tinkerpop.pageRank.propertyName","rank").With("~tinkerpop.pageRank [...]
                {"g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withyXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name","ripple").In("created").PeerPressure().With("~tinkerpop.peerPressure.edges",__.OutE()).With("~tinkerpop.peerPressure.propertyName","cluster").Repeat(__.Union<object>(__.Identity(),__.Both())).Times(2).Dedup().Va [...]
+               {"g_injectXnullX_productXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Product()}}, 
+               {"g_V_valuesXnameX_productXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Product()}}, 
+               {"g_V_fold_productXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Product()}}, 
+               {"g_V_fold_productXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Product()}}, 
+               {"g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Product()}}, 
+               {"g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Product()}}, 
+               {"g_V_valuesXageX_order_byXdescX_limitX3X_fold_productXV_valuesXageX_order_byXascX_limitX2X_foldX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().By(Order.Desc).Limit<object>(3).Fold().Product().Unfold<object>()}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_productXMARKOX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Product().Unfold<object>()}}, 
+               {"g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Product().Unfold<object>()}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_productXdulles_seattle_vancouverX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Product().Unfold<object>()}}, 
+               {"g_V_valuesXageX_order_byXascX_fold_productXconstantX27X_foldX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().By(Order.Asc).Fold().Product().Unfold<object>()}}, 
+               {"g_V_out_out_path_byXnameX_productXdave_kelvinX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Product().Unfold<object>()}}, 
+               {"g_injectXa_null_bX_productXa_cX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Product().Unfold<object>()}}, 
+               {"g_injectXa_null_bX_productXa_null_cX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Product().Unfold<object>()}}, 
+               {"g_injectX3_threeX_productXfive_three_7X_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Product().Unfold<object>()}}, 
                {"g_V_hasLabelXpersonX_projectXa_bX_byXoutE_countX_byXageX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("person").Project<object>("a","b").By(__.OutE().Count()).By("age")}}, 
                {"g_V_outXcreatedX_projectXa_bX_byXnameX_byXinXcreatedX_countX_order_byXselectXbX__descX_selectXaX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out("created").Project<object>("a","b").By("name").By(__.In("created").Count()).Order().By(__.Select<object>("b"),Order.Desc).Select<object>("a")}}, 
                {"g_V_valueMap_projectXxX_byXselectXnameXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>().Project<object>("x").By(__.Select<object>("name"))}}, 
@@ -911,17 +1020,24 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_hasXageX_propertiesXage_nameX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("age").Properties<object>("age","name").Value<object>()}}, 
                {"g_V_propertiesXname_age_nullX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>("name","age",null).Value<object>()}}, 
                {"g_V_valuesXname_age_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name","age",null)}}, 
-               {"g_injectX__feature___test__nullX_rTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("feature  ","one test ",null,""," ").RTrim()}}, 
-               {"g_injectX__feature__X_rTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject("  feature  ").RTrim()}}, 
-               {"g_injectXListXa_bXX_rTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).RTrim()}}, 
-               {"g_V_valuesXnameX_rTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name"," marko ").Property("age",29).As("marko").AddV("person").Property("name","  vadas  ").Property("age",27).As("vadas").AddV("software").Property("name","  lop").Property("lang","java").As("lop").AddV("person").Property("name","josh  ").Property("age",32).As("josh").AddV("software").Property("name","   ripple   ").Property("lang"," [...]
                {"g_injectXthat_this_testX_replaceXh_jX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("that","this","test",null).Replace("h","j")}}, 
                {"g_injectXListXa_bXcX_replaceXa_bX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Replace("a","b")}}, 
                {"g_V_hasLabelXsoftwareX_valueXnameX_replaceXnull_iX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("software").Values<object>("name").Replace(null,"g")}}, 
                {"g_V_hasLabelXsoftwareX_valueXnameX_replaceXa_iX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("software").Values<object>("name").Replace("p","g")}}, 
                {"g_injectXfeature_test_nullX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("feature","test one",null).Reverse()}}, 
-               {"g_injectXListXa_bXX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Reverse()}}, 
                {"g_V_valuesXnameX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Reverse()}}, 
+               {"g_V_valuesXageX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Reverse()}}, 
+               {"g_V_out_path_byXnameX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By("name").Reverse()}}, 
+               {"g_V_out_out_path_byXnameX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Reverse()}}, 
+               {"g_V_valuesXageX_fold_orderXlocalX_byXdescX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Order(Scope.Local).By(Order.Desc).Reverse()}}, 
+               {"g_V_valuesXnameX_fold_orderXlocalX_by_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Order(Scope.Local).By().Reverse()}}, 
+               {"g_injectXnullX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Reverse()}}, 
+               {"g_injectXbX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject("b").Reverse()}}, 
+               {"g_injectX3_threeX_reverse", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Reverse()}}, 
+               {"g_injectX__feature___test__nullX_rTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("feature  ","one test ",null,""," ").RTrim()}}, 
+               {"g_injectX__feature__X_rTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject("  feature  ").RTrim()}}, 
+               {"g_injectXListXa_bXX_rTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).RTrim()}}, 
+               {"g_V_valuesXnameX_rTrim", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name"," marko ").Property("age",29).As("marko").AddV("person").Property("name","  vadas  ").Property("age",27).As("vadas").AddV("software").Property("name","  lop").Property("lang","java").As("lop").AddV("person").Property("name","josh  ").Property("age",32).As("josh").AddV("software").Property("name","   ripple   ").Property("lang"," [...]
                {"g_VX1X_asXaX_outXknowsX_asXbX_selectXa_bX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).As("a").Out("knows").As("b").Select<object>("a","b")}}, 
                {"g_VX1X_asXaX_outXknowsX_asXbX_selectXa_bX_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).As("a").Out("knows").As("b").Select<object>("a","b").By("name")}}, 
                {"g_VX1X_asXaX_outXknowsX_asXbX_selectXaX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).As("a").Out("knows").As("b").Select<object>("a")}}, 
diff --git a/gremlin-go/driver/anonymousTraversal.go b/gremlin-go/driver/anonymousTraversal.go
index 009f25dd25..c0c85c70d2 100644
--- a/gremlin-go/driver/anonymousTraversal.go
+++ b/gremlin-go/driver/anonymousTraversal.go
@@ -87,6 +87,8 @@ type AnonymousTraversal interface {
 	Coalesce(args ...interface{}) *GraphTraversal
 	// Coin adds the coin step to the GraphTraversal.
 	Coin(args ...interface{}) *GraphTraversal
+	// Combine adds the combine step to the GraphTraversal.
+	Combine(args ...interface{}) *GraphTraversal
 	// Concat adds the Concat step to the GraphTraversal.
 	Concat(args ...interface{}) *GraphTraversal
 	// ConnectedComponent adds the connectedComponent step to the GraphTraversal.
@@ -99,6 +101,10 @@ type AnonymousTraversal interface {
 	CyclicPath(args ...interface{}) *GraphTraversal
 	// Dedup adds the dedup step to the GraphTraversal.
 	Dedup(args ...interface{}) *GraphTraversal
+	// Difference adds the difference step to the GraphTraversal.
+	Difference(args ...interface{}) *GraphTraversal
+	// Disjunct adds the disjunct step to the GraphTraversal.
+	Disjunct(args ...interface{}) *GraphTraversal
 	// Drop adds the drop step to the GraphTraversal.
 	Drop(args ...interface{}) *GraphTraversal
 	// Element adds the element step to the GraphTraversal.
@@ -147,8 +153,12 @@ type AnonymousTraversal interface {
 	Index(args ...interface{}) *GraphTraversal
 	// Inject adds the inject step to the GraphTraversal.
 	Inject(args ...interface{}) *GraphTraversal
+	// Intersect adds the intersect step to the GraphTraversal.
+	Intersect(args ...interface{}) *GraphTraversal
 	// Is adds the is step to the GraphTraversal.
 	Is(args ...interface{}) *GraphTraversal
+	// Join adds the join step to the GraphTraversal.
+	Join(args ...interface{}) *GraphTraversal
 	// Key adds the key step to the GraphTraversal.
 	Key(args ...interface{}) *GraphTraversal
 	// Label adds the label step to the GraphTraversal.
@@ -173,6 +183,8 @@ type AnonymousTraversal interface {
 	Max(args ...interface{}) *GraphTraversal
 	// Mean adds the mean step to the GraphTraversal.
 	Mean(args ...interface{}) *GraphTraversal
+	// Merge adds the merge step to the GraphTraversal.
+	Merge(args ...interface{}) *GraphTraversal
 	// MergeE adds the mergeE step to the GraphTraversal.
 	MergeE(args ...interface{}) *GraphTraversal
 	// MergeV adds the mergeV step to the GraphTraversal.
@@ -205,6 +217,8 @@ type AnonymousTraversal interface {
 	Path(args ...interface{}) *GraphTraversal
 	// PeerPressure adds the peerPressure step to the GraphTraversal.
 	PeerPressure(args ...interface{}) *GraphTraversal
+	// Product adds the product step to the GraphTraversal.
+	Product(args ...interface{}) *GraphTraversal
 	// Profile adds the profile step to the GraphTraversal.
 	Profile(args ...interface{}) *GraphTraversal
 	// Program adds the program step to the GraphTraversal.
@@ -418,6 +432,11 @@ func (anonymousTraversal *anonymousTraversal) Coin(args ...interface{}) *GraphTr
 	return anonymousTraversal.graphTraversal().Coin(args...)
 }
 
+// Combine adds the combine step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Combine(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Combine(args...)
+}
+
 // Concat adds the Concat step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Concat(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Concat(args...)
@@ -458,6 +477,16 @@ func (anonymousTraversal *anonymousTraversal) Dedup(args ...interface{}) *GraphT
 	return anonymousTraversal.graphTraversal().Dedup(args...)
 }
 
+// Differece adds the differece step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Differece(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Differece(args...)
+}
+
+// Disjunct adds the disjunct step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Disjunct(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Disjunct(args...)
+}
+
 // Drop adds the drop step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Drop(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Drop(args...)
@@ -578,11 +607,21 @@ func (anonymousTraversal *anonymousTraversal) Inject(args ...interface{}) *Graph
 	return anonymousTraversal.graphTraversal().Inject(args...)
 }
 
+// Intersect adds the intersect step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Intersect(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Intersect(args...)
+}
+
 // Is adds the is step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Is(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Is(args...)
 }
 
+// Join adds the join step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Join(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Join(args...)
+}
+
 // Key adds the key step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Key(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Key(args...)
@@ -643,6 +682,11 @@ func (anonymousTraversal *anonymousTraversal) Mean(args ...interface{}) *GraphTr
 	return anonymousTraversal.graphTraversal().Mean(args...)
 }
 
+// Merge adds the merge step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Merge(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Merge(args...)
+}
+
 // MergeE adds the mergeE step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) MergeE(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().MergeE(args...)
@@ -723,6 +767,11 @@ func (anonymousTraversal *anonymousTraversal) PeerPressure(args ...interface{})
 	return anonymousTraversal.graphTraversal().PeerPressure(args...)
 }
 
+// Product adds the product step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Product(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Product(args...)
+}
+
 // Profile adds the profile step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Profile(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Profile(args...)
diff --git a/gremlin-go/driver/cucumber/gremlin.go b/gremlin-go/driver/cucumber/gremlin.go
index 5ff32812a9..36ce242ded 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -535,6 +535,22 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_V_coalesceXoutXlikesX_outXknowsX_inXcreatedXX_groupCount_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Coalesce(gremlingo.T__.Out("likes"), gremlingo.T__.Out("knows"), gremlingo.T__.Out("created")).GroupCount().By("name")}}, 
     "g_V_coalesceXoutEXknowsX_outEXcreatedXX_otherV_path_byXnameX_byXlabelX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Coalesce(gremlingo.T__.OutE("knows"), gremlingo.T__.OutE("created")).OtherV().Path().By("name").By(gremlingo.T.Label)}}, 
     "g_V_outXcreatedX_order_byXnameX_coalesceXname_constantXxXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out("created").Order().By("name").Coalesce(gremlingo.T__.Values("name"), gremlingo.T__.Constant("x"))}}, 
+    "g_injectXnullX_combineXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Combine()}}, 
+    "g_V_valuesXnameX_combineXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Combine()}}, 
+    "g_V_fold_combineXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Combine()}}, 
+    "g_V_fold_combineXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Combine()}}, 
+    "g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Combine()}}, 
+    "g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Combine()}}, 
+    "g_V_valuesXageX_order_byXdescX_fold_combineXV_valuesXageX_order_byXdescX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().By(gremlingo.Order.Desc).Fold().Combine()}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_combineXMARKOX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Combine()}}, 
+    "g_injectXxx1X_combineXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Combine()}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_combineXseattle_vancouverX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Combine()}}, 
+    "g_V_out_out_path_byXnameX_combineXempty_listX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Combine()}}, 
+    "g_V_valuesXageX_fold_combineXconstantX27X_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Combine()}}, 
+    "g_V_out_out_path_byXnameX_combineXdave_kelvinX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Combine()}}, 
+    "g_injectXa_null_bX_combineXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Combine()}}, 
+    "g_injectXa_null_bX_combineXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Combine()}}, 
+    "g_injectX3_threeX_combineXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Combine()}}, 
     "g_injectXa_bX_concat": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("a", "b").Concat()}}, 
     "g_injectXa_bX_concat_XcX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("a", "b").Concat("c")}}, 
     "g_injectXa_bX_concat_Xc_dX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("a", "b").Concat("c", "d")}}, 
@@ -577,6 +593,38 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_injectXdatetimeXstrXX_dateAddXday_11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(time.UnixMilli(1693958400000)).DateAdd(gremlingo.DT.Day, 11)}}, 
     "g_injectXdatetimeXstr1XX_dateDiffXdatetimeXstr2XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(time.UnixMilli(1690934400000)).DateDiff(time.UnixMilli(1691539200000))}}, 
     "g_injectXdatetimeXstr1XX_dateDiffXinjectXdatetimeXstr2XXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(time.UnixMilli(1691452800000)).DateDiff(gremlingo.T__.Inject(time.UnixMilli(1690848000000)))}}, 
+    "g_injectXnullX_differenceXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Difference()}}, 
+    "g_V_valuesXnameX_differenceXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Difference()}}, 
+    "g_V_fold_differenceXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Difference()}}, 
+    "g_V_fold_differenceXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Difference()}}, 
+    "g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Difference()}}, 
+    "g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Difference()}}, 
+    "g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Difference()}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_differenceXMARKOX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Difference()}}, 
+    "g_injectXmarkoX_differenceXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Difference()}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_differenceXseattle_vancouverX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Difference()}}, 
+    "g_V_out_out_path_byXnameX_differenceXrippleX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Difference()}}, 
+    "g_V_out_out_path_byXnameX_differenceXempty_listX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Difference()}}, 
+    "g_V_valuesXageX_fold_differenceXconstantX27X_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Difference()}}, 
+    "g_V_out_out_path_byXnameX_differenceXdave_kelvinX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Difference()}}, 
+    "g_injectXa_null_bX_differenceXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Difference()}}, 
+    "g_injectXa_null_bX_differenceXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Difference()}}, 
+    "g_injectX3_threeX_differenceXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Difference()}}, 
+    "g_injectXnullX_disjunctXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Disjunct()}}, 
+    "g_V_valuesXnameX_disjunctXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Disjunct()}}, 
+    "g_V_fold_disjunctXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Disjunct()}}, 
+    "g_V_fold_disjunctXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Disjunct()}}, 
+    "g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Disjunct()}}, 
+    "g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Disjunct()}}, 
+    "g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Disjunct()}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_disjunctXMARKOX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Disjunct()}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_disjunctXseattle_vancouverX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Disjunct()}}, 
+    "g_V_out_out_path_byXnameX_disjunctXmarkoX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Disjunct()}}, 
+    "g_V_out_out_path_byXnameX_disjunctXstephen_markoX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Disjunct()}}, 
+    "g_V_out_out_path_byXnameX_disjunctXdave_kelvinX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Disjunct()}}, 
+    "g_injectXa_null_bX_disjunctXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct()}}, 
+    "g_injectXa_null_bX_disjunctXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct()}}, 
+    "g_injectX3_threeX_disjunctXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct()}}, 
     "g_V_EX11X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().E(p["eid11"])}}, 
     "g_EX11X_E": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E(p["eid11"]).E()}}, 
     "g_V_EXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().E(nil)}}, 
@@ -609,10 +657,31 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_V_hasLabelXsoftwareX_name_fold_orderXlocalX_index_unfold_order_byXtailXlocal_1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("software").Values("name").Fold().Order(gremlingo.Scope.Local).Index().Unfold().Order().By(gremlingo.T__.Tail(gremlingo.Scope.Local, 1))}}, 
     "g_V_hasLabelXpersonX_name_fold_orderXlocalX_index_withXmapX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("person").Values("name").Fold().Order(gremlingo.Scope.Local).Index().With("~tinkerpop.index.indexer", 1)}}, 
     "g_VX1X_valuesXageX_index_unfold_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Values("age").Index().Unfold().Unfold()}}, 
-    "g_injectX__feature___test__nullX_lTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("  feature", " one test", nil, "", " ").LTrim()}}, 
-    "g_injectX__feature__X_lTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("  feature  ").LTrim()}}, 
-    "g_injectXListXa_bXX_lTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).LTrim()}}, 
-    "g_V_valuesXnameX_lTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", " marko ").Property("age", 29).As("marko").AddV("person").Property("name", "  vadas  ").Property("age", 27).As("vadas").AddV("software").Property("name", "  lop").Property("lang", "java").As("lop").AddV("person").Property("name", "josh  ").Property("age", 32).As("josh").AddV("software").Property("name", "   ripple   ").Proper [...]
+    "g_injectXnullX_intersectXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Intersect()}}, 
+    "g_V_valuesXnameX_intersectXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Intersect()}}, 
+    "g_V_fold_intersectXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Intersect()}}, 
+    "g_V_fold_intersectXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Intersect()}}, 
+    "g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Intersect()}}, 
+    "g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Intersect()}}, 
+    "g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Intersect()}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_intersectXMARKOX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Intersect()}}, 
+    "g_injectXmarkoX_intersectX___V_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Intersect()}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_intersectXseattle_vancouverX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Intersect()}}, 
+    "g_V_valuesXageX_fold_intersectX___constantX27X_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Intersect()}}, 
+    "g_V_out_out_path_byXnameX_intersectXdave_kelvinX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Intersect()}}, 
+    "g_injectXa_null_bX_intersectXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Intersect()}}, 
+    "g_injectXa_null_bX_intersectXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Intersect()}}, 
+    "g_injectX3_threeX_intersectXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Intersect()}}, 
+    "g_injectXnullX_joinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Join()}}, 
+    "g_V_valuesXnameX_joinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Join()}}, 
+    "g_V_valuesXnonexistantX_fold_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Join()}}, 
+    "g_V_valuesXnameX_fold_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Join()}}, 
+    "g_V_valuesXageX_order_fold_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().Fold().Join()}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Join()}}, 
+    "g_injectXxx1X_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Join()}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Join()}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Join()}}, 
+    "g_V_out_out_path_byXnameX_joinXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Join()}}, 
+    "g_injectXxx1X_joinXxyzX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Join()}}, 
     "g_injectXfeature_test_nullX_length": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("feature", "test", nil).Length()}}, 
     "g_injectXListXa_bXX_length": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Length()}}, 
     "g_V_valuesXnameX_length": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Length()}}, 
@@ -620,6 +689,10 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_VX1X_repeatXboth_simplePathX_untilXhasXname_peterX_or_loops_isX2XX_hasXname_peterX_path_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Repeat(gremlingo.T__.Both().SimplePath()).Until(gremlingo.T__.Has("name", "peter").Or().Loops().Is(2)).Has("name", "peter").Path().By("name")}}, 
     "g_VX1X_repeatXboth_simplePathX_untilXhasXname_peterX_and_loops_isX3XX_hasXname_peterX_path_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Repeat(gremlingo.T__.Both().SimplePath()).Until(gremlingo.T__.Has("name", "peter").And().Loops().Is(3)).Has("name", "peter").Path().By("name")}}, 
     "g_V_emitXhasXname_markoX_or_loops_isX2XX_repeatXoutX_valuesXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Emit(gremlingo.T__.Has("name", "marko").Or().Loops().Is(2)).Repeat(gremlingo.T__.Out()).Values("name")}}, 
+    "g_injectX__feature___test__nullX_lTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("  feature", " one test", nil, "", " ").LTrim()}}, 
+    "g_injectX__feature__X_lTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("  feature  ").LTrim()}}, 
+    "g_injectXListXa_bXX_lTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).LTrim()}}, 
+    "g_V_valuesXnameX_lTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", " marko ").Property("age", 29).As("marko").AddV("person").Property("name", "  vadas  ").Property("age", 27).As("vadas").AddV("software").Property("name", "  lop").Property("lang", "java").As("lop").AddV("person").Property("name", "josh  ").Property("age", 32).As("josh").AddV("software").Property("name", "   ripple   ").Proper [...]
     "g_VX1X_mapXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Map(p["l1"])}}, 
     "g_VX1X_outE_label_mapXlengthX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).OutE().Label().Map(p["l1"])}}, 
     "g_VX1X_out_mapXnameX_mapXlengthX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Out().Map(p["l1"]).Map(p["l2"])}}, 
@@ -706,6 +779,27 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_injectXnull_10_20_nullX_mean": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil, p["xx1"], p["xx2"], nil).Mean()}}, 
     "g_injectXlistXnull_10_20_nullXX_meanXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Mean(gremlingo.Scope.Local)}}, 
     "g_VX1X_valuesXageX_meanXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Values("age").Mean(gremlingo.Scope.Local)}}, 
+    "g_injectXnullX_mergeXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Merge()}}, 
+    "g_V_valuesXnameX_mergeXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Merge()}}, 
+    "g_V_fold_mergeXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Merge()}}, 
+    "g_V_fold_mergeXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Merge()}}, 
+    "g_V_elementMap_mergeXconstantXaXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ElementMap().Merge()}}, 
+    "g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Merge()}}, 
+    "g_V_fold_mergeXk_vX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Merge()}}, 
+    "g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Merge()}}, 
+    "g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Merge()}}, 
+    "g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Merge()}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_mergeXMARKOX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Merge()}}, 
+    "g_injectXmarkoX_mergeXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Merge()}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_mergeXseattle_vancouverX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Merge()}}, 
+    "g_V_out_out_path_byXnameX_mergeXempty_listX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Merge()}}, 
+    "g_V_valuesXageX_fold_mergeXconstantX27X_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Merge()}}, 
+    "g_V_out_out_path_byXnameX_mergeXdave_kelvinX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Merge()}}, 
+    "g_injectXa_null_bX_mergeXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Merge()}}, 
+    "g_injectXa_null_bX_mergeXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Merge()}}, 
+    "g_injectX3_threeX_mergeXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Merge()}}, 
+    "g_V_asXnameX_projectXnameX_byXnameX_mergeXother_blueprintX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("name").Project("name").By("name").Merge()}}, 
+    "g_V_hasXname_markoX_elementMap_mergeXV_hasXname_lopX_elementMapX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", "marko").ElementMap().Merge()}}, 
     "g_V_mergeEXlabel_selfX_optionXonMatch_emptyX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property("age", 29).AddE("self")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().MergeE(p["xx1"]).Option(gremlingo.Merge.OnMatch, map[interface{}]interface{}{})}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremli [...]
     "g_V_mergeEXlabel_selfX_optionXonMatch_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property("age", 29).AddE("self")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().MergeE(p["xx1"]).Option(gremlingo.Merge.OnMatch, nil)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return  [...]
     "g_V_mergeEXemptyX_optionXonCreate_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property("age", 29)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("v").MergeE(p["xx1"]).Option(gremlingo.Merge.OnCreate, nil).Option(gremlingo.Merge.OutV, gremlingo.T__.Select("v")).Option(gremlingo.Merge.InV, gremlingo.T__.Select("v")) [...]
@@ -872,6 +966,21 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_V_peerPressure_hasXclusterX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().PeerPressure().Has("gremlin.peerPressureVertexProgram.cluster")}}, 
     "g_V_peerPressure_withXpropertyName_clusterX_withXedges_outEXknowsXX_pageRankX1X_byXrankX_withXedges_outEXknowsX_withXtimes_2X_group_byXclusterX_byXrank_sumX_limitX100X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().PeerPressure().With("~tinkerpop.peerPressure.propertyName", "cluster").With("~tinkerpop.peerPressure.edges", gremlingo.T__.OutE("knows")).PageRank(1.0).With("~tinkerpop.pageRank.propertyName", "rank").With("~ti [...]
     "g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withyXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", "ripple").In("created").PeerPressure().With("~tinkerpop.peerPressure.edges", gremlingo.T__.OutE()).With("~tinkerpop.peerPressure.propertyName", "cluster").Repeat(gremlingo.T__.Union(gremlingo.T__.Identity(),  [...]
+    "g_injectXnullX_productXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Product()}}, 
+    "g_V_valuesXnameX_productXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Product()}}, 
+    "g_V_fold_productXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Product()}}, 
+    "g_V_fold_productXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Product()}}, 
+    "g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Product()}}, 
+    "g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Product()}}, 
+    "g_V_valuesXageX_order_byXdescX_limitX3X_fold_productXV_valuesXageX_order_byXascX_limitX2X_foldX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().By(gremlingo.Order.Desc).Limit(3).Fold().Product().Unfold()}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_productXMARKOX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Product().Unfold()}}, 
+    "g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Product().Unfold()}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_productXdulles_seattle_vancouverX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Product().Unfold()}}, 
+    "g_V_valuesXageX_order_byXascX_fold_productXconstantX27X_foldX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().By(gremlingo.Order.Asc).Fold().Product().Unfold()}}, 
+    "g_V_out_out_path_byXnameX_productXdave_kelvinX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Product().Unfold()}}, 
+    "g_injectXa_null_bX_productXa_cX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Product().Unfold()}}, 
+    "g_injectXa_null_bX_productXa_null_cX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Product().Unfold()}}, 
+    "g_injectX3_threeX_productXfive_three_7X_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Product().Unfold()}}, 
     "g_V_hasLabelXpersonX_projectXa_bX_byXoutE_countX_byXageX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("person").Project("a", "b").By(gremlingo.T__.OutE().Count()).By("age")}}, 
     "g_V_outXcreatedX_projectXa_bX_byXnameX_byXinXcreatedX_countX_order_byXselectXbX__descX_selectXaX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out("created").Project("a", "b").By("name").By(gremlingo.T__.In("created").Count()).Order().By(gremlingo.T__.Select("b"), gremlingo.Order.Desc).Select("a")}}, 
     "g_V_valueMap_projectXxX_byXselectXnameXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap().Project("x").By(gremlingo.T__.Select("name"))}}, 
@@ -882,17 +991,24 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_V_hasXageX_propertiesXage_nameX_value": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("age").Properties("age", "name").Value()}}, 
     "g_V_propertiesXname_age_nullX_value": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Properties("name", "age", nil).Value()}}, 
     "g_V_valuesXname_age_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name", "age", nil)}}, 
-    "g_injectX__feature___test__nullX_rTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("feature  ", "one test ", nil, "", " ").RTrim()}}, 
-    "g_injectX__feature__X_rTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("  feature  ").RTrim()}}, 
-    "g_injectXListXa_bXX_rTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).RTrim()}}, 
-    "g_V_valuesXnameX_rTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", " marko ").Property("age", 29).As("marko").AddV("person").Property("name", "  vadas  ").Property("age", 27).As("vadas").AddV("software").Property("name", "  lop").Property("lang", "java").As("lop").AddV("person").Property("name", "josh  ").Property("age", 32).As("josh").AddV("software").Property("name", "   ripple   ").Proper [...]
     "g_injectXthat_this_testX_replaceXh_jX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("that", "this", "test", nil).Replace("h", "j")}}, 
     "g_injectXListXa_bXcX_replaceXa_bX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Replace("a", "b")}}, 
     "g_V_hasLabelXsoftwareX_valueXnameX_replaceXnull_iX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("software").Values("name").Replace(nil, "g")}}, 
     "g_V_hasLabelXsoftwareX_valueXnameX_replaceXa_iX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("software").Values("name").Replace("p", "g")}}, 
     "g_injectXfeature_test_nullX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("feature", "test one", nil).Reverse()}}, 
-    "g_injectXListXa_bXX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Reverse()}}, 
     "g_V_valuesXnameX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Reverse()}}, 
+    "g_V_valuesXageX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Reverse()}}, 
+    "g_V_out_path_byXnameX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By("name").Reverse()}}, 
+    "g_V_out_out_path_byXnameX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Reverse()}}, 
+    "g_V_valuesXageX_fold_orderXlocalX_byXdescX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Order(gremlingo.Scope.Local).By(gremlingo.Order.Desc).Reverse()}}, 
+    "g_V_valuesXnameX_fold_orderXlocalX_by_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Order(gremlingo.Scope.Local).By().Reverse()}}, 
+    "g_injectXnullX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Reverse()}}, 
+    "g_injectXbX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("b").Reverse()}}, 
+    "g_injectX3_threeX_reverse": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Reverse()}}, 
+    "g_injectX__feature___test__nullX_rTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("feature  ", "one test ", nil, "", " ").RTrim()}}, 
+    "g_injectX__feature__X_rTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("  feature  ").RTrim()}}, 
+    "g_injectXListXa_bXX_rTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).RTrim()}}, 
+    "g_V_valuesXnameX_rTrim": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", " marko ").Property("age", 29).As("marko").AddV("person").Property("name", "  vadas  ").Property("age", 27).As("vadas").AddV("software").Property("name", "  lop").Property("lang", "java").As("lop").AddV("person").Property("name", "josh  ").Property("age", 32).As("josh").AddV("software").Property("name", "   ripple   ").Proper [...]
     "g_VX1X_asXaX_outXknowsX_asXbX_selectXa_bX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).As("a").Out("knows").As("b").Select("a", "b")}}, 
     "g_VX1X_asXaX_outXknowsX_asXbX_selectXa_bX_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).As("a").Out("knows").As("b").Select("a", "b").By("name")}}, 
     "g_VX1X_asXaX_outXknowsX_asXbX_selectXaX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).As("a").Out("knows").As("b").Select("a")}}, 
diff --git a/gremlin-go/driver/graphTraversal.go b/gremlin-go/driver/graphTraversal.go
index ec85578b0a..ed287c5453 100644
--- a/gremlin-go/driver/graphTraversal.go
+++ b/gremlin-go/driver/graphTraversal.go
@@ -185,6 +185,12 @@ func (g *GraphTraversal) Coin(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Combine adds the combine step to the GraphTraversal.
+func (g *GraphTraversal) Combine(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("combine", args...)
+	return g
+}
+
 // Concat adds the concat step to the GraphTraversal.
 func (g *GraphTraversal) Concat(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("concat", args...)
@@ -234,6 +240,18 @@ func (g *GraphTraversal) Dedup(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Difference adds the difference step to the GraphTraversal.
+func (g *GraphTraversal) Difference(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("difference", args...)
+	return g
+}
+
+// Disjunct adds the disjunct step to the GraphTraversal.
+func (g *GraphTraversal) Disjunct(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("disjunct", args...)
+	return g
+}
+
 // Drop adds the drop step to the GraphTraversal.
 func (g *GraphTraversal) Drop(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("drop", args...)
@@ -379,12 +397,25 @@ func (g *GraphTraversal) Inject(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Intersect adds the intersect step to the GraphTraversal.
+func (g *GraphTraversal) Intersect(args ...interface{}) *GraphTraversal {
+	// Force int32 serialization for valid number values for server compatibility
+	g.Bytecode.AddStep("intersect", args...)
+	return g
+}
+
 // Is adds the is step to the GraphTraversal.
 func (g *GraphTraversal) Is(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("is", args...)
 	return g
 }
 
+// Join adds the join step to the GraphTraversal.
+func (g *GraphTraversal) Join(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("join", args...)
+	return g
+}
+
 // Key adds the key step to the GraphTraversal.
 func (g *GraphTraversal) Key(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("key", args...)
@@ -457,6 +488,12 @@ func (g *GraphTraversal) Mean(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Merge adds the merge step to the GraphTraversal.
+func (g *GraphTraversal) Merge(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("merge", args...)
+	return g
+}
+
 // MergeE adds the mergeE step to the GraphTraversal.
 func (g *GraphTraversal) MergeE(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("mergeE", args...)
@@ -553,6 +590,12 @@ func (g *GraphTraversal) PeerPressure(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Product adds the product step to the GraphTraversal.
+func (g *GraphTraversal) Product(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("product", args...)
+	return g
+}
+
 // Profile adds the profile step to the GraphTraversal.
 func (g *GraphTraversal) Profile(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("profile", args...)
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 d6ebf0f273..2bb33443ae 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
@@ -583,6 +583,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal combine method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  combine(...args) {
+    this.bytecode.addStep('combine', args);
+    return this;
+  }
+
   /**
    * Graph traversal concat method.
    * @param {...Object} args
@@ -663,6 +673,26 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal difference method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  difference(...args) {
+    this.bytecode.addStep('difference', args);
+    return this;
+  }
+
+  /**
+   * Graph traversal disjunct method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  disjunct(...args) {
+    this.bytecode.addStep('disjunct', args);
+    return this;
+  }
+
   /**
    * Graph traversal drop method.
    * @param {...Object} args
@@ -902,6 +932,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal intersect method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  intersect(...args) {
+    this.bytecode.addStep('intersect', args);
+    return this;
+  }
+
   /**
    * Graph traversal is method.
    * @param {...Object} args
@@ -912,6 +952,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal join method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  join(...args) {
+    this.bytecode.addStep('join', args);
+    return this;
+  }
+
   /**
    * Graph traversal key method.
    * @param {...Object} args
@@ -1032,6 +1082,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal merge method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  merge(...args) {
+    this.bytecode.addStep('merge', args);
+    return this;
+  }
+
   /**
    * Graph traversal mergeE method.
    * @param {...Object} args
@@ -1192,6 +1252,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal product method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  product(...args) {
+    this.bytecode.addStep('product', args);
+    return this;
+  }
+
   /**
    * Graph traversal profile method.
    * @param {...Object} args
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index 4bed5125c3..a431ab2c82 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -555,6 +555,22 @@ const gremlins = {
     g_V_coalesceXoutXlikesX_outXknowsX_inXcreatedXX_groupCount_byXnameX: [function({g}) { return g.V().coalesce(__.out("likes"),__.out("knows"),__.out("created")).groupCount().by("name") }], 
     g_V_coalesceXoutEXknowsX_outEXcreatedXX_otherV_path_byXnameX_byXlabelX: [function({g}) { return g.V().coalesce(__.outE("knows"),__.outE("created")).otherV().path().by("name").by(T.label) }], 
     g_V_outXcreatedX_order_byXnameX_coalesceXname_constantXxXX: [function({g}) { return g.V().out("created").order().by("name").coalesce(__.values("name"),__.constant("x")) }], 
+    g_injectXnullX_combineXinjectX1XX: [function({g}) { return g.inject(null).combine() }], 
+    g_V_valuesXnameX_combineXV_foldX: [function({g}) { return g.V().values("name").combine() }], 
+    g_V_fold_combineXconstantXnullXX: [function({g}) { return g.V().fold().combine() }], 
+    g_V_fold_combineXVX: [function({g}) { return g.V().fold().combine() }], 
+    g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().combine() }], 
+    g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().combine() }], 
+    g_V_valuesXageX_order_byXdescX_fold_combineXV_valuesXageX_order_byXdescX_foldX: [function({g}) { return g.V().values("age").order().by(Order.desc).fold().combine() }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_combineXMARKOX: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).combine() }], 
+    g_injectXxx1X_combineXV_valuesXnameX_foldX: [function({g, xx1}) { return g.inject(xx1).combine() }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_combineXseattle_vancouverX: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().combine() }], 
+    g_V_out_out_path_byXnameX_combineXempty_listX: [function({g}) { return g.V().out().out().path().by("name").combine() }], 
+    g_V_valuesXageX_fold_combineXconstantX27X_foldX: [function({g}) { return g.V().values("age").fold().combine() }], 
+    g_V_out_out_path_byXnameX_combineXdave_kelvinX: [function({g}) { return g.V().out().out().path().by("name").combine() }], 
+    g_injectXa_null_bX_combineXa_cX: [function({g, xx1}) { return g.inject(xx1).combine() }], 
+    g_injectXa_null_bX_combineXa_null_cX: [function({g, xx1}) { return g.inject(xx1).combine() }], 
+    g_injectX3_threeX_combineXfive_three_7X: [function({g, xx1}) { return g.inject(xx1).combine() }], 
     g_injectXa_bX_concat: [function({g}) { return g.inject("a","b").concat() }], 
     g_injectXa_bX_concat_XcX: [function({g}) { return g.inject("a","b").concat("c") }], 
     g_injectXa_bX_concat_Xc_dX: [function({g}) { return g.inject("a","b").concat("c","d") }], 
@@ -597,6 +613,38 @@ const gremlins = {
     g_injectXdatetimeXstrXX_dateAddXday_11X: [function({g}) { return g.inject(new Date(1693958400000)).dateAdd(DT.day,11) }], 
     g_injectXdatetimeXstr1XX_dateDiffXdatetimeXstr2XX: [function({g}) { return g.inject(new Date(1690934400000)).dateDiff(new Date(1691539200000)) }], 
     g_injectXdatetimeXstr1XX_dateDiffXinjectXdatetimeXstr2XXX: [function({g}) { return g.inject(new Date(1691452800000)).dateDiff(__.inject(new Date(1690848000000))) }], 
+    g_injectXnullX_differenceXinjectX1XX: [function({g}) { return g.inject(null).difference() }], 
+    g_V_valuesXnameX_differenceXV_foldX: [function({g}) { return g.V().values("name").difference() }], 
+    g_V_fold_differenceXconstantXnullXX: [function({g}) { return g.V().fold().difference() }], 
+    g_V_fold_differenceXVX: [function({g}) { return g.V().fold().difference() }], 
+    g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().difference() }], 
+    g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().difference() }], 
+    g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX: [function({g}) { return g.V().values("age").fold().difference() }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_differenceXMARKOX: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).difference() }], 
+    g_injectXmarkoX_differenceXV_valuesXnameX_foldX: [function({g, xx1}) { return g.inject(xx1).difference() }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_differenceXseattle_vancouverX: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().difference() }], 
+    g_V_out_out_path_byXnameX_differenceXrippleX: [function({g}) { return g.V().out().out().path().by("name").difference() }], 
+    g_V_out_out_path_byXnameX_differenceXempty_listX: [function({g}) { return g.V().out().out().path().by("name").difference() }], 
+    g_V_valuesXageX_fold_differenceXconstantX27X_foldX: [function({g}) { return g.V().values("age").fold().difference() }], 
+    g_V_out_out_path_byXnameX_differenceXdave_kelvinX: [function({g}) { return g.V().out().out().path().by("name").difference() }], 
+    g_injectXa_null_bX_differenceXa_cX: [function({g, xx1}) { return g.inject(xx1).difference() }], 
+    g_injectXa_null_bX_differenceXa_null_cX: [function({g, xx1}) { return g.inject(xx1).difference() }], 
+    g_injectX3_threeX_differenceXfive_three_7X: [function({g, xx1}) { return g.inject(xx1).difference() }], 
+    g_injectXnullX_disjunctXinjectX1XX: [function({g}) { return g.inject(null).disjunct() }], 
+    g_V_valuesXnameX_disjunctXV_foldX: [function({g}) { return g.V().values("name").disjunct() }], 
+    g_V_fold_disjunctXconstantXnullXX: [function({g}) { return g.V().fold().disjunct() }], 
+    g_V_fold_disjunctXVX: [function({g}) { return g.V().fold().disjunct() }], 
+    g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().disjunct() }], 
+    g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().disjunct() }], 
+    g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX: [function({g}) { return g.V().values("age").fold().disjunct() }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_disjunctXMARKOX: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).disjunct() }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_disjunctXseattle_vancouverX: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().disjunct() }], 
+    g_V_out_out_path_byXnameX_disjunctXmarkoX: [function({g}) { return g.V().out().out().path().by("name").disjunct() }], 
+    g_V_out_out_path_byXnameX_disjunctXstephen_markoX: [function({g}) { return g.V().out().out().path().by("name").disjunct() }], 
+    g_V_out_out_path_byXnameX_disjunctXdave_kelvinX: [function({g}) { return g.V().out().out().path().by("name").disjunct() }], 
+    g_injectXa_null_bX_disjunctXa_cX: [function({g, xx1}) { return g.inject(xx1).disjunct() }], 
+    g_injectXa_null_bX_disjunctXa_null_cX: [function({g, xx1}) { return g.inject(xx1).disjunct() }], 
+    g_injectX3_threeX_disjunctXfive_three_7X: [function({g, xx1}) { return g.inject(xx1).disjunct() }], 
     g_V_EX11X: [function({g, eid11}) { return g.V().E(eid11) }], 
     g_EX11X_E: [function({g, eid11}) { return g.E(eid11).E() }], 
     g_V_EXnullX: [function({g}) { return g.V().E(null) }], 
@@ -629,10 +677,31 @@ const gremlins = {
     g_V_hasLabelXsoftwareX_name_fold_orderXlocalX_index_unfold_order_byXtailXlocal_1XX: [function({g}) { return g.V().hasLabel("software").values("name").fold().order(Scope.local).index().unfold().order().by(__.tail(Scope.local,1)) }], 
     g_V_hasLabelXpersonX_name_fold_orderXlocalX_index_withXmapX: [function({g}) { return g.V().hasLabel("person").values("name").fold().order(Scope.local).index().with_("~tinkerpop.index.indexer",1) }], 
     g_VX1X_valuesXageX_index_unfold_unfold: [function({g, vid1}) { return g.V(vid1).values("age").index().unfold().unfold() }], 
-    g_injectX__feature___test__nullX_lTrim: [function({g}) { return g.inject("  feature"," one test",null,""," ").lTrim() }], 
-    g_injectX__feature__X_lTrim: [function({g}) { return g.inject("  feature  ").lTrim() }], 
-    g_injectXListXa_bXX_lTrim: [function({g, xx1}) { return g.inject(xx1).lTrim() }], 
-    g_V_valuesXnameX_lTrim: [function({g}) { return g.addV("person").property("name"," marko ").property("age",29).as("marko").addV("person").property("name","  vadas  ").property("age",27).as("vadas").addV("software").property("name","  lop").property("lang","java").as("lop").addV("person").property("name","josh  ").property("age",32).as("josh").addV("software").property("name","   ripple   ").property("lang","java").as("ripple").addV("person").property("name","peter").property("age",35 [...]
+    g_injectXnullX_intersectXinjectX1XX: [function({g}) { return g.inject(null).intersect() }], 
+    g_V_valuesXnameX_intersectXV_foldX: [function({g}) { return g.V().values("name").intersect() }], 
+    g_V_fold_intersectXconstantXnullXX: [function({g}) { return g.V().fold().intersect() }], 
+    g_V_fold_intersectXVX: [function({g}) { return g.V().fold().intersect() }], 
+    g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().intersect() }], 
+    g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().intersect() }], 
+    g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX: [function({g}) { return g.V().values("age").fold().intersect() }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_intersectXMARKOX: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).intersect() }], 
+    g_injectXmarkoX_intersectX___V_valuesXnameX_foldX: [function({g, xx1}) { return g.inject(xx1).intersect() }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_intersectXseattle_vancouverX: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().intersect() }], 
+    g_V_valuesXageX_fold_intersectX___constantX27X_foldX: [function({g}) { return g.V().values("age").fold().intersect() }], 
+    g_V_out_out_path_byXnameX_intersectXdave_kelvinX: [function({g}) { return g.V().out().out().path().by("name").intersect() }], 
+    g_injectXa_null_bX_intersectXa_cX: [function({g, xx1}) { return g.inject(xx1).intersect() }], 
+    g_injectXa_null_bX_intersectXa_null_cX: [function({g, xx1}) { return g.inject(xx1).intersect() }], 
+    g_injectX3_threeX_intersectXfive_three_7X: [function({g, xx1}) { return g.inject(xx1).intersect() }], 
+    g_injectXnullX_joinX1X: [function({g}) { return g.inject(null).join() }], 
+    g_V_valuesXnameX_joinX1X: [function({g}) { return g.V().values("name").join() }], 
+    g_V_valuesXnonexistantX_fold_joinX_X: [function({g}) { return g.V().values("nonexistant").fold().join() }], 
+    g_V_valuesXnameX_fold_joinX_X: [function({g}) { return g.V().values("name").fold().join() }], 
+    g_V_valuesXageX_order_fold_joinX_X: [function({g}) { return g.V().values("age").order().fold().join() }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).join() }], 
+    g_injectXxx1X_joinX_X: [function({g, xx1}) { return g.inject(xx1).join() }, function({g, xx1}) { return g.inject(xx1).join() }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().join() }], 
+    g_V_out_out_path_byXnameX_joinXX: [function({g}) { return g.V().out().out().path().by("name").join() }], 
+    g_injectXxx1X_joinXxyzX: [function({g, xx1}) { return g.inject(xx1).join() }], 
     g_injectXfeature_test_nullX_length: [function({g}) { return g.inject("feature","test",null).length() }], 
     g_injectXListXa_bXX_length: [function({g, xx1}) { return g.inject(xx1).length() }], 
     g_V_valuesXnameX_length: [function({g}) { return g.V().values("name").length() }], 
@@ -640,6 +709,10 @@ const gremlins = {
     g_VX1X_repeatXboth_simplePathX_untilXhasXname_peterX_or_loops_isX2XX_hasXname_peterX_path_byXnameX: [function({g, vid1}) { return g.V(vid1).repeat(__.both().simplePath()).until(__.has("name","peter").or().loops().is(2)).has("name","peter").path().by("name") }], 
     g_VX1X_repeatXboth_simplePathX_untilXhasXname_peterX_and_loops_isX3XX_hasXname_peterX_path_byXnameX: [function({g, vid1}) { return g.V(vid1).repeat(__.both().simplePath()).until(__.has("name","peter").and().loops().is(3)).has("name","peter").path().by("name") }], 
     g_V_emitXhasXname_markoX_or_loops_isX2XX_repeatXoutX_valuesXnameX: [function({g}) { return g.V().emit(__.has("name","marko").or().loops().is(2)).repeat(__.out()).values("name") }], 
+    g_injectX__feature___test__nullX_lTrim: [function({g}) { return g.inject("  feature"," one test",null,""," ").lTrim() }], 
+    g_injectX__feature__X_lTrim: [function({g}) { return g.inject("  feature  ").lTrim() }], 
+    g_injectXListXa_bXX_lTrim: [function({g, xx1}) { return g.inject(xx1).lTrim() }], 
+    g_V_valuesXnameX_lTrim: [function({g}) { return g.addV("person").property("name"," marko ").property("age",29).as("marko").addV("person").property("name","  vadas  ").property("age",27).as("vadas").addV("software").property("name","  lop").property("lang","java").as("lop").addV("person").property("name","josh  ").property("age",32).as("josh").addV("software").property("name","   ripple   ").property("lang","java").as("ripple").addV("person").property("name","peter").property("age",35 [...]
     g_VX1X_mapXnameX: [function({g, l1, vid1}) { return g.V(vid1).map(l1) }], 
     g_VX1X_outE_label_mapXlengthX: [function({g, l1, vid1}) { return g.V(vid1).outE().label().map(l1) }], 
     g_VX1X_out_mapXnameX_mapXlengthX: [function({g, l1, l2, vid1}) { return g.V(vid1).out().map(l1).map(l2) }], 
@@ -726,6 +799,27 @@ const gremlins = {
     g_injectXnull_10_20_nullX_mean: [function({g, xx1, xx2}) { return g.inject(null,xx1,xx2,null).mean() }], 
     g_injectXlistXnull_10_20_nullXX_meanXlocalX: [function({g, xx1}) { return g.inject(xx1).mean(Scope.local) }], 
     g_VX1X_valuesXageX_meanXlocalX: [function({g, vid1}) { return g.V(vid1).values("age").mean(Scope.local) }], 
+    g_injectXnullX_mergeXinjectX1XX: [function({g}) { return g.inject(null).merge() }], 
+    g_V_valuesXnameX_mergeXV_foldX: [function({g}) { return g.V().values("name").merge() }], 
+    g_V_fold_mergeXconstantXnullXX: [function({g}) { return g.V().fold().merge() }], 
+    g_V_fold_mergeXVX: [function({g}) { return g.V().fold().merge() }], 
+    g_V_elementMap_mergeXconstantXaXX: [function({g}) { return g.V().elementMap().merge() }], 
+    g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX: [function({g}) { return g.V().fold().merge() }], 
+    g_V_fold_mergeXk_vX: [function({g}) { return g.V().fold().merge() }], 
+    g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().merge() }], 
+    g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().merge() }], 
+    g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX: [function({g}) { return g.V().values("age").fold().merge() }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_mergeXMARKOX: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).merge() }], 
+    g_injectXmarkoX_mergeXV_valuesXnameX_foldX: [function({g, xx1}) { return g.inject(xx1).merge() }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_mergeXseattle_vancouverX: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().merge() }], 
+    g_V_out_out_path_byXnameX_mergeXempty_listX: [function({g}) { return g.V().out().out().path().by("name").merge() }], 
+    g_V_valuesXageX_fold_mergeXconstantX27X_foldX: [function({g}) { return g.V().values("age").fold().merge() }], 
+    g_V_out_out_path_byXnameX_mergeXdave_kelvinX: [function({g}) { return g.V().out().out().path().by("name").merge() }], 
+    g_injectXa_null_bX_mergeXa_cX: [function({g, xx1}) { return g.inject(xx1).merge() }], 
+    g_injectXa_null_bX_mergeXa_null_cX: [function({g, xx1}) { return g.inject(xx1).merge() }], 
+    g_injectX3_threeX_mergeXfive_three_7X: [function({g, xx1}) { return g.inject(xx1).merge() }], 
+    g_V_asXnameX_projectXnameX_byXnameX_mergeXother_blueprintX: [function({g}) { return g.V().as("name").project("name").by("name").merge() }], 
+    g_V_hasXname_markoX_elementMap_mergeXV_hasXname_lopX_elementMapX: [function({g}) { return g.V().has("name","marko").elementMap().merge() }], 
     g_V_mergeEXlabel_selfX_optionXonMatch_emptyX: [function({g, xx1}) { return g.addV("person").property("name","marko").property("age",29).addE("self") }, function({g, xx1}) { return g.V().mergeE(xx1).option(Merge.onMatch,new Map([])) }, function({g, xx1}) { return g.E() }, function({g, xx1}) { return g.E().properties() }, function({g, xx1}) { return g.V() }], 
     g_V_mergeEXlabel_selfX_optionXonMatch_nullX: [function({g, xx1}) { return g.addV("person").property("name","marko").property("age",29).addE("self") }, function({g, xx1}) { return g.V().mergeE(xx1).option(Merge.onMatch,null) }, function({g, xx1}) { return g.E() }, function({g, xx1}) { return g.E().properties() }, function({g, xx1}) { return g.V() }], 
     g_V_mergeEXemptyX_optionXonCreate_nullX: [function({g, xx1}) { return g.addV("person").property("name","marko").property("age",29) }, function({g, xx1}) { return g.V().as("v").mergeE(xx1).option(Merge.onCreate,null).option(Merge.outV,__.select("v")).option(Merge.inV,__.select("v")) }, function({g, xx1}) { return g.E() }, function({g, xx1}) { return g.V() }], 
@@ -892,6 +986,21 @@ const gremlins = {
     g_V_peerPressure_hasXclusterX: [function({g}) { return g.V().peerPressure().has("gremlin.peerPressureVertexProgram.cluster") }], 
     g_V_peerPressure_withXpropertyName_clusterX_withXedges_outEXknowsXX_pageRankX1X_byXrankX_withXedges_outEXknowsX_withXtimes_2X_group_byXclusterX_byXrank_sumX_limitX100X: [function({g}) { return g.V().peerPressure().with_("~tinkerpop.peerPressure.propertyName","cluster").with_("~tinkerpop.peerPressure.edges",__.outE("knows")).pageRank(1.0).with_("~tinkerpop.pageRank.propertyName","rank").with_("~tinkerpop.pageRank.edges",__.outE("knows")).with_("~tinkerpop.pageRank.times",1).group().by [...]
     g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withyXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX: [function({g}) { return g.V().has("name","ripple").in_("created").peerPressure().with_("~tinkerpop.peerPressure.edges",__.outE()).with_("~tinkerpop.peerPressure.propertyName","cluster").repeat(__.union(__.identity(),__.both())).times(2).dedup().valueMap("name","cluster") }], 
+    g_injectXnullX_productXinjectX1XX: [function({g}) { return g.inject(null).product() }], 
+    g_V_valuesXnameX_productXV_foldX: [function({g}) { return g.V().values("name").product() }], 
+    g_V_fold_productXconstantXnullXX: [function({g}) { return g.V().fold().product() }], 
+    g_V_fold_productXVX: [function({g}) { return g.V().fold().product() }], 
+    g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().product() }], 
+    g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().product() }], 
+    g_V_valuesXageX_order_byXdescX_limitX3X_fold_productXV_valuesXageX_order_byXascX_limitX2X_foldX_unfold: [function({g}) { return g.V().values("age").order().by(Order.desc).limit(3).fold().product().unfold() }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_productXMARKOX_unfold: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).product().unfold() }], 
+    g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold: [function({g, xx1}) { return g.inject(xx1).product().unfold() }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_productXdulles_seattle_vancouverX_unfold: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().product().unfold() }], 
+    g_V_valuesXageX_order_byXascX_fold_productXconstantX27X_foldX_unfold: [function({g}) { return g.V().values("age").order().by(Order.asc).fold().product().unfold() }], 
+    g_V_out_out_path_byXnameX_productXdave_kelvinX_unfold: [function({g}) { return g.V().out().out().path().by("name").product().unfold() }], 
+    g_injectXa_null_bX_productXa_cX_unfold: [function({g, xx1}) { return g.inject(xx1).product().unfold() }], 
+    g_injectXa_null_bX_productXa_null_cX_unfold: [function({g, xx1}) { return g.inject(xx1).product().unfold() }], 
+    g_injectX3_threeX_productXfive_three_7X_unfold: [function({g, xx1}) { return g.inject(xx1).product().unfold() }], 
     g_V_hasLabelXpersonX_projectXa_bX_byXoutE_countX_byXageX: [function({g}) { return g.V().hasLabel("person").project("a","b").by(__.outE().count()).by("age") }], 
     g_V_outXcreatedX_projectXa_bX_byXnameX_byXinXcreatedX_countX_order_byXselectXbX__descX_selectXaX: [function({g}) { return g.V().out("created").project("a","b").by("name").by(__.in_("created").count()).order().by(__.select("b"),Order.desc).select("a") }], 
     g_V_valueMap_projectXxX_byXselectXnameXX: [function({g}) { return g.V().valueMap().project("x").by(__.select("name")) }], 
@@ -902,17 +1011,24 @@ const gremlins = {
     g_V_hasXageX_propertiesXage_nameX_value: [function({g}) { return g.V().has("age").properties("age","name").value() }], 
     g_V_propertiesXname_age_nullX_value: [function({g}) { return g.V().properties("name","age",null).value() }], 
     g_V_valuesXname_age_nullX: [function({g}) { return g.V().values("name","age",null) }], 
-    g_injectX__feature___test__nullX_rTrim: [function({g}) { return g.inject("feature  ","one test ",null,""," ").rTrim() }], 
-    g_injectX__feature__X_rTrim: [function({g}) { return g.inject("  feature  ").rTrim() }], 
-    g_injectXListXa_bXX_rTrim: [function({g, xx1}) { return g.inject(xx1).rTrim() }], 
-    g_V_valuesXnameX_rTrim: [function({g}) { return g.addV("person").property("name"," marko ").property("age",29).as("marko").addV("person").property("name","  vadas  ").property("age",27).as("vadas").addV("software").property("name","  lop").property("lang","java").as("lop").addV("person").property("name","josh  ").property("age",32).as("josh").addV("software").property("name","   ripple   ").property("lang","java").as("ripple").addV("person").property("name","peter").property("age",35 [...]
     g_injectXthat_this_testX_replaceXh_jX: [function({g}) { return g.inject("that","this","test",null).replace("h","j") }], 
     g_injectXListXa_bXcX_replaceXa_bX: [function({g, xx1}) { return g.inject(xx1).replace("a","b") }], 
     g_V_hasLabelXsoftwareX_valueXnameX_replaceXnull_iX: [function({g}) { return g.V().hasLabel("software").values("name").replace(null,"g") }], 
     g_V_hasLabelXsoftwareX_valueXnameX_replaceXa_iX: [function({g}) { return g.V().hasLabel("software").values("name").replace("p","g") }], 
     g_injectXfeature_test_nullX_reverse: [function({g}) { return g.inject("feature","test one",null).reverse() }], 
-    g_injectXListXa_bXX_reverse: [function({g, xx1}) { return g.inject(xx1).reverse() }], 
     g_V_valuesXnameX_reverse: [function({g}) { return g.V().values("name").reverse() }], 
+    g_V_valuesXageX_reverse: [function({g}) { return g.V().values("age").reverse() }], 
+    g_V_out_path_byXnameX_reverse: [function({g}) { return g.V().out().path().by("name").reverse() }], 
+    g_V_out_out_path_byXnameX_reverse: [function({g}) { return g.V().out().out().path().by("name").reverse() }], 
+    g_V_valuesXageX_fold_orderXlocalX_byXdescX_reverse: [function({g}) { return g.V().values("age").fold().order(Scope.local).by(Order.desc).reverse() }], 
+    g_V_valuesXnameX_fold_orderXlocalX_by_reverse: [function({g}) { return g.V().values("name").fold().order(Scope.local).by().reverse() }], 
+    g_injectXnullX_reverse: [function({g}) { return g.inject(null).reverse() }], 
+    g_injectXbX_reverse: [function({g}) { return g.inject("b").reverse() }], 
+    g_injectX3_threeX_reverse: [function({g, xx1}) { return g.inject(xx1).reverse() }], 
+    g_injectX__feature___test__nullX_rTrim: [function({g}) { return g.inject("feature  ","one test ",null,""," ").rTrim() }], 
+    g_injectX__feature__X_rTrim: [function({g}) { return g.inject("  feature  ").rTrim() }], 
+    g_injectXListXa_bXX_rTrim: [function({g, xx1}) { return g.inject(xx1).rTrim() }], 
+    g_V_valuesXnameX_rTrim: [function({g}) { return g.addV("person").property("name"," marko ").property("age",29).as("marko").addV("person").property("name","  vadas  ").property("age",27).as("vadas").addV("software").property("name","  lop").property("lang","java").as("lop").addV("person").property("name","josh  ").property("age",32).as("josh").addV("software").property("name","   ripple   ").property("lang","java").as("ripple").addV("person").property("name","peter").property("age",35 [...]
     g_VX1X_asXaX_outXknowsX_asXbX_selectXa_bX: [function({g, vid1}) { return g.V(vid1).as("a").out("knows").as("b").select("a","b") }], 
     g_VX1X_asXaX_outXknowsX_asXbX_selectXa_bX_byXnameX: [function({g, vid1}) { return g.V(vid1).as("a").out("knows").as("b").select("a","b").by("name") }], 
     g_VX1X_asXaX_outXknowsX_asXbX_selectXaX: [function({g, vid1}) { return g.V(vid1).as("a").out("knows").as("b").select("a") }], 
diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 b/gremlin-language/src/main/antlr4/Gremlin.g4
index 8d08eb1676..1155cdc28e 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -202,6 +202,8 @@ traversalMethod
     | traversalMethod_count
     | traversalMethod_cyclicPath
     | traversalMethod_dedup
+    | traversalMethod_difference
+    | traversalMethod_disjunct
     | traversalMethod_drop
     | traversalMethod_elementMap
     | traversalMethod_emit
@@ -221,10 +223,12 @@ traversalMethod
     | traversalMethod_identity
     | traversalMethod_in
     | traversalMethod_inE
+    | traversalMethod_intersect
     | traversalMethod_inV
     | traversalMethod_index
     | traversalMethod_inject
     | traversalMethod_is
+    | traversalMethod_join
     | traversalMethod_key
     | traversalMethod_label
     | traversalMethod_limit
@@ -259,6 +263,9 @@ traversalMethod
     | traversalMethod_sack
     | traversalMethod_sample
     | traversalMethod_select
+    | traversalMethod_combine
+    | traversalMethod_product
+    | traversalMethod_merge
     | traversalMethod_shortestPath
     | traversalMethod_sideEffect
     | traversalMethod_simplePath
@@ -339,16 +346,16 @@ traversalMethod_aggregate
     ;
 
 traversalMethod_all
-	: 'all' LPAREN traversalPredicate RPAREN #traversalMethod_all_P
-	;
+    : 'all' LPAREN traversalPredicate RPAREN #traversalMethod_all_P
+    ;
 
 traversalMethod_and
     : 'and' LPAREN nestedTraversalList RPAREN
     ;
 
 traversalMethod_any
-	: 'any' LPAREN traversalPredicate RPAREN #traversalMethod_any_P
-	;
+    : 'any' LPAREN traversalPredicate RPAREN #traversalMethod_any_P
+    ;
 
 traversalMethod_as
     : 'as' LPAREN stringArgument (COMMA stringLiteralVarargs)? RPAREN
@@ -410,6 +417,11 @@ traversalMethod_coin
     : 'coin' LPAREN floatArgument RPAREN
     ;
 
+traversalMethod_combine
+    : 'combine' LPAREN nestedTraversal RPAREN #traversalMethod_combine_Traversal
+    | 'combine' LPAREN genericLiteralArgument RPAREN #traversalMethod_combine_Object
+    ;
+
 traversalMethod_connectedComponent
     : 'connectedComponent' LPAREN RPAREN
     ;
@@ -432,6 +444,16 @@ traversalMethod_dedup
     | 'dedup' LPAREN stringLiteralVarargs RPAREN #traversalMethod_dedup_String
     ;
 
+traversalMethod_difference
+    : 'difference' LPAREN nestedTraversal RPAREN #traversalMethod_difference_Traversal
+    | 'difference' LPAREN genericLiteralArgument RPAREN #traversalMethod_difference_Object
+    ;
+
+traversalMethod_disjunct
+    : 'disjunct' LPAREN nestedTraversal RPAREN #traversalMethod_disjunct_Traversal
+    | 'disjunct' LPAREN genericLiteralArgument RPAREN #traversalMethod_disjunct_Object
+    ;
+
 traversalMethod_drop
     : 'drop' LPAREN RPAREN
     ;
@@ -528,6 +550,11 @@ traversalMethod_inE
     : 'inE' LPAREN stringLiteralVarargs RPAREN
     ;
 
+traversalMethod_intersect
+    : 'intersect' LPAREN nestedTraversal RPAREN #traversalMethod_intersect_Traversal
+    | 'intersect' LPAREN genericLiteralArgument RPAREN #traversalMethod_intersect_Object
+    ;
+
 traversalMethod_inV
     : 'inV' LPAREN RPAREN
     ;
@@ -545,6 +572,10 @@ traversalMethod_is
     | 'is' LPAREN traversalPredicate RPAREN #traversalMethod_is_P
     ;
 
+traversalMethod_join
+    : 'join' LPAREN stringArgument RPAREN #traversalMethod_join_String
+    ;
+
 traversalMethod_key
     : 'key' LPAREN RPAREN
     ;
@@ -589,6 +620,11 @@ traversalMethod_mean
     | 'mean' LPAREN traversalScopeArgument RPAREN #traversalMethod_mean_Scope
     ;
 
+traversalMethod_merge
+    : 'merge' LPAREN nestedTraversal RPAREN #traversalMethod_merge_Traversal
+    | 'merge' LPAREN genericLiteralArgument RPAREN #traversalMethod_merge_Object
+    ;
+
 traversalMethod_min
     : 'min' LPAREN RPAREN #traversalMethod_min_Empty
     | 'min' LPAREN traversalScopeArgument RPAREN #traversalMethod_min_Scope
@@ -649,6 +685,11 @@ traversalMethod_peerPressure
     : 'peerPressure' LPAREN RPAREN
     ;
 
+traversalMethod_product
+    : 'product' LPAREN nestedTraversal RPAREN #traversalMethod_product_Traversal
+    | 'product' LPAREN genericLiteralArgument RPAREN #traversalMethod_product_Object
+    ;
+
 traversalMethod_profile
     : 'profile' LPAREN RPAREN #traversalMethod_profile_Empty
     | 'profile' LPAREN stringArgument RPAREN #traversalMethod_profile_String
@@ -687,6 +728,10 @@ traversalMethod_repeat
     | 'repeat' LPAREN nestedTraversal RPAREN #traversalMethod_repeat_Traversal
     ;
 
+traversalMethod_reverse
+    : 'reverse' LPAREN RPAREN #traversalMethod_reverse_Empty
+    ;
+
 traversalMethod_sack
     : 'sack' LPAREN traversalBiFunctionArgument RPAREN #traversalMethod_sack_BiFunction
     | 'sack' LPAREN RPAREN #traversalMethod_sack_Empty
@@ -862,10 +907,6 @@ traversalMethod_rTrim
     : 'rTrim' LPAREN RPAREN #traversalMethod_rTrim_Empty
     ;
 
-traversalMethod_reverse
-    : 'reverse' LPAREN RPAREN #traversalMethod_reverse_Empty
-    ;
-
 traversalMethod_replace
     : 'replace' LPAREN stringNullableArgument COMMA stringNullableArgument RPAREN #traversalMethod_replace_String_String
     ;
@@ -888,8 +929,8 @@ traversalMethod_dateAdd
     ;
 
 traversalMethod_dateDiff
-	: 'dateDiff' LPAREN nestedTraversal RPAREN #traversalMethod_dateDiff_Traversal
-	| 'dateDiff' LPAREN dateArgument RPAREN #traversalMethod_dateDiff_Date
+    : 'dateDiff' LPAREN nestedTraversal RPAREN #traversalMethod_dateDiff_Traversal
+    | 'dateDiff' LPAREN dateArgument RPAREN #traversalMethod_dateDiff_Date
     ;
 
 /*********************************************
diff --git a/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py b/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
index db12758288..9457f711df 100644
--- a/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
@@ -391,6 +391,10 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("coin", *args)
         return self
 
+    def combine(self, *args):
+        self.bytecode.add_step("combine", *args)
+        return self
+
     def concat(self, *args):
         self.bytecode.add_step("concat", *args)
         return self
@@ -437,6 +441,14 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("dedup", *args)
         return self
 
+    def difference(self, *args):
+        self.bytecode.add_step("difference", *args)
+        return self
+
+    def disjunct(self, *args):
+        self.bytecode.add_step("disjunct", *args)
+        return self
+
     def drop(self, *args):
         self.bytecode.add_step("drop", *args)
         return self
@@ -603,10 +615,18 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("inject", *args)
         return self
 
+    def intersect(self, *args):
+        self.bytecode.add_step("intersect", *args)
+        return self
+
     def is_(self, *args):
         self.bytecode.add_step("is", *args)
         return self
 
+    def join(self, *args):
+        self.bytecode.add_step("join", *args)
+        return self
+
     def key(self, *args):
         self.bytecode.add_step("key", *args)
         return self
@@ -655,6 +675,10 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("mean", *args)
         return self
 
+    def merge(self, *args):
+        self.bytecode.add_step("merge", *args)
+        return self
+
     def merge_e(self, *args):
         self.bytecode.add_step("mergeE", *args)
         return self
@@ -754,6 +778,10 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("peerPressure", *args)
         return self
 
+    def product(self, *args):
+        self.bytecode.add_step("product", *args)
+        return self
+
     def profile(self, *args):
         self.bytecode.add_step("profile", *args)
         return self
@@ -1119,6 +1147,10 @@ class __(object, metaclass=MagicType):
     def coin(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).coin(*args)
 
+    @classmethod
+    def combine(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).combine(*args)
+
     @classmethod
     def concat(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).concat(*args)
@@ -1155,6 +1187,14 @@ class __(object, metaclass=MagicType):
     def dedup(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).dedup(*args)
 
+    @classmethod
+    def difference(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).difference(*args)
+
+    @classmethod
+    def disjunct(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).disjunct(*args)
+
     @classmethod
     def drop(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).drop(*args)
@@ -1327,6 +1367,10 @@ class __(object, metaclass=MagicType):
     def inject(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).inject(*args)
 
+    @classmethod
+    def intersect(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).intersect(*args)
+
     @classmethod
     def is_(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).is_(*args)
@@ -1379,6 +1423,10 @@ class __(object, metaclass=MagicType):
     def mean(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).mean(*args)
 
+    @classmethod
+    def merge(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).merge(*args)
+
     @classmethod
     def merge_e(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).merge_e(*args)
@@ -1451,6 +1499,10 @@ class __(object, metaclass=MagicType):
     def path(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).path(*args)
 
+    @classmethod
+    def product(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).product(*args)
+
     @classmethod
     def project(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).project(*args)
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index 304a12cebc..a2a792e91b 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -537,6 +537,22 @@ world.gremlins = {
     'g_V_coalesceXoutXlikesX_outXknowsX_inXcreatedXX_groupCount_byXnameX': [(lambda g:g.V().coalesce(__.out('likes'),__.out('knows'),__.out('created')).groupCount().by('name'))], 
     'g_V_coalesceXoutEXknowsX_outEXcreatedXX_otherV_path_byXnameX_byXlabelX': [(lambda g:g.V().coalesce(__.outE('knows'),__.outE('created')).otherV().path().by('name').by(T.label))], 
     'g_V_outXcreatedX_order_byXnameX_coalesceXname_constantXxXX': [(lambda g:g.V().out('created').order().by('name').coalesce(__.name,__.constant('x')))], 
+    'g_injectXnullX_combineXinjectX1XX': [(lambda g:g.inject(None).combine())], 
+    'g_V_valuesXnameX_combineXV_foldX': [(lambda g:g.V().name.combine())], 
+    'g_V_fold_combineXconstantXnullXX': [(lambda g:g.V().fold().combine())], 
+    'g_V_fold_combineXVX': [(lambda g:g.V().fold().combine())], 
+    'g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().combine())], 
+    'g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().combine())], 
+    'g_V_valuesXageX_order_byXdescX_fold_combineXV_valuesXageX_order_byXdescX_foldX': [(lambda g:g.V().age.order().by(Order.desc).fold().combine())], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_combineXMARKOX': [(lambda g:g.V().out().path().by(__.name.to_upper()).combine())], 
+    'g_injectXxx1X_combineXV_valuesXnameX_foldX': [(lambda g, xx1=None:g.inject(xx1).combine())], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_combineXseattle_vancouverX': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().combine())], 
+    'g_V_out_out_path_byXnameX_combineXempty_listX': [(lambda g:g.V().out().out().path().by('name').combine())], 
+    'g_V_valuesXageX_fold_combineXconstantX27X_foldX': [(lambda g:g.V().age.fold().combine())], 
+    'g_V_out_out_path_byXnameX_combineXdave_kelvinX': [(lambda g:g.V().out().out().path().by('name').combine())], 
+    'g_injectXa_null_bX_combineXa_cX': [(lambda g, xx1=None:g.inject(xx1).combine())], 
+    'g_injectXa_null_bX_combineXa_null_cX': [(lambda g, xx1=None:g.inject(xx1).combine())], 
+    'g_injectX3_threeX_combineXfive_three_7X': [(lambda g, xx1=None:g.inject(xx1).combine())], 
     'g_injectXa_bX_concat': [(lambda g:g.inject('a','b').concat())], 
     'g_injectXa_bX_concat_XcX': [(lambda g:g.inject('a','b').concat('c'))], 
     'g_injectXa_bX_concat_Xc_dX': [(lambda g:g.inject('a','b').concat('c','d'))], 
@@ -579,6 +595,38 @@ world.gremlins = {
     'g_injectXdatetimeXstrXX_dateAddXday_11X': [(lambda g:g.inject(datetime.datetime.utcfromtimestamp(1693958400000 / 1000.0)).date_add(DT.day,11))], 
     'g_injectXdatetimeXstr1XX_dateDiffXdatetimeXstr2XX': [(lambda g:g.inject(datetime.datetime.utcfromtimestamp(1690934400000 / 1000.0)).date_diff(datetime.datetime.utcfromtimestamp(1691539200000 / 1000.0)))], 
     'g_injectXdatetimeXstr1XX_dateDiffXinjectXdatetimeXstr2XXX': [(lambda g:g.inject(datetime.datetime.utcfromtimestamp(1691452800000 / 1000.0)).date_diff(__.inject(datetime.datetime.utcfromtimestamp(1690848000000 / 1000.0))))], 
+    'g_injectXnullX_differenceXinjectX1XX': [(lambda g:g.inject(None).difference())], 
+    'g_V_valuesXnameX_differenceXV_foldX': [(lambda g:g.V().name.difference())], 
+    'g_V_fold_differenceXconstantXnullXX': [(lambda g:g.V().fold().difference())], 
+    'g_V_fold_differenceXVX': [(lambda g:g.V().fold().difference())], 
+    'g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().difference())], 
+    'g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().difference())], 
+    'g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX': [(lambda g:g.V().age.fold().difference())], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_differenceXMARKOX': [(lambda g:g.V().out().path().by(__.name.to_upper()).difference())], 
+    'g_injectXmarkoX_differenceXV_valuesXnameX_foldX': [(lambda g, xx1=None:g.inject(xx1).difference())], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_differenceXseattle_vancouverX': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().difference())], 
+    'g_V_out_out_path_byXnameX_differenceXrippleX': [(lambda g:g.V().out().out().path().by('name').difference())], 
+    'g_V_out_out_path_byXnameX_differenceXempty_listX': [(lambda g:g.V().out().out().path().by('name').difference())], 
+    'g_V_valuesXageX_fold_differenceXconstantX27X_foldX': [(lambda g:g.V().age.fold().difference())], 
+    'g_V_out_out_path_byXnameX_differenceXdave_kelvinX': [(lambda g:g.V().out().out().path().by('name').difference())], 
+    'g_injectXa_null_bX_differenceXa_cX': [(lambda g, xx1=None:g.inject(xx1).difference())], 
+    'g_injectXa_null_bX_differenceXa_null_cX': [(lambda g, xx1=None:g.inject(xx1).difference())], 
+    'g_injectX3_threeX_differenceXfive_three_7X': [(lambda g, xx1=None:g.inject(xx1).difference())], 
+    'g_injectXnullX_disjunctXinjectX1XX': [(lambda g:g.inject(None).disjunct())], 
+    'g_V_valuesXnameX_disjunctXV_foldX': [(lambda g:g.V().name.disjunct())], 
+    'g_V_fold_disjunctXconstantXnullXX': [(lambda g:g.V().fold().disjunct())], 
+    'g_V_fold_disjunctXVX': [(lambda g:g.V().fold().disjunct())], 
+    'g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().disjunct())], 
+    'g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().disjunct())], 
+    'g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX': [(lambda g:g.V().age.fold().disjunct())], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_disjunctXMARKOX': [(lambda g:g.V().out().path().by(__.name.to_upper()).disjunct())], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_disjunctXseattle_vancouverX': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().disjunct())], 
+    'g_V_out_out_path_byXnameX_disjunctXmarkoX': [(lambda g:g.V().out().out().path().by('name').disjunct())], 
+    'g_V_out_out_path_byXnameX_disjunctXstephen_markoX': [(lambda g:g.V().out().out().path().by('name').disjunct())], 
+    'g_V_out_out_path_byXnameX_disjunctXdave_kelvinX': [(lambda g:g.V().out().out().path().by('name').disjunct())], 
+    'g_injectXa_null_bX_disjunctXa_cX': [(lambda g, xx1=None:g.inject(xx1).disjunct())], 
+    'g_injectXa_null_bX_disjunctXa_null_cX': [(lambda g, xx1=None:g.inject(xx1).disjunct())], 
+    'g_injectX3_threeX_disjunctXfive_three_7X': [(lambda g, xx1=None:g.inject(xx1).disjunct())], 
     'g_V_EX11X': [(lambda g, eid11=None:g.V().E(eid11))], 
     'g_EX11X_E': [(lambda g, eid11=None:g.E(eid11).E())], 
     'g_V_EXnullX': [(lambda g:g.V().E(None))], 
@@ -611,10 +659,31 @@ world.gremlins = {
     'g_V_hasLabelXsoftwareX_name_fold_orderXlocalX_index_unfold_order_byXtailXlocal_1XX': [(lambda g:g.V().hasLabel('software').name.fold().order(Scope.local).index().unfold().order().by(__.tail(Scope.local,1)))], 
     'g_V_hasLabelXpersonX_name_fold_orderXlocalX_index_withXmapX': [(lambda g:g.V().hasLabel('person').name.fold().order(Scope.local).index().with_('~tinkerpop.index.indexer',1))], 
     'g_VX1X_valuesXageX_index_unfold_unfold': [(lambda g, vid1=None:g.V(vid1).age.index().unfold().unfold())], 
-    'g_injectX__feature___test__nullX_lTrim': [(lambda g:g.inject('  feature',' one test',None,'',' ').lTrim())], 
-    'g_injectX__feature__X_lTrim': [(lambda g:g.inject('  feature  ').lTrim())], 
-    'g_injectXListXa_bXX_lTrim': [(lambda g, xx1=None:g.inject(xx1).lTrim())], 
-    'g_V_valuesXnameX_lTrim': [(lambda g:g.addV('person').property('name',' marko ').property('age',29).as_('marko').addV('person').property('name','  vadas  ').property('age',27).as_('vadas').addV('software').property('name','  lop').property('lang','java').as_('lop').addV('person').property('name','josh  ').property('age',32).as_('josh').addV('software').property('name','   ripple   ').property('lang','java').as_('ripple').addV('person').property('name','peter').property('age',35).as_( [...]
+    'g_injectXnullX_intersectXinjectX1XX': [(lambda g:g.inject(None).intersect())], 
+    'g_V_valuesXnameX_intersectXV_foldX': [(lambda g:g.V().name.intersect())], 
+    'g_V_fold_intersectXconstantXnullXX': [(lambda g:g.V().fold().intersect())], 
+    'g_V_fold_intersectXVX': [(lambda g:g.V().fold().intersect())], 
+    'g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().intersect())], 
+    'g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().intersect())], 
+    'g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX': [(lambda g:g.V().age.fold().intersect())], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_intersectXMARKOX': [(lambda g:g.V().out().path().by(__.name.to_upper()).intersect())], 
+    'g_injectXmarkoX_intersectX___V_valuesXnameX_foldX': [(lambda g, xx1=None:g.inject(xx1).intersect())], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_intersectXseattle_vancouverX': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().intersect())], 
+    'g_V_valuesXageX_fold_intersectX___constantX27X_foldX': [(lambda g:g.V().age.fold().intersect())], 
+    'g_V_out_out_path_byXnameX_intersectXdave_kelvinX': [(lambda g:g.V().out().out().path().by('name').intersect())], 
+    'g_injectXa_null_bX_intersectXa_cX': [(lambda g, xx1=None:g.inject(xx1).intersect())], 
+    'g_injectXa_null_bX_intersectXa_null_cX': [(lambda g, xx1=None:g.inject(xx1).intersect())], 
+    'g_injectX3_threeX_intersectXfive_three_7X': [(lambda g, xx1=None:g.inject(xx1).intersect())], 
+    'g_injectXnullX_joinX1X': [(lambda g:g.inject(None).join())], 
+    'g_V_valuesXnameX_joinX1X': [(lambda g:g.V().name.join())], 
+    'g_V_valuesXnonexistantX_fold_joinX_X': [(lambda g:g.V().nonexistant.fold().join())], 
+    'g_V_valuesXnameX_fold_joinX_X': [(lambda g:g.V().name.fold().join())], 
+    'g_V_valuesXageX_order_fold_joinX_X': [(lambda g:g.V().age.order().fold().join())], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX': [(lambda g:g.V().out().path().by(__.name.to_upper()).join())], 
+    'g_injectXxx1X_joinX_X': [(lambda g, xx1=None:g.inject(xx1).join()), (lambda g, xx1=None:g.inject(xx1).join())], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().join())], 
+    'g_V_out_out_path_byXnameX_joinXX': [(lambda g:g.V().out().out().path().by('name').join())], 
+    'g_injectXxx1X_joinXxyzX': [(lambda g, xx1=None:g.inject(xx1).join())], 
     'g_injectXfeature_test_nullX_length': [(lambda g:g.inject('feature','test',None).length())], 
     'g_injectXListXa_bXX_length': [(lambda g, xx1=None:g.inject(xx1).length())], 
     'g_V_valuesXnameX_length': [(lambda g:g.V().name.length())], 
@@ -622,6 +691,10 @@ world.gremlins = {
     'g_VX1X_repeatXboth_simplePathX_untilXhasXname_peterX_or_loops_isX2XX_hasXname_peterX_path_byXnameX': [(lambda g, vid1=None:g.V(vid1).repeat(__.both().simplePath()).until(__.has('name','peter').or_().loops().is_(2)).has('name','peter').path().by('name'))], 
     'g_VX1X_repeatXboth_simplePathX_untilXhasXname_peterX_and_loops_isX3XX_hasXname_peterX_path_byXnameX': [(lambda g, vid1=None:g.V(vid1).repeat(__.both().simplePath()).until(__.has('name','peter').and_().loops().is_(3)).has('name','peter').path().by('name'))], 
     'g_V_emitXhasXname_markoX_or_loops_isX2XX_repeatXoutX_valuesXnameX': [(lambda g:g.V().emit(__.has('name','marko').or_().loops().is_(2)).repeat(__.out()).name)], 
+    'g_injectX__feature___test__nullX_lTrim': [(lambda g:g.inject('  feature',' one test',None,'',' ').lTrim())], 
+    'g_injectX__feature__X_lTrim': [(lambda g:g.inject('  feature  ').lTrim())], 
+    'g_injectXListXa_bXX_lTrim': [(lambda g, xx1=None:g.inject(xx1).lTrim())], 
+    'g_V_valuesXnameX_lTrim': [(lambda g:g.addV('person').property('name',' marko ').property('age',29).as_('marko').addV('person').property('name','  vadas  ').property('age',27).as_('vadas').addV('software').property('name','  lop').property('lang','java').as_('lop').addV('person').property('name','josh  ').property('age',32).as_('josh').addV('software').property('name','   ripple   ').property('lang','java').as_('ripple').addV('person').property('name','peter').property('age',35).as_( [...]
     'g_VX1X_mapXnameX': [(lambda g, l1=None,vid1=None:g.V(vid1).map(l1))], 
     'g_VX1X_outE_label_mapXlengthX': [(lambda g, l1=None,vid1=None:g.V(vid1).outE().label().map(l1))], 
     'g_VX1X_out_mapXnameX_mapXlengthX': [(lambda g, l1=None,l2=None,vid1=None:g.V(vid1).out().map(l1).map(l2))], 
@@ -708,6 +781,27 @@ world.gremlins = {
     'g_injectXnull_10_20_nullX_mean': [(lambda g, xx1=None,xx2=None:g.inject(None,xx1,xx2,None).mean())], 
     'g_injectXlistXnull_10_20_nullXX_meanXlocalX': [(lambda g, xx1=None:g.inject(xx1).mean(Scope.local))], 
     'g_VX1X_valuesXageX_meanXlocalX': [(lambda g, vid1=None:g.V(vid1).age.mean(Scope.local))], 
+    'g_injectXnullX_mergeXinjectX1XX': [(lambda g:g.inject(None).merge())], 
+    'g_V_valuesXnameX_mergeXV_foldX': [(lambda g:g.V().name.merge())], 
+    'g_V_fold_mergeXconstantXnullXX': [(lambda g:g.V().fold().merge())], 
+    'g_V_fold_mergeXVX': [(lambda g:g.V().fold().merge())], 
+    'g_V_elementMap_mergeXconstantXaXX': [(lambda g:g.V().elementMap().merge())], 
+    'g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX': [(lambda g:g.V().fold().merge())], 
+    'g_V_fold_mergeXk_vX': [(lambda g:g.V().fold().merge())], 
+    'g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().merge())], 
+    'g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().merge())], 
+    'g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX': [(lambda g:g.V().age.fold().merge())], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_mergeXMARKOX': [(lambda g:g.V().out().path().by(__.name.to_upper()).merge())], 
+    'g_injectXmarkoX_mergeXV_valuesXnameX_foldX': [(lambda g, xx1=None:g.inject(xx1).merge())], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_mergeXseattle_vancouverX': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().merge())], 
+    'g_V_out_out_path_byXnameX_mergeXempty_listX': [(lambda g:g.V().out().out().path().by('name').merge())], 
+    'g_V_valuesXageX_fold_mergeXconstantX27X_foldX': [(lambda g:g.V().age.fold().merge())], 
+    'g_V_out_out_path_byXnameX_mergeXdave_kelvinX': [(lambda g:g.V().out().out().path().by('name').merge())], 
+    'g_injectXa_null_bX_mergeXa_cX': [(lambda g, xx1=None:g.inject(xx1).merge())], 
+    'g_injectXa_null_bX_mergeXa_null_cX': [(lambda g, xx1=None:g.inject(xx1).merge())], 
+    'g_injectX3_threeX_mergeXfive_three_7X': [(lambda g, xx1=None:g.inject(xx1).merge())], 
+    'g_V_asXnameX_projectXnameX_byXnameX_mergeXother_blueprintX': [(lambda g:g.V().as_('name').project('name').by('name').merge())], 
+    'g_V_hasXname_markoX_elementMap_mergeXV_hasXname_lopX_elementMapX': [(lambda g:g.V().has('name','marko').elementMap().merge())], 
     'g_V_mergeEXlabel_selfX_optionXonMatch_emptyX': [(lambda g, xx1=None:g.addV('person').property('name','marko').property('age',29).addE('self')), (lambda g, xx1=None:g.V().merge_e(xx1).option(Merge.on_match,{})), (lambda g, xx1=None:g.E()), (lambda g, xx1=None:g.E().properties()), (lambda g, xx1=None:g.V())], 
     'g_V_mergeEXlabel_selfX_optionXonMatch_nullX': [(lambda g, xx1=None:g.addV('person').property('name','marko').property('age',29).addE('self')), (lambda g, xx1=None:g.V().merge_e(xx1).option(Merge.on_match,None)), (lambda g, xx1=None:g.E()), (lambda g, xx1=None:g.E().properties()), (lambda g, xx1=None:g.V())], 
     'g_V_mergeEXemptyX_optionXonCreate_nullX': [(lambda g, xx1=None:g.addV('person').property('name','marko').property('age',29)), (lambda g, xx1=None:g.V().as_('v').merge_e(xx1).option(Merge.on_create,None).option(Merge.out_v,__.select('v')).option(Merge.in_v,__.select('v'))), (lambda g, xx1=None:g.E()), (lambda g, xx1=None:g.V())], 
@@ -874,6 +968,21 @@ world.gremlins = {
     'g_V_peerPressure_hasXclusterX': [(lambda g:g.V().peerPressure().has('gremlin.peerPressureVertexProgram.cluster'))], 
     'g_V_peerPressure_withXpropertyName_clusterX_withXedges_outEXknowsXX_pageRankX1X_byXrankX_withXedges_outEXknowsX_withXtimes_2X_group_byXclusterX_byXrank_sumX_limitX100X': [(lambda g:g.V().peerPressure().with_('~tinkerpop.peerPressure.propertyName','cluster').with_('~tinkerpop.peerPressure.edges',__.outE('knows')).pageRank(float(1.0)).with_('~tinkerpop.pageRank.propertyName','rank').with_('~tinkerpop.pageRank.edges',__.outE('knows')).with_('~tinkerpop.pageRank.times',1).group().by('cl [...]
     'g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withyXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX': [(lambda g:g.V().has('name','ripple').in_('created').peerPressure().with_('~tinkerpop.peerPressure.edges',__.outE()).with_('~tinkerpop.peerPressure.propertyName','cluster').repeat(__.union(__.identity(),__.both())).times(2).dedup().valueMap('name','cluster'))], 
+    'g_injectXnullX_productXinjectX1XX': [(lambda g:g.inject(None).product())], 
+    'g_V_valuesXnameX_productXV_foldX': [(lambda g:g.V().name.product())], 
+    'g_V_fold_productXconstantXnullXX': [(lambda g:g.V().fold().product())], 
+    'g_V_fold_productXVX': [(lambda g:g.V().fold().product())], 
+    'g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().product())], 
+    'g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().product())], 
+    'g_V_valuesXageX_order_byXdescX_limitX3X_fold_productXV_valuesXageX_order_byXascX_limitX2X_foldX_unfold': [(lambda g:g.V().age.order().by(Order.desc)[0:3].fold().product().unfold())], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_productXMARKOX_unfold': [(lambda g:g.V().out().path().by(__.name.to_upper()).product().unfold())], 
+    'g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold': [(lambda g, xx1=None:g.inject(xx1).product().unfold())], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_productXdulles_seattle_vancouverX_unfold': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().product().unfold())], 
+    'g_V_valuesXageX_order_byXascX_fold_productXconstantX27X_foldX_unfold': [(lambda g:g.V().age.order().by(Order.asc).fold().product().unfold())], 
+    'g_V_out_out_path_byXnameX_productXdave_kelvinX_unfold': [(lambda g:g.V().out().out().path().by('name').product().unfold())], 
+    'g_injectXa_null_bX_productXa_cX_unfold': [(lambda g, xx1=None:g.inject(xx1).product().unfold())], 
+    'g_injectXa_null_bX_productXa_null_cX_unfold': [(lambda g, xx1=None:g.inject(xx1).product().unfold())], 
+    'g_injectX3_threeX_productXfive_three_7X_unfold': [(lambda g, xx1=None:g.inject(xx1).product().unfold())], 
     'g_V_hasLabelXpersonX_projectXa_bX_byXoutE_countX_byXageX': [(lambda g:g.V().hasLabel('person').project('a','b').by(__.outE().count()).by('age'))], 
     'g_V_outXcreatedX_projectXa_bX_byXnameX_byXinXcreatedX_countX_order_byXselectXbX__descX_selectXaX': [(lambda g:g.V().out('created').project('a','b').by('name').by(__.in_('created').count()).order().by(__.select('b'),Order.desc).select('a'))], 
     'g_V_valueMap_projectXxX_byXselectXnameXX': [(lambda g:g.V().valueMap().project('x').by(__.select('name')))], 
@@ -884,17 +993,24 @@ world.gremlins = {
     'g_V_hasXageX_propertiesXage_nameX_value': [(lambda g:g.V().has('age').properties('age','name').value())], 
     'g_V_propertiesXname_age_nullX_value': [(lambda g:g.V().properties('name','age',None).value())], 
     'g_V_valuesXname_age_nullX': [(lambda g:g.V().values('name','age',None))], 
-    'g_injectX__feature___test__nullX_rTrim': [(lambda g:g.inject('feature  ','one test ',None,'',' ').rTrim())], 
-    'g_injectX__feature__X_rTrim': [(lambda g:g.inject('  feature  ').rTrim())], 
-    'g_injectXListXa_bXX_rTrim': [(lambda g, xx1=None:g.inject(xx1).rTrim())], 
-    'g_V_valuesXnameX_rTrim': [(lambda g:g.addV('person').property('name',' marko ').property('age',29).as_('marko').addV('person').property('name','  vadas  ').property('age',27).as_('vadas').addV('software').property('name','  lop').property('lang','java').as_('lop').addV('person').property('name','josh  ').property('age',32).as_('josh').addV('software').property('name','   ripple   ').property('lang','java').as_('ripple').addV('person').property('name','peter').property('age',35).as_( [...]
     'g_injectXthat_this_testX_replaceXh_jX': [(lambda g:g.inject('that','this','test',None).replace('h','j'))], 
     'g_injectXListXa_bXcX_replaceXa_bX': [(lambda g, xx1=None:g.inject(xx1).replace('a','b'))], 
     'g_V_hasLabelXsoftwareX_valueXnameX_replaceXnull_iX': [(lambda g:g.V().hasLabel('software').name.replace(None,'g'))], 
     'g_V_hasLabelXsoftwareX_valueXnameX_replaceXa_iX': [(lambda g:g.V().hasLabel('software').name.replace('p','g'))], 
     'g_injectXfeature_test_nullX_reverse': [(lambda g:g.inject('feature','test one',None).reverse())], 
-    'g_injectXListXa_bXX_reverse': [(lambda g, xx1=None:g.inject(xx1).reverse())], 
     'g_V_valuesXnameX_reverse': [(lambda g:g.V().name.reverse())], 
+    'g_V_valuesXageX_reverse': [(lambda g:g.V().age.reverse())], 
+    'g_V_out_path_byXnameX_reverse': [(lambda g:g.V().out().path().by('name').reverse())], 
+    'g_V_out_out_path_byXnameX_reverse': [(lambda g:g.V().out().out().path().by('name').reverse())], 
+    'g_V_valuesXageX_fold_orderXlocalX_byXdescX_reverse': [(lambda g:g.V().age.fold().order(Scope.local).by(Order.desc).reverse())], 
+    'g_V_valuesXnameX_fold_orderXlocalX_by_reverse': [(lambda g:g.V().name.fold().order(Scope.local).by().reverse())], 
+    'g_injectXnullX_reverse': [(lambda g:g.inject(None).reverse())], 
+    'g_injectXbX_reverse': [(lambda g:g.inject('b').reverse())], 
+    'g_injectX3_threeX_reverse': [(lambda g, xx1=None:g.inject(xx1).reverse())], 
+    'g_injectX__feature___test__nullX_rTrim': [(lambda g:g.inject('feature  ','one test ',None,'',' ').rTrim())], 
+    'g_injectX__feature__X_rTrim': [(lambda g:g.inject('  feature  ').rTrim())], 
+    'g_injectXListXa_bXX_rTrim': [(lambda g, xx1=None:g.inject(xx1).rTrim())], 
+    'g_V_valuesXnameX_rTrim': [(lambda g:g.addV('person').property('name',' marko ').property('age',29).as_('marko').addV('person').property('name','  vadas  ').property('age',27).as_('vadas').addV('software').property('name','  lop').property('lang','java').as_('lop').addV('person').property('name','josh  ').property('age',32).as_('josh').addV('software').property('name','   ripple   ').property('lang','java').as_('ripple').addV('person').property('name','peter').property('age',35).as_( [...]
     'g_VX1X_asXaX_outXknowsX_asXbX_selectXa_bX': [(lambda g, vid1=None:g.V(vid1).as_('a').out('knows').as_('b').select('a','b'))], 
     'g_VX1X_asXaX_outXknowsX_asXbX_selectXa_bX_byXnameX': [(lambda g, vid1=None:g.V(vid1).as_('a').out('knows').as_('b').select('a','b').by('name'))], 
     'g_VX1X_asXaX_outXknowsX_asXbX_selectXaX': [(lambda g, vid1=None:g.V(vid1).as_('a').out('knows').as_('b').select('a'))], 
diff --git a/gremlin-server/src/assembly/standalone.xml b/gremlin-server/src/assembly/standalone.xml
index 9d7e814b71..33dc322d90 100644
--- a/gremlin-server/src/assembly/standalone.xml
+++ b/gremlin-server/src/assembly/standalone.xml
@@ -56,14 +56,6 @@ limitations under the License.
         </fileSet>
     </fileSets>
 
-    <files>
-        <file>
-            <source>../hadoop-gremlin/conf/hadoop-gryo.properties</source>
-            <outputDirectory>/conf</outputDirectory>
-            <filtered>false</filtered>
-        </file>
-    </files>
-
     <dependencySets>
         <dependencySet>
             <outputDirectory>/lib</outputDirectory>
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
index 6b09811472..0b510b6a62 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
@@ -189,6 +189,12 @@ public final class StepDefinition {
             return Stream.of(items).map(String::trim).map(x -> convertToObject(x)).collect(Collectors.toList());
         }));
 
+        add(Pair.with(Pattern.compile("s\\[\\]"), s -> Collections.emptySet()));
+        add(Pair.with(Pattern.compile("s\\[(.*)\\]"), s -> {
+            final String[] items = s.split(",");
+            return Stream.of(items).map(String::trim).map(x -> convertToObject(x)).collect(Collectors.toSet());
+        }));
+
         /*
          * TODO FIXME Add same support for other languages (js, python, .net)
          */
@@ -229,14 +235,15 @@ public final class StepDefinition {
         add(Pair.with(Pattern.compile("D\\[(.*)\\]"), Direction::valueOf));
         add(Pair.with(Pattern.compile("M\\[(.*)\\]"), Merge::valueOf));
 
-        add(Pair.with(Pattern.compile("c\\[(.*)\\]"), s -> Collections.emptySet()));
-        add(Pair.with(Pattern.compile("s\\[\\]"), s -> {
-            throw new AssumptionViolatedException("This test uses a empty Set as a parameter which is not supported by gremlin-language");
-        }));
-        add(Pair.with(Pattern.compile("s\\[(.*)\\]"), s -> {
-            final String[] items = s.split(",");
-            return Stream.of(items).map(String::trim).map(x -> convertToObject(x)).collect(Collectors.toSet());
+        add(Pair.with(Pattern.compile("c\\[(.*)\\]"), s -> {
+            throw new AssumptionViolatedException("This test uses a lambda as a parameter which is not supported by gremlin-language");
         }));
+//        add(Pair.with(Pattern.compile("s\\[\\]"), s -> {
+//            throw new AssumptionViolatedException("This test uses a empty Set as a parameter which is not supported by gremlin-language");
+//        }));
+//        add(Pair.with(Pattern.compile("s\\[(.*)\\]"), s -> {
+//            throw new AssumptionViolatedException("This test uses a Set as a parameter which is not supported by gremlin-language");
+//        }));
 
         add(Pair.with(Pattern.compile("(null)"), s -> null));
         add(Pair.with(Pattern.compile("(true)"), s -> true));
@@ -517,7 +524,7 @@ public final class StepDefinition {
             final Matcher matcher = pattern.matcher((String) v);
             if (matcher.find()) {
                 final Function<String,Object> converter = matcherConverter.getValue1();
-                return converter.apply(matcher.group(1));
+                return converter.apply(matcher.groupCount() == 0 ? "" : matcher.group(1));
             }
         }
 
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Combine.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Combine.feature
new file mode 100644
index 0000000000..492718cfdb
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Combine.feature
@@ -0,0 +1,213 @@
+# 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.
+
+@StepClassMap @StepCombine
+Feature: Step - combine()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_combineXinjectX1XX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).combine(__.inject(1))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for combine step can't be null"
+
+  Scenario: g_V_valuesXnameX_combineXV_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").combine(__.V().fold())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "combine step can only take an array or an Iterable type for incoming traversers"
+
+  Scenario: g_V_fold_combineXconstantXnullXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().combine(__.constant(null))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for combine step must yield an iterable type, not null"
+
+  Scenario: g_V_fold_combineXVX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().combine(__.V())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for combine step must yield an iterable type, encountered"
+
+  Scenario: g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().combine(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().combine(__.V().values("nonexistant").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valuesXageX_order_byXdescX_fold_combineXV_valuesXageX_order_byXdescX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").order().by(desc).fold().combine(__.V().values("age").order().by(desc).fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[35].i,d[32].i,d[29].i,d[27].i,d[35].i,d[32].i,d[29].i,d[27].i] |
+
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_combineXMARKOX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[MARKO]"
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).combine(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[MARKO,LOP,MARKO] |
+      | l[MARKO,VADAS,MARKO] |
+      | l[MARKO,JOSH,MARKO] |
+      | l[JOSH,RIPPLE,MARKO] |
+      | l[JOSH,LOP,MARKO] |
+      | l[PETER,LOP,MARKO] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXxx1X_combineXV_valuesXnameX_foldX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.inject(xx1).combine(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[marko,marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_combineXseattle_vancouverX
+    Given the crew graph
+    And using the parameter xx1 defined as "l[seattle,vancouver]"
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().combine(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[san diego,santa cruz,brussels,santa fe,seattle,vancouver] |
+      | l[centreville,dulles,purcellville,seattle,vancouver] |
+      | l[bremen,baltimore,oakland,seattle,seattle,vancouver] |
+      | l[spremberg,kaiserslautern,aachen,seattle,vancouver] |
+
+  Scenario: g_V_out_out_path_byXnameX_combineXempty_listX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").combine(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[marko,josh,ripple] |
+      | l[marko,josh,lop] |
+
+  Scenario: g_V_valuesXageX_fold_combineXconstantX27X_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().combine(__.constant(27).fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[29].i,d[27].i,d[32].i,d[35].i,d[27].i] |
+
+  Scenario: g_V_out_out_path_byXnameX_combineXdave_kelvinX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[dave,kelvin]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").combine(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[marko,josh,ripple,dave,kelvin] |
+      | l[marko,josh,lop,dave,kelvin] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_combineXa_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,c]"
+    And the traversal of
+      """
+      g.inject(xx1).combine(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[a,null,b,a,c] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_combineXa_null_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,null,c]"
+    And the traversal of
+      """
+      g.inject(xx1).combine(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[a,null,b,a,null,c] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_combineXfive_three_7X
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And using the parameter xx2 defined as "l[five,three,d[7].i]"
+    And the traversal of
+      """
+      g.inject(xx1).combine(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[3].i,three,five,three,d[7].i] |
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Difference.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Difference.feature
new file mode 100644
index 0000000000..01a4dc92c5
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Difference.feature
@@ -0,0 +1,226 @@
+# 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.
+
+@StepClassMap @StepDifference
+Feature: Step - difference()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_differenceXinjectX1XX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).difference(__.inject(1))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for difference step can't be null"
+
+  Scenario: g_V_valuesXnameX_differenceXV_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").difference(__.V().fold())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "difference step can only take an array or an Iterable type for incoming traversers"
+
+  Scenario: g_V_fold_differenceXconstantXnullXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().difference(__.constant(null))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for difference step must yield an iterable type, not null"
+
+  Scenario: g_V_fold_differenceXVX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().difference(__.V())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for difference step must yield an iterable type, encountered"
+
+  Scenario: g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().difference(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[] |
+
+  Scenario: g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().difference(__.V().values("nonexistant").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().difference(__.V().values("age").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[] |
+
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_differenceXMARKOX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[MARKO]"
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).difference(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[LOP] |
+      | s[VADAS] |
+      | s[JOSH] |
+      | s[JOSH,RIPPLE] |
+      | s[LOP,JOSH] |
+      | s[LOP,PETER] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXmarkoX_differenceXV_valuesXnameX_foldX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.inject(xx1).difference(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[] |
+
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_differenceXseattle_vancouverX
+    Given the crew graph
+    And using the parameter xx1 defined as "l[seattle,vancouver]"
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().difference(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[san diego,santa cruz,brussels,santa fe] |
+      | s[centreville,dulles,purcellville] |
+      | s[bremen,baltimore,oakland] |
+      | s[spremberg,kaiserslautern,aachen] |
+
+  Scenario: g_V_out_out_path_byXnameX_differenceXrippleX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[ripple]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").difference(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,josh] |
+      | s[josh,lop,marko] |
+
+  Scenario: g_V_out_out_path_byXnameX_differenceXempty_listX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").difference(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,josh,ripple] |
+      | s[marko,josh,lop] |
+
+  Scenario: g_V_valuesXageX_fold_differenceXconstantX27X_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().difference(__.constant(27).fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[d[29].i,d[32].i,d[35].i] |
+
+  Scenario: g_V_out_out_path_byXnameX_differenceXdave_kelvinX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[dave,kelvin]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").difference(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,josh,ripple] |
+      | s[marko,josh,lop] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_differenceXa_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,c]"
+    And the traversal of
+      """
+      g.inject(xx1).difference(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[null,b] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_differenceXa_null_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,null,c]"
+    And the traversal of
+      """
+      g.inject(xx1).difference(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[b] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_differenceXfive_three_7X
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And using the parameter xx2 defined as "l[five,three,d[7].i]"
+    And the traversal of
+      """
+      g.inject(xx1).difference(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[d[3].i] |
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Disjunct.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Disjunct.feature
new file mode 100644
index 0000000000..8c1bc14e5f
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Disjunct.feature
@@ -0,0 +1,204 @@
+# 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.
+
+@StepClassMap @StepDisjunct
+Feature: Step - disjunct()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_disjunctXinjectX1XX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).disjunct(__.inject(1))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for disjunct step can't be null"
+
+  # Test that non-iterable data isn't accepted
+
+  Scenario: g_V_valuesXnameX_disjunctXV_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").disjunct(__.V().fold())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "disjunct step can only take an array or an Iterable type for incoming traversers, encountered"
+
+  Scenario: g_V_fold_disjunctXconstantXnullXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().disjunct(__.constant(null))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for disjunct step must yield an iterable type, not null"
+
+  Scenario: g_V_fold_disjunctXVX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().disjunct(__.V())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for disjunct step must yield an iterable type, encountered"
+
+  Scenario: g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().disjunct(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().disjunct(__.V().values("nonexistant").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().disjunct(__.V().values("age").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[] |
+
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_disjunctXMARKOX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[MARKO]"
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).disjunct(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[LOP] |
+      | s[VADAS] |
+      | s[JOSH] |
+      | s[JOSH,RIPPLE,MARKO] |
+      | s[LOP,JOSH,MARKO] |
+      | s[LOP,PETER,MARKO] |
+
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_disjunctXseattle_vancouverX
+    Given the crew graph
+    And using the parameter xx1 defined as "l[seattle,vancouver]"
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().disjunct(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[san diego,santa cruz,brussels,santa fe,seattle,vancouver] |
+      | s[centreville,dulles,purcellville,seattle,vancouver] |
+      | s[bremen,baltimore,oakland,vancouver] |
+      | s[spremberg,kaiserslautern,aachen,seattle,vancouver] |
+
+  Scenario: g_V_out_out_path_byXnameX_disjunctXmarkoX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").disjunct(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[josh,ripple] |
+      | s[josh,lop] |
+
+  Scenario: g_V_out_out_path_byXnameX_disjunctXstephen_markoX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[stephen,marko]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").disjunct(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[stephen,josh,ripple] |
+      | s[stephen,josh,lop] |
+
+  Scenario: g_V_out_out_path_byXnameX_disjunctXdave_kelvinX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[dave,kelvin]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").disjunct(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,josh,ripple,dave,kelvin] |
+      | s[marko,josh,lop,dave,kelvin] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_disjunctXa_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,c]"
+    And the traversal of
+      """
+      g.inject(xx1).disjunct(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[null,b,c] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_disjunctXa_null_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,null,c]"
+    And the traversal of
+      """
+      g.inject(xx1).disjunct(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[b,c] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_disjunctXfive_three_7X
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And using the parameter xx2 defined as "l[five,three,d[7].i]"
+    And the traversal of
+      """
+      g.inject(xx1).disjunct(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[d[3].i,five,d[7].i] |
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Intersect.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Intersect.feature
new file mode 100644
index 0000000000..75277057bc
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Intersect.feature
@@ -0,0 +1,204 @@
+# 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.
+
+@StepClassMap @StepIntersect
+Feature: Step - intersect()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_intersectXinjectX1XX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).intersect(__.inject(1))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for intersect step can't be null"
+
+  # Test that non-iterable data isn't accepted
+
+  Scenario: g_V_valuesXnameX_intersectXV_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").intersect(__.V().fold())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "intersect step can only take an array or an Iterable type for incoming traversers, encountered"
+
+  Scenario: g_V_fold_intersectXconstantXnullXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().intersect(__.constant(null))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for intersect step must yield an iterable type, not null"
+
+  Scenario: g_V_fold_intersectXVX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().intersect(__.V())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for intersect step must yield an iterable type, encountered"
+
+  # Test empty list
+
+  Scenario: g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().intersect(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[] |
+
+  Scenario: g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().intersect(__.V().values("nonexistant").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[] |
+
+  Scenario: g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().intersect(__.V().values("age").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[d[29].i,d[27].i,d[32].i,d[35].i] |
+
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_intersectXMARKOX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[MARKO]"
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).intersect(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[MARKO] |
+      | s[MARKO] |
+      | s[MARKO] |
+      | s[] |
+      | s[] |
+      | s[] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXmarkoX_intersectX___V_valuesXnameX_foldX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.inject(xx1).intersect(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko] |
+
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_intersectXseattle_vancouverX
+    Given the crew graph
+    And using the parameter xx1 defined as "l[seattle,vancouver]"
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().intersect(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[] |
+      | s[] |
+      | s[seattle] |
+      | s[] |
+
+  Scenario: g_V_valuesXageX_fold_intersectX___constantX27X_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().intersect(__.constant(27).fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[d[27].i] |
+
+  Scenario: g_V_out_out_path_byXnameX_intersectXdave_kelvinX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[dave,kelvin]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").intersect(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[] |
+      | s[] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_intersectXa_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,c]"
+    And the traversal of
+      """
+      g.inject(xx1).intersect(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[a] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_intersectXa_null_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,null,c]"
+    And the traversal of
+      """
+      g.inject(xx1).intersect(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[a,null] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_intersectXfive_three_7X
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And using the parameter xx2 defined as "l[five,three,d[7].i]"
+    And the traversal of
+      """
+      g.inject(xx1).intersect(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[three] |
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Join.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Join.feature
new file mode 100644
index 0000000000..261c17142a
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Join.feature
@@ -0,0 +1,152 @@
+# 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.
+
+@StepClassMap @StepJoin
+Feature: Step - join()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_joinX1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).join("1")
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for join step can't be null"
+
+  Scenario: g_V_valuesXnameX_joinX1X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").join("1")
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "join step can only take an array or an Iterable type for incoming traversers, encountered "
+
+  Scenario: g_V_valuesXnonexistantX_fold_joinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().join(";")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | str[] |
+
+  Scenario: g_V_valuesXnameX_fold_joinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().join("_")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | marko_vadas_lop_josh_ripple_peter |
+
+  Scenario: g_V_valuesXageX_order_fold_joinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").order().fold().join(";")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | 27;29;32;35 |
+
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).join("MARKO")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | MARKOMARKOLOP |
+      | MARKOMARKOVADAS |
+      | MARKOMARKOJOSH |
+      | JOSHMARKORIPPLE |
+      | JOSHMARKOLOP |
+      | PETERMARKOLOP |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXxx1X_joinX_X
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.inject(xx1).join("-")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | marko |
+
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X
+    Given the crew graph
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().join("1")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | san diego1santa cruz1brussels1santa fe |
+      | centreville1dulles1purcellville |
+      | bremen1baltimore1oakland1seattle |
+      | spremberg1kaiserslautern1aachen |
+
+  Scenario: g_V_out_out_path_byXnameX_joinXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").join("")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | markojoshripple |
+      | markojoshlop |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXxx1X_joinXxyzX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And the traversal of
+      """
+      g.inject(xx1).join("xyz")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | str[axyznullxyzb] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXxx1X_joinX_X
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And the traversal of
+      """
+      g.inject(xx1).join(";")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | 3;three |
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Merge.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Merge.feature
new file mode 100644
index 0000000000..7956ae363a
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Merge.feature
@@ -0,0 +1,271 @@
+# 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.
+
+@StepClassMap @StepMerge
+Feature: Step - merge()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_mergeXinjectX1XX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).merge(__.inject(1))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for merge step can't be null"
+
+  # Test that non-iterable data isn't accepted
+
+  Scenario: g_V_valuesXnameX_mergeXV_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").merge(__.V().fold())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "merge step can only take an array or an Iterable type for incoming traversers, encountered"
+
+  Scenario: g_V_fold_mergeXconstantXnullXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().merge(__.constant(null))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for merge step must yield an iterable type, not null"
+
+  Scenario: g_V_fold_mergeXVX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().merge(__.V())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for merge step must yield an iterable type, encountered"
+
+  Scenario: g_V_elementMap_mergeXconstantXaXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().elementMap().merge(__.constant("a"))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "merge step expected provided argument to evaluate to a Map, encountered"
+
+  Scenario: g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().merge(__.V().as("a").project("a").by("name"))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for merge step must yield an iterable type, encountered"
+
+  Scenario: g_V_fold_mergeXk_vX
+    Given the modern graph
+    And using the parameter xx1 defined as "m[{\"k\":\"v\"}]"
+    And the traversal of
+      """
+      g.V().fold().merge(xx1)
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "step type mismatch: expected argument to be Iterable but got Map"
+
+  Scenario: g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().merge(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().merge(__.V().values("nonexistant").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().merge(__.V().values("age").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[d[35].i,d[32].i,d[29].i,d[27].i] |
+
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_mergeXMARKOX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[MARKO]"
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).merge(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[MARKO,LOP] |
+      | s[MARKO,VADAS] |
+      | s[MARKO,JOSH] |
+      | s[MARKO,JOSH,RIPPLE] |
+      | s[MARKO,LOP,JOSH] |
+      | s[MARKO,LOP,PETER] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXmarkoX_mergeXV_valuesXnameX_foldX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.inject(xx1).merge(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,vadas,lop,josh,ripple,peter] |
+
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_mergeXseattle_vancouverX
+    Given the crew graph
+    And using the parameter xx1 defined as "l[seattle,vancouver]"
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().merge(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[san diego,santa cruz,brussels,santa fe,seattle,vancouver] |
+      | s[centreville,dulles,purcellville,seattle,vancouver] |
+      | s[bremen,baltimore,oakland,seattle,vancouver] |
+      | s[spremberg,kaiserslautern,aachen,seattle,vancouver] |
+
+  Scenario: g_V_out_out_path_byXnameX_mergeXempty_listX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").merge(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,josh,ripple] |
+      | s[marko,josh,lop] |
+
+  Scenario: g_V_valuesXageX_fold_mergeXconstantX27X_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().merge(__.constant(27).fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[d[27].i,d[29].i,d[32].i,d[35].i] |
+
+  Scenario: g_V_out_out_path_byXnameX_mergeXdave_kelvinX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[dave,kelvin]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").merge(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[marko,josh,ripple,dave,kelvin] |
+      | s[marko,josh,lop,dave,kelvin] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_mergeXa_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,c]"
+    And the traversal of
+      """
+      g.inject(xx1).merge(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[null,a,c,b] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_mergeXa_null_cX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,null,c]"
+    And the traversal of
+      """
+      g.inject(xx1).merge(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[null,a,c,b] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_mergeXfive_three_7X
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And using the parameter xx2 defined as "l[five,three,d[7].i]"
+    And the traversal of
+      """
+      g.inject(xx1).merge(xx2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | s[d[3].i,five,three,d[7].i] |
+
+  Scenario: g_V_asXnameX_projectXnameX_byXnameX_mergeXother_blueprintX
+    Given the modern graph
+    And using the parameter xx1 defined as "m[{\"other\":\"blueprint\"}]"
+    And the traversal of
+      """
+      g.V().as("name").project("name").by("name").merge(xx1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"name":"marko", "other":"blueprint"}] |
+      | m[{"name":"lop", "other":"blueprint"}] |
+      | m[{"name":"vadas", "other":"blueprint"}] |
+      | m[{"name":"josh", "other":"blueprint"}] |
+      | m[{"name":"peter", "other":"blueprint"}] |
+      | m[{"name":"ripple", "other":"blueprint"}] |
+
+  Scenario: g_V_hasXname_markoX_elementMap_mergeXV_hasXname_lopX_elementMapX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().has("name","marko").elementMap().merge(__.V().has("name","lop").elementMap())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"t[id]":"v[lop].id","t[label]":"software","name":"lop","age":29,"lang":"java"}] |
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Product.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Product.feature
new file mode 100644
index 0000000000..2653630ff9
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Product.feature
@@ -0,0 +1,285 @@
+# 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.
+
+@StepClassMap @Product
+Feature: Step - product()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_productXinjectX1XX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).product(__.inject(1))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for product step can't be null"
+
+  Scenario: g_V_valuesXnameX_productXV_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").product(__.V().fold())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "product step can only take an array or an Iterable type for incoming traversers, encountered"
+
+  Scenario: g_V_fold_productXconstantXnullXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().product(__.constant(null))
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for product step must yield an iterable type, not null"
+
+  Scenario: g_V_fold_productXVX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().fold().product(__.V())
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "traversal argument for product step must yield an iterable type, encountered"
+
+  Scenario: g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().product(__.V().values("name").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[] |
+
+  Scenario: g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().product(__.V().values("nonexistant").fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[] |
+
+  Scenario: g_V_valuesXageX_order_byXdescX_limitX3X_fold_productXV_valuesXageX_order_byXascX_limitX2X_foldX_unfold
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").order().by(desc).limit(3).fold().product(__.V().values("age").order().by(asc).limit(2).fold()).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[35].i,d[27].i] |
+      | l[d[35].i,d[29].i] |
+      | l[d[32].i,d[27].i] |
+      | l[d[32].i,d[29].i] |
+      | l[d[29].i,d[27].i] |
+      | l[d[29].i,d[29].i] |
+
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_productXMARKOX_unfold
+    Given the modern graph
+    And using the parameter xx1 defined as "l[MARKO]"
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).product(xx1).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[MARKO,MARKO] |
+      | l[LOP,MARKO] |
+      | l[MARKO,MARKO] |
+      | l[VADAS,MARKO] |
+      | l[MARKO,MARKO] |
+      | l[JOSH,MARKO] |
+      | l[JOSH,MARKO] |
+      | l[RIPPLE,MARKO] |
+      | l[JOSH,MARKO] |
+      | l[LOP,MARKO] |
+      | l[PETER,MARKO] |
+      | l[LOP,MARKO] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.inject(xx1).product(__.V().values("name").order().fold()).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[marko,josh] |
+      | l[marko,lop] |
+      | l[marko,marko] |
+      | l[marko,peter] |
+      | l[marko,ripple] |
+      | l[marko,vadas] |
+
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_productXdulles_seattle_vancouverX_unfold
+    Given the crew graph
+    And using the parameter xx1 defined as "l[dulles,seattle,vancouver]"
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().product(xx1).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[san diego,dulles] |
+      | l[san diego,seattle] |
+      | l[san diego,vancouver] |
+      | l[santa cruz,dulles] |
+      | l[santa cruz,seattle] |
+      | l[santa cruz,vancouver] |
+      | l[brussels,dulles] |
+      | l[brussels,seattle] |
+      | l[brussels,vancouver] |
+      | l[santa fe,dulles] |
+      | l[santa fe,seattle] |
+      | l[santa fe,vancouver] |
+      | l[centreville,dulles] |
+      | l[centreville,seattle] |
+      | l[centreville,vancouver] |
+      | l[dulles,dulles] |
+      | l[dulles,seattle] |
+      | l[dulles,vancouver] |
+      | l[purcellville,dulles] |
+      | l[purcellville,seattle] |
+      | l[purcellville,vancouver] |
+      | l[bremen,dulles] |
+      | l[bremen,seattle] |
+      | l[bremen,vancouver] |
+      | l[baltimore,dulles] |
+      | l[baltimore,seattle] |
+      | l[baltimore,vancouver] |
+      | l[oakland,dulles] |
+      | l[oakland,seattle] |
+      | l[oakland,vancouver] |
+      | l[seattle,dulles] |
+      | l[seattle,seattle] |
+      | l[seattle,vancouver] |
+      | l[spremberg,dulles] |
+      | l[spremberg,seattle] |
+      | l[spremberg,vancouver] |
+      | l[kaiserslautern,dulles] |
+      | l[kaiserslautern,seattle] |
+      | l[kaiserslautern,vancouver] |
+      | l[aachen,dulles] |
+      | l[aachen,seattle] |
+      | l[aachen,vancouver] |
+
+  Scenario: g_V_valuesXageX_order_byXascX_fold_productXconstantX27X_foldX_unfold
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").order().by(asc).fold().product(__.constant(27).fold()).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[27].i,d[27].i] |
+      | l[d[29].i,d[27].i] |
+      | l[d[32].i,d[27].i] |
+      | l[d[35].i,d[27].i] |
+
+  Scenario: g_V_out_out_path_byXnameX_productXdave_kelvinX_unfold
+    Given the modern graph
+    And using the parameter xx1 defined as "l[dave,kelvin]"
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").product(xx1).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[marko,dave] |
+      | l[marko,kelvin] |
+      | l[josh,dave] |
+      | l[josh,kelvin] |
+      | l[ripple,dave] |
+      | l[ripple,kelvin] |
+      | l[marko,dave] |
+      | l[marko,kelvin] |
+      | l[josh,dave] |
+      | l[josh,kelvin] |
+      | l[lop,dave] |
+      | l[lop,kelvin] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_productXa_cX_unfold
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,c]"
+    And the traversal of
+      """
+      g.inject(xx1).product(xx2).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[a,a] |
+      | l[a,c] |
+      | l[null,a] |
+      | l[null,c] |
+      | l[b,a] |
+      | l[b,c] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_productXa_null_cX_unfold
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And using the parameter xx2 defined as "l[a,null,c]"
+    And the traversal of
+      """
+      g.inject(xx1).product(xx2).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[a,a] |
+      | l[a,null] |
+      | l[a,c] |
+      | l[null,a] |
+      | l[null,null] |
+      | l[null,c] |
+      | l[b,a] |
+      | l[b,null] |
+      | l[b,c] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_productXfive_three_7X_unfold
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And using the parameter xx2 defined as "l[five,three,d[7].i]"
+    And the traversal of
+      """
+      g.inject(xx1).product(xx2).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[3].i,five] |
+      | l[d[3].i,three] |
+      | l[d[3].i,d[7].i] |
+      | l[three,five] |
+      | l[three,three] |
+      | l[three,d[7].i] |
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Reverse.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Reverse.feature
index 02d74d5667..92df01c618 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Reverse.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Reverse.feature
@@ -32,17 +32,6 @@ Feature: Step - reverse()
       | eno tset |
       | null |
 
-  @GraphComputerVerificationInjectionNotSupported
-  Scenario: g_injectXListXa_bXX_reverse
-    Given the empty graph
-    And using the parameter xx1 defined as "l[a,b]"
-    And the traversal of
-    """
-    g.inject(xx1).reverse()
-    """
-    When iterated to list
-    Then the traversal will raise an error with message containing text of "The reverse() step can only take string as argument"
-
   Scenario: g_V_valuesXnameX_reverse
     Given the modern graph
     And the traversal of
@@ -58,3 +47,104 @@ Feature: Step - reverse()
       | hsoj |
       | elppir |
       | retep |
+
+  Scenario: g_V_valuesXageX_reverse
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").reverse()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[29].i |
+      | d[27].i |
+      | d[32].i |
+      | d[35].i |
+
+  Scenario: g_V_out_path_byXnameX_reverse
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().path().by("name").reverse()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[lop,marko] |
+      | l[vadas,marko] |
+      | l[josh,marko] |
+      | l[ripple,josh] |
+      | l[lop,josh] |
+      | l[lop,peter] |
+
+  Scenario: g_V_out_out_path_byXnameX_reverse
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").reverse()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[ripple,josh,marko] |
+      | l[lop,josh,marko] |
+
+  Scenario: g_V_valuesXageX_fold_orderXlocalX_byXdescX_reverse
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().order(local).by(desc).reverse()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[27].i,d[29].i,d[32].i,d[35].i] |
+
+  Scenario: g_V_valuesXnameX_fold_orderXlocalX_by_reverse
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().order(local).by().reverse()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[vadas,ripple,peter,marko,lop,josh] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_reverse
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).reverse()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | null |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXbX_reverse
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject("b").reverse()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_reverse
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And the traversal of
+      """
+      g.inject(xx1).reverse()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[three,d[3].i] |
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphFeatureTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphFeatureTest.java
index 8f03a7e991..9a5dfcf3eb 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphFeatureTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphFeatureTest.java
@@ -30,7 +30,7 @@ import org.junit.runner.RunWith;
 
 @RunWith(Cucumber.class)
 @CucumberOptions(
-        tags = "not @RemoteOnly and not @GraphComputerOnly and not @AllowNullPropertyValues",
+        tags = "@DisjunctTest",
         glue = { "org.apache.tinkerpop.gremlin.features" },
         objectFactory = TinkerGraphFeatureTest.TinkerGraphGuiceFactory.class,
         features = { "classpath:/org/apache/tinkerpop/gremlin/test/features" },