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/19 23:42:33 UTC

[tinkerpop] branch TINKERPOP-2978-3 updated (515f8f0b04 -> c58ca11ffd)

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


 discard 515f8f0b04 TINKERPOP-2978: Implement list functions.
     new c58ca11ffd TINKERPOP-2978: Implement list functions.

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (515f8f0b04)
            \
             N -- N -- N   refs/heads/TINKERPOP-2978-3 (c58ca11ffd)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

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.


Summary of changes:
 .../traversal/step/map/ProductStepTest.java        | 23 --------------
 .../Process/Traversal/GraphTraversal.cs            | 18 +++++------
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 36 ++++++++++++++--------
 gremlin-go/driver/anonymousTraversal.go            | 14 ++++-----
 gremlin-go/driver/cucumber/gremlin.go              | 36 ++++++++++++++--------
 gremlin-go/driver/graphTraversal.go                | 12 ++++----
 .../lib/process/graph-traversal.js                 | 20 ++++++------
 .../gremlin-javascript/test/cucumber/gremlin.js    | 36 ++++++++++++++--------
 .../gremlin_python/process/graph_traversal.py      | 12 +++++---
 gremlin-python/src/main/python/radish/gremlin.py   | 36 ++++++++++++++--------
 10 files changed, 136 insertions(+), 107 deletions(-)


[tinkerpop] 01/01: TINKERPOP-2978: 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 c58ca11ffd0eb985097843011eec7a2c818190f8
Author: Ken Hu <10...@users.noreply.github.com>
AuthorDate: Mon Sep 18 13:25:56 2023 -0700

    TINKERPOP-2978: Implement list functions.
    
    Includes combine, difference, disjunct, intersect, join, merge, product
    and reverse.
---
 .../dev/future/proposal-3-remove-closures.asciidoc |  34 ++-
 docs/src/dev/provider/gremlin-semantics.asciidoc   | 246 +++++++++++++++-
 docs/src/reference/the-traversal.asciidoc          | 132 ++++++++-
 docs/src/upgrade/release-3.7.x.asciidoc            |  28 +-
 .../grammar/DefaultGremlinBaseVisitor.java         |  28 ++
 .../language/grammar/TraversalMethodVisitor.java   |  56 ++++
 .../traversal/dsl/graph/GraphTraversal.java        | 105 ++++++-
 .../gremlin/process/traversal/dsl/graph/__.java    |  60 +++-
 .../process/traversal/step/map/CombineStep.java    |  96 +++++++
 .../process/traversal/step/map/ConjoinStep.java    |  80 ++++++
 .../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/ProductStep.java    | 103 +++++++
 .../process/traversal/step/map/ReverseStep.java    |  36 ++-
 .../traversal/step/map/TraversalMergeStep.java     | 132 +++++++++
 .../process/traversal/util/BytecodeHelper.java     |  14 +
 .../process/traversal/util/ListFunction.java       | 199 +++++++++++++
 .../gremlin/util/iterator/IteratorUtils.java       |   4 +
 .../grammar/TraversalMethodVisitorTest.java        |  73 +++++
 .../traversal/step/map/CombineStepTest.java        |  71 +++++
 .../{ReverseStepTest.java => ConjoinStepTest.java} |  33 ++-
 .../traversal/step/map/DifferenceStepTest.java     |  67 +++++
 .../traversal/step/map/DisjunctStepTest.java       |  67 +++++
 .../traversal/step/map/IntersectStepTest.java      |  68 +++++
 .../traversal/step/map/ProductStepTest.java        |  76 +++++
 .../traversal/step/map/ReverseStepTest.java        |  20 +-
 .../traversal/step/map/TraversalMergeStepTest.java |  68 +++++
 .../Process/Traversal/GraphTraversal.cs            |  67 ++++-
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 133 ++++++++-
 gremlin-go/driver/anonymousTraversal.go            |  49 ++++
 gremlin-go/driver/cucumber/gremlin.go              | 133 ++++++++-
 gremlin-go/driver/graphTraversal.go                |  43 +++
 .../lib/process/graph-traversal.js                 |  70 +++++
 .../test/cucumber/feature-steps.js                 |  46 +++
 .../gremlin-javascript/test/cucumber/gremlin.js    | 133 ++++++++-
 gremlin-language/src/main/antlr4/Gremlin.g4        |  55 +++-
 .../gremlin_python/process/graph_traversal.py      |  56 ++++
 gremlin-python/src/main/python/radish/gremlin.py   | 133 ++++++++-
 gremlin-server/src/assembly/standalone.xml         |   8 -
 .../tinkerpop/gremlin/features/StepDefinition.java |  17 +-
 .../gremlin/test/features/map/Combine.feature      | 240 ++++++++++++++++
 .../gremlin/test/features/map/Conjoin.feature      | 155 ++++++++++
 .../gremlin/test/features/map/Difference.feature   | 254 +++++++++++++++++
 .../gremlin/test/features/map/Disjunct.feature     | 230 +++++++++++++++
 .../gremlin/test/features/map/Intersect.feature    | 226 +++++++++++++++
 .../gremlin/test/features/map/Merge.feature        | 300 ++++++++++++++++++++
 .../gremlin/test/features/map/Product.feature      | 311 +++++++++++++++++++++
 .../gremlin/test/features/map/Reverse.feature      | 114 +++++++-
 49 files changed, 4889 insertions(+), 88 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 c1825c261d..a71145f106 100644
--- a/docs/src/dev/provider/gremlin-semantics.asciidoc
+++ b/docs/src/dev/provider/gremlin-semantics.asciidoc
@@ -725,6 +725,42 @@ 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)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`List`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array) 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 +907,76 @@ 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)`
+
+[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) or 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)`
+
+[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 +1023,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)`
+
+[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) or 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]
+
+[[conjoin-step]]
+=== conjoin()
+
+*Description:* Joins every element in a list together into a String. 
+
+*Syntax:* `conjoin(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/ConjoinStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#conjoin-step[reference]
+
 [[lTrim-step]]
 === lTrim()
 
@@ -943,6 +1119,40 @@ 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)`
+
+[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), a map, or 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 +1295,40 @@ 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)`
+
+[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) or 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 +1357,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..05f77750ff 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -1140,6 +1140,24 @@ 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/docs/x.y.z/dev/provider/#combine-step++[`Semantics`]
+
 [[concat-step]]
 === Concat Step
 
@@ -1382,6 +1400,43 @@ 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/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/docs/x.y.z/dev/provider/#disjunct-step++[`Semantics`]
+
 [[drop-step]]
 === Drop Step
 
@@ -1881,6 +1936,23 @@ 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/docs/x.y.z/dev/provider/#intersect-step++[`Semantics`]
+
 anchor:_gremlin_i_o[]
 [[io-step]]
 === IO Step
@@ -2089,6 +2161,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`]
 
+[[conjoin-step]]
+=== Conjoin Step
+
+The `conjoin()`-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().conjoin("+")
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#conjoin-String++[`conjoin(String)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#conjoin-step++[`Semantics`]
+
 [[key-step]]
 === Key Step
 
@@ -2614,6 +2704,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 +3456,23 @@ 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/docs/x.y.z/dev/provider/#product-step++[`Semantics`]
+
 [[profile-step]]
 === Profile Step
 
@@ -3759,12 +3885,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 5b50aa07c8..fbfae20e0f 100644
--- a/docs/src/upgrade/release-3.7.x.asciidoc
+++ b/docs/src/upgrade/release-3.7.x.asciidoc
@@ -215,7 +215,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:
 
@@ -225,11 +226,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]
 
 ==== Date manipulation functions
 
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..e9c99eb01f 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_conjoin_String(final GremlinParser.TraversalMethod_conjoin_StringContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
@@ -343,6 +351,14 @@ 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_disjunct_Object(final GremlinParser.TraversalMethod_disjunct_ObjectContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
@@ -507,6 +523,10 @@ 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}
 	 */
@@ -583,6 +603,10 @@ 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}
 	 */
@@ -651,6 +675,10 @@ 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}
 	 */
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..24d92aa002 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,14 @@ 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}
      */
@@ -440,6 +448,14 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
         return graphTraversal.coin(((Number) antlr.argumentVisitor.visitFloatArgument(ctx.floatArgument())).doubleValue());
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_conjoin_String(final GremlinParser.TraversalMethod_conjoin_StringContext ctx) {
+        return graphTraversal.conjoin(antlr.argumentVisitor.parseString(ctx.stringArgument()));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -490,6 +506,22 @@ 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_disjunct_Object(final GremlinParser.TraversalMethod_disjunct_ObjectContext ctx) {
+        return graphTraversal.disjunct(antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -826,6 +858,14 @@ 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}
      */
@@ -1018,6 +1058,14 @@ 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}
      */
@@ -1193,6 +1241,14 @@ 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}
      */
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 a6257a4eba..9f3168d7de 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,13 +86,17 @@ 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.ConjoinStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConstantStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
 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,6 +107,7 @@ 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.LabelStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaCollectingBarrierStep;
@@ -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, ?> reverse() {
         this.asAdmin().getBytecode().addStep(Symbols.reverse);
         return this.asAdmin().addStep(new ReverseStep<>(this.asAdmin()));
     }
@@ -1672,6 +1678,90 @@ 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, values);
+        return this.asAdmin().addStep(new DifferenceStep<>(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 Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.disjunct, values);
+        return this.asAdmin().addStep(new DisjunctStep<>(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 Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.intersect, values);
+        return this.asAdmin().addStep(new IntersectStep<>(this.asAdmin(), values));
+    }
+
+    /**
+     * Joins together the elements of the incoming list traverser together with the provided delimiter.
+     *
+     * @return the traversal with an appended {@link ConjoinStep}.
+     * @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> conjoin(final String delimiter) {
+        this.asAdmin().getBytecode().addStep(Symbols.conjoin, delimiter);
+        return this.asAdmin().addStep(new ConjoinStep<>(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, ?> merge(final Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.merge, values);
+        return this.asAdmin().addStep(new TraversalMergeStep<>(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 Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.combine, values);
+        return this.asAdmin().addStep(new CombineStep<>(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 Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.product, values);
+        return this.asAdmin().addStep(new ProductStep<>(this.asAdmin(), values));
+    }
+
     ///////////////////// FILTER STEPS /////////////////////
 
     /**
@@ -3749,6 +3839,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 conjoin = "conjoin";
         public static final String not = "not";
         public static final String range = "range";
         public static final String limit = "limit";
@@ -3777,6 +3868,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 cee80f1dad..e1949dde17 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, ?> 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,55 @@ public class __ {
         return __.<A>start().dateDiff(dateTraversal);
     }
 
+    /**
+     * @see GraphTraversal#difference(Object)
+     */
+    public static <A> GraphTraversal<A, Set<?>> difference(final Object values) {
+        return __.<A>start().difference(values);
+    }
+
+    /**
+     * @see GraphTraversal#disjunct(Object)
+     */
+    public static <A> GraphTraversal<A, Set<?>> disjunct(final Object values) {
+        return __.<A>start().disjunct(values);
+    }
+
+    /**
+     * @see GraphTraversal#intersect(Object)
+     */
+    public static <A> GraphTraversal<A, Set<?>> intersect(final Object values) {
+        return __.<A>start().intersect(values);
+    }
+
+    /**
+     * @see GraphTraversal#conjoin(String)
+     */
+    public static <A> GraphTraversal<A, String> conjoin(final String values) {
+        return __.<A>start().conjoin(values);
+    }
+
+    /**
+     * @see GraphTraversal#merge(Object)
+     */
+    public static <A> GraphTraversal<A, ?> merge(final Object values) {
+        return __.<A>start().merge(values);
+    }
+
+    /**
+     * @see GraphTraversal#combine(Object)
+     */
+    public static <A> GraphTraversal<A, List<?>> combine(final Object values) {
+        return __.<A>start().combine(values);
+    }
+
+    /**
+     * @see GraphTraversal#product(Object)
+     */
+    public static <A> GraphTraversal<A, List<List<?>>> product(final Object values) {
+        return __.<A>start().product(values);
+    }
+
     ///////////////////// 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..ae854eb29f
--- /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);
+
+        if (values instanceof Traversal) {
+            valueTraversal = integrateChild(((Traversal<S, E>) values).asAdmin());
+        } else {
+            parameterItems = values;
+        }
+    }
+
+    @Override
+    public String getStepName() { return "combine"; }
+
+    @Override
+    protected List<?> map(Traverser.Admin<S> traverser) {
+        final Collection listA = convertTraverserToCollection(traverser);
+        final Collection listB = (null != valueTraversal) ? convertTraversalToCollection(traverser, valueTraversal) : convertArgumentToCollection(parameterItems);
+
+        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/ConjoinStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStep.java
new file mode 100644
index 0000000000..f7b27ef1b6
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStep.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 ConjoinStep<S> extends ScalarMapStep<S, String> implements ListFunction {
+    private String delimiter;
+
+    public ConjoinStep(final Traversal.Admin traversal, final String delimiter) {
+        super(traversal);
+        if (null == delimiter) { throw new IllegalArgumentException("Input delimiter to conjoin step can't be null."); }
+        this.delimiter = delimiter;
+    }
+
+    @Override
+    public String getStepName() { return "conjoin"; }
+
+    @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 ConjoinStep<S> clone() {
+        final ConjoinStep<S> clone = (ConjoinStep<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/DifferenceStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStep.java
new file mode 100644
index 0000000000..427ff7e78c
--- /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);
+
+        if (values instanceof Traversal) {
+            valueTraversal = integrateChild(((Traversal<S, E>) values).asAdmin());
+        } else {
+            parameterItems = values;
+        }
+    }
+
+    @Override
+    public String getStepName() { return "difference"; }
+
+    @Override
+    protected Set<?> map(Traverser.Admin<S> traverser) {
+        final Collection setA = convertTraverserToCollection(traverser);
+        final Collection setB = (null != valueTraversal) ? convertTraversalToCollection(traverser, valueTraversal) : convertArgumentToCollection(parameterItems);
+        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..d42c317813
--- /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);
+
+        if (values instanceof Traversal) {
+            valueTraversal = integrateChild(((Traversal<S, E>) values).asAdmin());
+        } else {
+            parameterItems = values;
+        }
+    }
+
+    @Override
+    public String getStepName() { return "disjunct"; }
+
+    @Override
+    protected Set<?> map(Traverser.Admin<S> traverser) {
+        final Set setA = convertTraverserToSet(traverser);
+        final Set setB = (null != valueTraversal) ? convertTraversalToSet(traverser, this.valueTraversal) : convertArgumentToSet(parameterItems);
+        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..506ae0fc31
--- /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);
+
+        if (values instanceof Traversal) {
+            valueTraversal = integrateChild(((Traversal<S, E>) values).asAdmin());
+        } else {
+            parameterItems = values;
+        }
+    }
+
+    @Override
+    public String getStepName() { return "intersect"; }
+
+    @Override
+    protected Set<?> map(Traverser.Admin<S> traverser) {
+        final Set setA = convertTraverserToSet(traverser);
+        final Collection setB = (null != valueTraversal) ? convertTraversalToCollection(traverser, this.valueTraversal) : convertArgumentToCollection(parameterItems);
+        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/ProductStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStep.java
new file mode 100644
index 0000000000..9f60ac9184
--- /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);
+
+        if (values instanceof Traversal) {
+            valueTraversal = integrateChild(((Traversal<S, E>) values).asAdmin());
+        } else {
+            parameterItems = values;
+        }
+    }
+
+    @Override
+    public String getStepName() { return "product"; }
+
+    @Override
+    protected List<List<?>> map(Traverser.Admin<S> traverser) {
+        final Collection listA = convertTraverserToCollection(traverser);
+        final Collection listB = (null != valueTraversal) ? convertTraversalToCollection(traverser, valueTraversal) : convertArgumentToCollection(parameterItems);
+        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..abc90b4a8f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStep.java
@@ -0,0 +1,132 @@
+/*
+ * 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);
+
+        if (values instanceof Traversal) {
+            valueTraversal = integrateChild(((Traversal<S, E>) values).asAdmin());
+        } else {
+            parameterItems = values;
+        }
+    }
+
+    @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 = (valueTraversal != null) ? TraversalUtil.apply(traverser, valueTraversal) : parameterItems;
+            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 != valueTraversal)
+                            ? convertTraversalToCollection(traverser, valueTraversal)
+                            : convertArgumentToCollection(parameterItems);
+
+            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..19a8814b82 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,13 +68,17 @@ 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.ConjoinStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConstantStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
 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 +88,7 @@ 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.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.conjoin, Collections.singletonList(ConjoinStep.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/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..a4fdcefef8 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
@@ -39,6 +39,7 @@ import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.function.Function;
 
@@ -276,6 +277,17 @@ public class TraversalMethodVisitorTest {
         compare(g.V().coin(2.5), eval("g.V().coin(2.5)"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_combine_Object() throws Exception {
+        final ArrayList<Integer> list = new ArrayList<>();
+        list.add(1);
+        list.add(2);
+        compare(g.V().values("name").fold().combine(list),
+                eval("g.V().values(\"name\").fold().combine([1,2])"));
+        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,28 @@ public class TraversalMethodVisitorTest {
         compare(g.V().dedup(), eval("g.V().dedup()"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_difference_Object() throws Exception {
+        final ArrayList<Integer> list = new ArrayList<>();
+        list.add(1);
+        list.add(2);
+        compare(g.V().values("name").fold().difference(list),
+                eval("g.V().values(\"name\").fold().difference([1,2])"));
+        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 {
+        final ArrayList<Integer> list = new ArrayList<>();
+        list.add(1);
+        list.add(2);
+        compare(g.V().values("name").fold().disjunct(list),
+                eval("g.V().values(\"name\").fold().disjunct([1,2])"));
+        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 +543,17 @@ public class TraversalMethodVisitorTest {
                 eval("g.V(4).out().values(\"name\").inject(\"daniel\")"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_intersect_Object() throws Exception {
+        final ArrayList<Integer> list = new ArrayList<>();
+        list.add(1);
+        list.add(2);
+        compare(g.V().values("name").fold().intersect(list),
+                eval("g.V().values(\"name\").fold().intersect([1,2])"));
+        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 +569,12 @@ public class TraversalMethodVisitorTest {
         compare(g.V().iterate(), eval("g.V().iterate()"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_conjoin_Object() throws Exception {
+        compare(g.V().values("name").fold().conjoin(";"),
+                eval("g.V().values(\"name\").fold().conjoin(\";\")"));
+    }
+
     @Test
     public void shouldParseTraversalMethod_key() throws Exception {
         compare(g.V().key(), eval("g.V().key()"));
@@ -589,6 +640,17 @@ public class TraversalMethodVisitorTest {
         compare(g.V().mean(global), eval("g.V().mean(global)"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_merge_Object() throws Exception {
+        final ArrayList<Integer> list = new ArrayList<>();
+        list.add(1);
+        list.add(2);
+        compare(g.V().values("name").fold().merge(list),
+                eval("g.V().values(\"name\").fold().merge([1,2])"));
+        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 +737,17 @@ public class TraversalMethodVisitorTest {
         compare(g.V().peerPressure(), eval("g.V().peerPressure()"));
     }
 
+    @Test
+    public void shouldParseTraversalMethod_product_Object() throws Exception {
+        final ArrayList<Integer> list = new ArrayList<>();
+        list.add(1);
+        list.add(2);
+        compare(g.V().values("name").fold().product(list),
+                eval("g.V().values(\"name\").fold().product([1,2])"));
+        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/CombineStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CombineStepTest.java
new file mode 100644
index 0000000000..180365a6bd
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CombineStepTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.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;
+import org.junit.Test;
+
+import java.util.ArrayList;
+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.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+public class CombineStepTest extends StepTest {
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Arrays.asList(
+            __.combine(Collections.emptyList()),
+            __.combine(Collections.emptySet()),
+            __.combine(__.V().fold()));
+    }
+
+    @Test
+    public void testReturnTypes() {
+        assertEquals(Collections.emptyList(), __.__(Collections.emptyList()).combine(Collections.emptyList()).next());
+        assertEquals(Arrays.asList(1, 2, 3), __.__(Collections.emptyList()).combine(Arrays.asList(1, 2, 3)).next());
+        assertEquals(Arrays.asList(1, 2, 3), __.__(Arrays.asList(1, 2, 3)).combine(Collections.emptyList()).next());
+
+        assertEquals(Arrays.asList(5L, 8L, 10L, 7L, 10L), __.__(new long[] {5L, 8L, 10L}).combine(new long[] {7L, 10L}).next());
+        assertEquals(Arrays.asList(5L, 8L, 10L, 7L, 10L), __.__(new long[] {5L, 8L, 10L}).combine(__.constant(new long[] {7L, 10L})).next());
+
+        assertEquals(Arrays.asList(7L, 8L, 11L), __.__(1).constant(new Long[] {7L}).combine(new Long[] {8L, 11L}).next());
+        assertEquals(Arrays.asList(7L, 8L, 11L), __.__(1).constant(new Long[] {7L}).combine(__.constant(new Long[] {8L, 11L})).next());
+
+        assertEquals(Arrays.asList(5.5, 8.0, 10.1, 7.1, 10.5), __.__(new double[] {5.5, 8.0, 10.1}).combine(new double[] {7.1, 10.5}).next());
+        assertEquals(Arrays.asList(5.5, 8.0, 10.1, 7.1, 10.5), __.__(new double[] {5.5, 8.0, 10.1}).combine(__.constant(new double[] {7.1, 10.5})).next());
+
+        final Set<Integer> ten = new HashSet<>();
+        ten.add(10);
+        final Set<Integer> eleven = new HashSet<>();
+        eleven.add(11);
+        assertEquals(Arrays.asList(10, 11), __.__(ten).combine(eleven).next());
+        assertEquals(Arrays.asList(10, 11), __.__(ten).combine(__.constant(eleven)).next());
+    }
+}
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/ConjoinStepTest.java
similarity index 56%
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/ConjoinStepTest.java
index 1d508d1b1d..ea7ab91bd5 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/ConjoinStepTest.java
@@ -25,27 +25,34 @@ 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.assertNull;
+import static org.junit.Assert.assertTrue;
 
-/**
- * @author Yang Xia (http://github.com/xiazcy)
- */
-public class ReverseStepTest extends StepTest {
-
+public class ConjoinStepTest extends StepTest {
     @Override
-    protected List<Traversal> getTraversals() {return Collections.singletonList(__.reverse());}
+    protected List<Traversal> getTraversals() { return Collections.singletonList(__.conjoin("a")); }
 
     @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());
+        try {
+            __.__(Collections.emptyList()).conjoin(null).next();
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains("Input delimiter to conjoin step can't be null"));
+        }
+
+        assertEquals("", __.__(Collections.emptyList()).conjoin("a").next());
+        assertEquals("5AA8AA10", __.__(new long[] {5L, 8L, 10L}).conjoin("AA").next());
+        assertEquals("715", __.__(1).constant(new Long[] {7L, 15L}).conjoin("").next());
+        assertEquals("5.5,8.0,10.1", __.__(new double[] {5.5, 8.0, 10.1}).conjoin(",").next());
+
+        final Set<Integer> set = new HashSet<>();
+        set.add(10); set.add(11); set.add(12);
+        assertEquals("10.11.12", __.__(set).conjoin(".").next());
     }
-
-    @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/DifferenceStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStepTest.java
new file mode 100644
index 0000000000..ed20bb2571
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStepTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.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.assertNull;
+
+public class DifferenceStepTest extends StepTest {
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Arrays.asList(
+                __.difference(Collections.emptyList()),
+                __.difference(Collections.emptySet()),
+                __.difference(__.V().fold()));
+    }
+
+    @Test
+    public void testReturnTypes() {
+        assertEquals(Collections.emptySet(), __.__(Collections.emptyList()).difference(Collections.emptyList()).next());
+        assertEquals(Collections.emptySet(), __.__(Collections.emptyList()).difference(Arrays.asList(1, 2, 3)).next());
+        assertEquals(new HashSet(Arrays.asList(1, 2, 3)), __.__(Arrays.asList(1, 2, 3)).difference(Collections.emptyList()).next());
+
+        assertEquals(new HashSet(Arrays.asList(5L)), __.__(new long[] {5L, 8L, 10L}).difference(new long[] {7L, 8L, 10L}).next());
+        assertEquals(new HashSet(Arrays.asList(5L)), __.__(new long[] {5L, 8L, 10L}).difference(__.constant(new long[] {7L, 8L, 10L})).next());
+
+        assertEquals(new HashSet(Arrays.asList(12L)), __.__(1).constant(new Long[] {12L, 7L}).difference(new Long[] {7L, 8L, 11L}).next());
+        assertEquals(new HashSet(Arrays.asList(12L)), __.__(1).constant(new Long[] {7L, 12L}).difference(__.constant(new Long[] {7L, 8L, 11L})).next());
+
+        assertEquals(Collections.emptySet(), __.__(new double[] {5.5, 8.0, 10.1}).difference(new double[] {5.5, 8.0, 10.1, 10.5}).next());
+        assertEquals(new HashSet(Arrays.asList(5.5, 10.1)), __.__(new double[] {5.5, 8.0, 10.1}).difference(__.constant(new double[] {8.0, 10.5})).next());
+
+        final Set<Integer> setA = new HashSet<>();
+        setA.add(10); setA.add(11); setA.add(12);
+        final Set<Integer> setB = new HashSet<>();
+        setB.add(10); setB.add(11); setB.add(15);
+        assertEquals(new HashSet(Arrays.asList(12)), __.__(setA).difference(setB).next());
+        assertEquals(new HashSet(Arrays.asList(12)), __.__(setA).difference(__.constant(setB)).next());
+    }
+}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java
new file mode 100644
index 0000000000..d4902f8900
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.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.assertNull;
+
+public class DisjunctStepTest extends StepTest {
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Arrays.asList(
+                __.disjunct(Collections.emptyList()),
+                __.disjunct(Collections.emptySet()),
+                __.disjunct(__.V().fold()));
+    }
+
+    @Test
+    public void testReturnTypes() {
+        assertEquals(Collections.emptySet(), __.__(Collections.emptyList()).disjunct(Collections.emptyList()).next());
+        assertEquals(new HashSet(Arrays.asList(1, 2, 3)), __.__(Collections.emptyList()).disjunct(Arrays.asList(1, 2, 3)).next());
+        assertEquals(new HashSet(Arrays.asList(1, 2, 3)), __.__(Arrays.asList(1, 2, 3)).disjunct(Collections.emptyList()).next());
+
+        assertEquals(new HashSet(Arrays.asList(5L, 7L)), __.__(new long[] {5L, 8L, 10L}).disjunct(new long[] {7L, 8L, 10L}).next());
+        assertEquals(new HashSet(Arrays.asList(5L, 7L)), __.__(new long[] {5L, 8L, 10L}).disjunct(__.constant(new long[] {7L, 8L, 10L})).next());
+
+        assertEquals(new HashSet(Arrays.asList(8L, 11L)), __.__(1).constant(new Long[] {7L}).disjunct(new Long[] {7L, 8L, 11L}).next());
+        assertEquals(new HashSet(Arrays.asList(8L, 11L)), __.__(1).constant(new Long[] {7L}).disjunct(__.constant(new Long[] {7L, 8L, 11L})).next());
+
+        assertEquals(new HashSet(Arrays.asList(5.5, 10.1, 10.5)), __.__(new double[] {5.5, 8.0, 10.1}).disjunct(new double[] {8.0, 10.5}).next());
+        assertEquals(new HashSet(Arrays.asList(5.5, 10.1, 10.5)), __.__(new double[] {5.5, 8.0, 10.1}).disjunct(__.constant(new double[] {8.0, 10.5})).next());
+
+        final Set<Integer> setA = new HashSet<>();
+        setA.add(10); setA.add(11); setA.add(12);
+        final Set<Integer> setB = new HashSet<>();
+        setB.add(10); setB.add(11); setB.add(15);
+        assertEquals(new HashSet(Arrays.asList(12, 15)), __.__(setA).disjunct(setB).next());
+        assertEquals(new HashSet(Arrays.asList(12, 15)), __.__(setA).disjunct(__.constant(setB)).next());
+    }
+}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStepTest.java
new file mode 100644
index 0000000000..e665233ac4
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStepTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.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.assertNull;
+
+public class IntersectStepTest extends StepTest {
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Arrays.asList(
+                __.intersect(Collections.emptyList()),
+                __.intersect(Collections.emptySet()),
+                __.intersect(__.V().fold()));
+    }
+
+    @Test
+    public void testReturnTypes() {
+        assertEquals(Collections.emptySet(), __.__(Collections.emptyList()).intersect(Collections.emptyList()).next());
+        assertEquals(Collections.emptySet(), __.__(Collections.emptyList()).intersect(Arrays.asList(1, 2, 3)).next());
+        assertEquals(Collections.emptySet(), __.__(Arrays.asList(1, 2, 3)).intersect(Collections.emptyList()).next());
+
+        assertEquals(new HashSet(Arrays.asList(8L, 10L)), __.__(new long[] {5L, 8L, 10L}).intersect(new long[] {7L, 8L, 10L}).next());
+        assertEquals(Collections.emptySet(), __.__(new long[] {5L, 8L}).intersect(__.constant(new long[] {7L, 9L, 10L})).next());
+
+        assertEquals(new HashSet(Arrays.asList(7L)), __.__(1).constant(new Long[] {7L}).intersect(new Long[] {7L, 8L, 11L}).next());
+        assertEquals(new HashSet(Arrays.asList(7L)), __.__(1).constant(new Long[] {7L}).intersect(__.constant(new Long[] {7L, 8L, 11L})).next());
+
+        assertEquals(new HashSet(Arrays.asList(8.0, 10.1)), __.__(new double[] {5.5, 8.0, 10.1}).intersect(new double[] {8.0, 10.1, 10.5}).next());
+        assertEquals(new HashSet(Arrays.asList(8.0)), __.__(new double[] {5.5, 8.0, 10.1}).intersect(__.constant(new double[] {8.0, 10.5})).next());
+
+        final Set<Integer> setA = new HashSet<>();
+        setA.add(10); setA.add(11); setA.add(12);
+        final Set<Integer> setB = new HashSet<>();
+        setB.add(10); setB.add(11); setB.add(15);
+        assertEquals(new HashSet(Arrays.asList(10, 11)), __.__(setA).intersect(setB).next());
+        assertEquals(new HashSet(Arrays.asList(10, 11)), __.__(setA).intersect(__.constant(setB)).next());
+    }
+
+}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStepTest.java
new file mode 100644
index 0000000000..9d0091e71e
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStepTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.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.assertNull;
+
+public class ProductStepTest extends StepTest {
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Arrays.asList(
+                __.product(Collections.emptyList()),
+                __.product(Collections.emptySet()),
+                __.product(__.V().fold()));
+    }
+
+    @Test
+    public void testReturnTypes() {
+        assertEquals(Collections.emptyList(), __.__(Collections.emptyList()).product(Collections.emptyList()).next());
+        assertEquals(Collections.emptyList(), __.__(Collections.emptyList()).product(Arrays.asList(1, 2, 3)).next());
+        assertEquals(Collections.emptyList(), __.__(Arrays.asList(1, 2, 3)).product(Collections.emptyList()).next());
+
+        assertEquals(Arrays.asList(Arrays.asList(1,1), Arrays.asList(1,2), Arrays.asList(1,3)), __.__(Arrays.asList(1)).product(Arrays.asList(1, 2, 3)).next());
+        assertEquals(Arrays.asList(Arrays.asList(1,1), Arrays.asList(2,1), Arrays.asList(3,1)), __.__(Arrays.asList(1, 2, 3)).product(Arrays.asList(1)).next());
+
+        assertEquals(Arrays.asList(Arrays.asList(5L,7L), Arrays.asList(5L,10L), Arrays.asList(8L,7L), Arrays.asList(8L,10L)),
+                    __.__(new long[] {5L, 8L}).product(new long[] {7L, 10L}).next());
+        assertEquals(Arrays.asList(Arrays.asList(5L,7L), Arrays.asList(5L,10L), Arrays.asList(8L,7L), Arrays.asList(8L,10L)),
+                    __.__(new long[] {5L, 8L}).product(__.constant(new long[] {7L, 10L})).next());
+
+        assertEquals(Arrays.asList(Arrays.asList(7L,8L), Arrays.asList(7L,11L), Arrays.asList(3L,8L), Arrays.asList(3L,11L)),
+                    __.__(1).constant(new Long[] {7L, 3L}).product(new Long[] {8L, 11L}).next());
+        assertEquals(Arrays.asList(Arrays.asList(7L,8L), Arrays.asList(7L,11L), Arrays.asList(1L,8L), Arrays.asList(1L,11L)),
+                    __.__(1).constant(new Long[] {7L, 1L}).product(__.constant(new Long[] {8L, 11L})).next());
+
+        assertEquals(Arrays.asList(Arrays.asList(5.5,5.5), Arrays.asList(5.5,10.5), Arrays.asList(8.0,5.5), Arrays.asList(8.0,10.5)),
+                    __.__(new double[] {5.5, 8.0}).product(new double[] {5.5, 10.5}).next());
+        assertEquals(Arrays.asList(Arrays.asList(5.5,5.5), Arrays.asList(5.5,10.5), Arrays.asList(8.0,5.5), Arrays.asList(8.0,10.5)),
+                    __.__(new double[] {5.5, 8.0}).product(__.constant(new double[] {5.5, 10.5})).next());
+
+        final Set<Integer> ten = new HashSet<>();
+        ten.add(10);
+        final Set<Integer> eleven = new HashSet<>();
+        eleven.add(11);
+        assertEquals(Arrays.asList(Arrays.asList(10, 11)), __.__(ten).product(eleven).next());
+        assertEquals(Arrays.asList(Arrays.asList(10, 11)), __.__(ten).product(__.constant(eleven)).next());
+    }
+}
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-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStepTest.java
new file mode 100644
index 0000000000..4260162454
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStepTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.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;
+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.assertNull;
+
+public class TraversalMergeStepTest extends StepTest {
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Arrays.asList(
+                __.merge(Collections.emptyList()),
+                __.merge(Collections.emptySet()),
+                __.merge(__.V().fold()));
+    }
+
+    @Test
+    public void testReturnTypes() {
+        assertEquals(Collections.emptySet(), __.__(Collections.emptyList()).merge(Collections.emptyList()).next());
+        assertEquals(new HashSet(Arrays.asList(1, 2, 3)), __.__(Collections.emptyList()).merge(Arrays.asList(1, 2, 3)).next());
+        assertEquals(new HashSet(Arrays.asList(1, 2, 3)), __.__(Arrays.asList(1, 2, 3)).merge(Collections.emptyList()).next());
+
+        assertEquals(new HashSet(Arrays.asList(5L, 8L, 7L, 10L)), __.__(new long[] {5L, 8L, 10L}).merge(new long[] {7L, 10L}).next());
+        assertEquals(new HashSet(Arrays.asList(5L, 8L, 10L, 7L)), __.__(new long[] {5L, 8L, 10L}).merge(__.constant(new long[] {7L, 8L, 10L})).next());
+
+        assertEquals(new HashSet(Arrays.asList(7L, 8L, 11L)), __.__(1).constant(new Long[] {7L}).merge(new Long[] {8L, 11L}).next());
+        assertEquals(new HashSet(Arrays.asList(7L, 8L, 11L)), __.__(1).constant(new Long[] {7L, 8L}).merge(__.constant(new Long[] {8L, 11L})).next());
+
+        assertEquals(new HashSet(Arrays.asList(5.5, 8.0, 10.1)), __.__(new double[] {5.5, 8.0, 10.1}).merge(new double[] {5.5, 8.0, 10.1}).next());
+        assertEquals(new HashSet(Arrays.asList(5.5, 8.0, 10.1, 7.1, 10.5)), __.__(new double[] {5.5, 8.0, 10.1}).merge(__.constant(new double[] {7.1, 10.5})).next());
+
+        final Set<Integer> setA = new HashSet<>();
+        setA.add(5); setA.add(6); setA.add(7);
+        final Set<Integer> setB = new HashSet<>();
+        setB.add(7); setB.add(8);
+        assertEquals(new HashSet(Arrays.asList(5, 6, 7, 8)), __.__(setA).merge(setB).next());
+        assertEquals(new HashSet(Arrays.asList(5, 6 ,7, 8)), __.__(setA).merge(__.constant(setB)).next());
+    }
+}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index d232bff33d..3d8a4e6a32 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -538,6 +538,15 @@ 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 (object combineObject)
+        {
+            Bytecode.AddStep("combine", combineObject);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the concat step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -560,6 +569,15 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, TEnd>(this);
         }
 
+        /// <summary>
+        ///     Adds the conjoin step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Conjoin (string delimiter)
+        {
+            Bytecode.AddStep("conjoin", delimiter);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the connectedComponent step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -658,6 +676,24 @@ 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 (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 (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 +1180,15 @@ 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 (object intersectObject)
+        {
+            Bytecode.AddStep("intersect", intersectObject);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the is step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -1319,6 +1364,15 @@ 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 (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 +1619,15 @@ 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 (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 +1784,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 bf1f83db0a..89685e027b 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -564,6 +564,24 @@ 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(__.Inject(1))}}, 
+               {"g_V_valuesXnameX_combineXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Combine(__.V().Fold())}}, 
+               {"g_V_fold_combineXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Combine(__.Constant<object>(null))}}, 
+               {"g_V_fold_combineXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Combine(__.V())}}, 
+               {"g_V_valuesXnameX_fold_combineX2X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Combine(2)}}, 
+               {"g_V_valuesXnameX_fold_combineXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Combine(null)}}, 
+               {"g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Combine(__.V().Values<object>("name").Fold())}}, 
+               {"g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Combine(__.V().Values<object>("nonexistant").Fold())}}, 
+               {"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(__.V().Values<object>("age").Order().By(Order.Desc).Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXxx1X_combineXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Combine(__.V().Values<object>("name").Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"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(p["xx1"])}}, 
+               {"g_V_valuesXageX_order_fold_combineXconstantX27X_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().Fold().Combine(__.Constant<object>(27).Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXa_null_bX_combineXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Combine(p["xx2"])}}, 
+               {"g_injectXa_null_bX_combineXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Combine(p["xx2"])}}, 
+               {"g_injectX3_threeX_combineXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Combine(p["xx2"])}}, 
                {"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")}}, 
@@ -578,6 +596,17 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_hasLabelXsoftwareX_asXaX_valuesXnameX_concatXunsesX_concatXselectXaXvaluesXlangX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("software").As("a").Values<object>("name").Concat<object>(" uses ").Concat<object>(__.Select<object>("a").Values<object>("lang"))}}, 
                {"g_VX1X_outE_asXaX_constantXX_concatXVX1X_valuesXnameX_concatXselectXaX_label_concatXselectXaX_inV_valuesXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).OutE().As("a").V(p["vid1"]).Values<object>("name").Concat<object>(__.Select<object>("a").Label()).Concat<object>(__.Select<object>("a").InV().Values<object>("name"))}}, 
                {"g_addVXconstantXprefix_X_concatXVX1X_labelX_label", 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").Proper [...]
+               {"g_injectXnullX_conjoinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Conjoin("1")}}, 
+               {"g_V_valuesXnameX_conjoinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Conjoin("1")}}, 
+               {"g_V_valuesXnonexistantX_fold_conjoinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Conjoin(";")}}, 
+               {"g_V_valuesXnameX_order_fold_conjoinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Order().Fold().Conjoin("_")}}, 
+               {"g_V_valuesXageX_order_fold_conjoinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().Fold().Conjoin(";")}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_conjoinXMARKOX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Conjoin("MARKO")}}, 
+               {"g_injectXmarkoX_conjoinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Conjoin("-")}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_conjoinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Conjoin("1")}}, 
+               {"g_V_out_out_path_byXnameX_conjoinXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Conjoin("")}}, 
+               {"g_injectXa_null_bX_conjoinXxyzX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Conjoin("xyz")}}, 
+               {"g_injectX3_threeX_conjoinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Conjoin(";")}}, 
                {"g_V_connectedComponent_hasXcomponentX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ConnectedComponent().Has("gremlin.connectedComponentVertexProgram.component")}}, 
                {"g_V_dedup_connectedComponent_hasXcomponentX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Dedup().ConnectedComponent().Has("gremlin.connectedComponentVertexProgram.component")}}, 
                {"g_V_hasLabelXsoftwareX_connectedComponent_project_byXnameX_byXcomponentX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("software").ConnectedComponent().Project<object>("name","component").By("name").By("gremlin.connectedComponentVertexProgram.component")}}, 
@@ -604,9 +633,45 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_injectXdatetimeXstrXX_dateAddXminute_10X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1690934400000)).DateAdd(DT.Minute,10)}}, 
                {"g_injectXdatetimeXstrXX_dateAddXsecond_20X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1690934400000)).DateAdd(DT.Second,20)}}, 
                {"g_injectXdatetimeXstrXX_dateAddXday_11X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1693958400000)).DateAdd(DT.Day,11)}}, 
-               {"g_injectXdatetimeXXX_dateDiffXdatetimeXstrXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1697150417516)).DateDiff(DateTimeOffset.FromUnixTimeMilliseconds(1673481600000)).Is(P.Gt(0))}}, 
+               {"g_injectXdatetimeXXX_dateDiffXdatetimeXstrXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(DateTimeOffset.FromUnixTimeMilliseconds(1697758681476)).DateDiff(DateTimeOffset.FromUnixTimeMilliseconds(1673481600000)).Is(P.Gt(0))}}, 
                {"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(__.Inject(1))}}, 
+               {"g_V_valuesXnameX_differenceXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Difference(__.V().Fold())}}, 
+               {"g_V_fold_differenceXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Difference(__.Constant<object>(null))}}, 
+               {"g_V_fold_differenceXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Difference(__.V())}}, 
+               {"g_V_valuesXnameX_fold_differenceX2X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Difference(2)}}, 
+               {"g_V_valuesXnameX_fold_differenceXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Difference(null)}}, 
+               {"g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Difference(__.V().Values<object>("name").Fold())}}, 
+               {"g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Difference(__.V().Values<object>("nonexistant").Fold())}}, 
+               {"g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Difference(__.V().Values<object>("age").Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXmarkoX_differenceXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Difference(__.V().Values<object>("name").Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"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(p["xx1"])}}, 
+               {"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(p["xx1"])}}, 
+               {"g_V_valuesXageX_fold_differenceXconstantX27X_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Difference(__.Constant<object>(27).Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXa_null_bX_differenceXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Difference(p["xx2"])}}, 
+               {"g_injectXa_null_bX_differenceXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Difference(p["xx2"])}}, 
+               {"g_injectX3_threeX_differenceXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Difference(p["xx2"])}}, 
+               {"g_injectXnullX_disjunctXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Disjunct(__.Inject(1))}}, 
+               {"g_V_valuesXnameX_disjunctXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Disjunct(__.V().Fold())}}, 
+               {"g_V_fold_disjunctXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Disjunct(__.Constant<object>(null))}}, 
+               {"g_V_fold_disjunctXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Disjunct(__.V())}}, 
+               {"g_V_valuesXnameX_fold_disjunctX2X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Disjunct(2)}}, 
+               {"g_V_valuesXnameX_fold_disjunctXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Disjunct(null)}}, 
+               {"g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Disjunct(__.V().Values<object>("name").Fold())}}, 
+               {"g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Disjunct(__.V().Values<object>("nonexistant").Fold())}}, 
+               {"g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Disjunct(__.V().Values<object>("age").Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"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(p["xx1"])}}, 
+               {"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(p["xx1"])}}, 
+               {"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(p["xx1"])}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXa_null_bX_disjunctXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Disjunct(p["xx2"])}}, 
+               {"g_injectXa_null_bX_disjunctXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Disjunct(p["xx2"])}}, 
+               {"g_injectX3_threeX_disjunctXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Disjunct(p["xx2"])}}, 
                {"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)}}, 
@@ -639,6 +704,23 @@ 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_injectXnullX_intersectXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Intersect(__.Inject(1))}}, 
+               {"g_V_valuesXnameX_intersectXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Intersect(__.V().Fold())}}, 
+               {"g_V_fold_intersectXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Intersect(__.Constant<object>(null))}}, 
+               {"g_V_fold_intersectXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Intersect(__.V())}}, 
+               {"g_V_valuesXnameX_fold_intersectX2X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Intersect(2)}}, 
+               {"g_V_valuesXnameX_fold_intersectXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Intersect(null)}}, 
+               {"g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Intersect(__.V().Values<object>("name").Fold())}}, 
+               {"g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Intersect(__.V().Values<object>("nonexistant").Fold())}}, 
+               {"g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX_order_local", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Intersect(__.V().Values<object>("age").Fold()).Order(Scope.Local)}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXmarkoX_intersectX___V_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Intersect(__.V().Values<object>("name").Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"g_V_valuesXageX_fold_intersectX___constantX27X_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Intersect(__.Constant<object>(27).Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXa_null_bX_intersectXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Intersect(p["xx2"])}}, 
+               {"g_injectXa_null_bX_intersectXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Intersect(p["xx2"])}}, 
+               {"g_injectX3_threeX_intersectXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Intersect(p["xx2"])}}, 
                {"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()}}, 
@@ -736,6 +818,29 @@ 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(__.Inject(1))}}, 
+               {"g_V_valuesXnameX_mergeXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Merge(__.V().Fold())}}, 
+               {"g_V_fold_mergeXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Merge(__.Constant<object>(null))}}, 
+               {"g_V_fold_mergeXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Merge(__.V())}}, 
+               {"g_V_elementMap_mergeXconstantXaXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ElementMap<object>().Merge(__.Constant<object>("a"))}}, 
+               {"g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Merge(__.V().As("a").Project<object>("a").By("name"))}}, 
+               {"g_V_fold_mergeXk_vX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Merge(p["xx1"])}}, 
+               {"g_V_valuesXnameX_fold_mergeX2X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Merge(2)}}, 
+               {"g_V_valuesXnameX_fold_mergeXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Merge(null)}}, 
+               {"g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Merge(__.V().Values<object>("name").Fold())}}, 
+               {"g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Merge(__.V().Values<object>("nonexistant").Fold())}}, 
+               {"g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Merge(__.V().Values<object>("age").Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXmarkoX_mergeXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Merge(__.V().Values<object>("name").Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"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(p["xx1"])}}, 
+               {"g_V_valuesXageX_fold_mergeXconstantX27X_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Fold().Merge(__.Constant<object>(27).Fold())}}, 
+               {"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(p["xx1"])}}, 
+               {"g_injectXa_null_bX_mergeXa_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Merge(p["xx2"])}}, 
+               {"g_injectXa_null_bX_mergeXa_null_cX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Merge(p["xx2"])}}, 
+               {"g_injectX3_threeX_mergeXfive_three_7X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Merge(p["xx2"])}}, 
+               {"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(p["xx1"])}}, 
+               {"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(__.V().Has("name","lop").ElementMap<object>())}}, 
                {"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()}}, 
@@ -902,6 +1007,23 @@ 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(__.Inject(1))}}, 
+               {"g_V_valuesXnameX_productXV_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Product(__.V().Fold())}}, 
+               {"g_V_fold_productXconstantXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Product(__.Constant<object>(null))}}, 
+               {"g_V_fold_productXVX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Fold().Product(__.V())}}, 
+               {"g_V_valuesXnameX_fold_productX2X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Product(2)}}, 
+               {"g_V_valuesXnameX_fold_productXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Product(null)}}, 
+               {"g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Product(__.V().Values<object>("name").Fold())}}, 
+               {"g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Fold().Product(__.V().Values<object>("nonexistant").Fold())}}, 
+               {"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(__.V().Values<object>("age").Order().By(Order.Asc).Limit<object>(2).Fold()).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(p["xx1"]).Unfold<object>()}}, 
+               {"g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Product(__.V().Values<object>("name").Order().Fold()).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(p["xx1"]).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(__.Constant<object>(27).Fold()).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(p["xx1"]).Unfold<object>()}}, 
+               {"g_injectXa_null_bX_productXa_cX_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Product(p["xx2"]).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(p["xx2"]).Unfold<object>()}}, 
+               {"g_injectX3_threeX_productXfive_three_7X_unfold", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Product(p["xx2"]).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"))}}, 
@@ -917,8 +1039,15 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"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()}}, 
diff --git a/gremlin-go/driver/anonymousTraversal.go b/gremlin-go/driver/anonymousTraversal.go
index 009f25dd25..d1d625c233 100644
--- a/gremlin-go/driver/anonymousTraversal.go
+++ b/gremlin-go/driver/anonymousTraversal.go
@@ -87,8 +87,12 @@ 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
+	// Conjoin adds the Conjoin step to the GraphTraversal.
+	Conjoin(args ...interface{}) *GraphTraversal
 	// ConnectedComponent adds the connectedComponent step to the GraphTraversal.
 	ConnectedComponent(args ...interface{}) *GraphTraversal
 	// Constant adds the constant step to the GraphTraversal.
@@ -99,6 +103,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,6 +155,8 @@ 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
 	// Key adds the key 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,11 +432,21 @@ 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...)
 }
 
+// Conjoin adds the conjoin step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Conjoin(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Conjoin(args...)
+}
+
 // ConnectedComponent adds the connectedComponent step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) ConnectedComponent(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().ConnectedComponent(args...)
@@ -458,6 +482,16 @@ func (anonymousTraversal *anonymousTraversal) Dedup(args ...interface{}) *GraphT
 	return anonymousTraversal.graphTraversal().Dedup(args...)
 }
 
+// Difference adds the difference step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Difference(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Difference(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,6 +612,11 @@ 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...)
@@ -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 a1b837ada1..3b052ace57 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -535,6 +535,24 @@ 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(gremlingo.T__.Inject(1))}}, 
+    "g_V_valuesXnameX_combineXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Combine(gremlingo.T__.V().Fold())}}, 
+    "g_V_fold_combineXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Combine(gremlingo.T__.Constant(nil))}}, 
+    "g_V_fold_combineXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Combine(gremlingo.T__.V())}}, 
+    "g_V_valuesXnameX_fold_combineX2X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Combine(2)}}, 
+    "g_V_valuesXnameX_fold_combineXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Combine(nil)}}, 
+    "g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Combine(gremlingo.T__.V().Values("name").Fold())}}, 
+    "g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Combine(gremlingo.T__.V().Values("nonexistant").Fold())}}, 
+    "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(gremlingo.T__.V().Values("age").Order().By(gremlingo.Order.Desc).Fold())}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXxx1X_combineXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Combine(gremlingo.T__.V().Values("name").Fold())}}, 
+    "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(p["xx1"])}}, 
+    "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(p["xx1"])}}, 
+    "g_V_valuesXageX_order_fold_combineXconstantX27X_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().Fold().Combine(gremlingo.T__.Constant(27).Fold())}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXa_null_bX_combineXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Combine(p["xx2"])}}, 
+    "g_injectXa_null_bX_combineXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Combine(p["xx2"])}}, 
+    "g_injectX3_threeX_combineXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Combine(p["xx2"])}}, 
     "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")}}, 
@@ -549,6 +567,17 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_hasLabelXsoftwareX_asXaX_valuesXnameX_concatXunsesX_concatXselectXaXvaluesXlangX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("software").As("a").Values("name").Concat(" uses ").Concat(gremlingo.T__.Select("a").Values("lang"))}}, 
     "g_VX1X_outE_asXaX_constantXX_concatXVX1X_valuesXnameX_concatXselectXaX_label_concatXselectXaX_inV_valuesXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).OutE().As("a").V(p["vid1"]).Values("name").Concat(gremlingo.T__.Select("a").Label()).Concat(gremlingo.T__.Select("a").InV().Values("name"))}}, 
     "g_addVXconstantXprefix_X_concatXVX1X_labelX_label": {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", "ripp [...]
+    "g_injectXnullX_conjoinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Conjoin("1")}}, 
+    "g_V_valuesXnameX_conjoinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Conjoin("1")}}, 
+    "g_V_valuesXnonexistantX_fold_conjoinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Conjoin(";")}}, 
+    "g_V_valuesXnameX_order_fold_conjoinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Order().Fold().Conjoin("_")}}, 
+    "g_V_valuesXageX_order_fold_conjoinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().Fold().Conjoin(";")}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_conjoinXMARKOX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Conjoin("MARKO")}}, 
+    "g_injectXmarkoX_conjoinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Conjoin("-")}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_conjoinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Conjoin("1")}}, 
+    "g_V_out_out_path_byXnameX_conjoinXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Conjoin("")}}, 
+    "g_injectXa_null_bX_conjoinXxyzX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Conjoin("xyz")}}, 
+    "g_injectX3_threeX_conjoinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Conjoin(";")}}, 
     "g_V_connectedComponent_hasXcomponentX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ConnectedComponent().Has("gremlin.connectedComponentVertexProgram.component")}}, 
     "g_V_dedup_connectedComponent_hasXcomponentX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Dedup().ConnectedComponent().Has("gremlin.connectedComponentVertexProgram.component")}}, 
     "g_V_hasLabelXsoftwareX_connectedComponent_project_byXnameX_byXcomponentX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("software").ConnectedComponent().Project("name", "component").By("name").By("gremlin.connectedComponentVertexProgram.component")}}, 
@@ -575,9 +604,45 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_injectXdatetimeXstrXX_dateAddXminute_10X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(time.UnixMilli(1690934400000)).DateAdd(gremlingo.DT.Minute, 10)}}, 
     "g_injectXdatetimeXstrXX_dateAddXsecond_20X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(time.UnixMilli(1690934400000)).DateAdd(gremlingo.DT.Second, 20)}}, 
     "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_injectXdatetimeXXX_dateDiffXdatetimeXstrXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(time.UnixMilli(1697150105085)).DateDiff(time.UnixMilli(1673481600000)).Is(gremlingo.P.Gt(0))}}, 
+    "g_injectXdatetimeXXX_dateDiffXdatetimeXstrXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(time.UnixMilli(1697758691000)).DateDiff(time.UnixMilli(1673481600000)).Is(gremlingo.P.Gt(0))}}, 
     "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(gremlingo.T__.Inject(1))}}, 
+    "g_V_valuesXnameX_differenceXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Difference(gremlingo.T__.V().Fold())}}, 
+    "g_V_fold_differenceXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Difference(gremlingo.T__.Constant(nil))}}, 
+    "g_V_fold_differenceXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Difference(gremlingo.T__.V())}}, 
+    "g_V_valuesXnameX_fold_differenceX2X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Difference(2)}}, 
+    "g_V_valuesXnameX_fold_differenceXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Difference(nil)}}, 
+    "g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Difference(gremlingo.T__.V().Values("name").Fold())}}, 
+    "g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Difference(gremlingo.T__.V().Values("nonexistant").Fold())}}, 
+    "g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Difference(gremlingo.T__.V().Values("age").Fold())}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXmarkoX_differenceXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Difference(gremlingo.T__.V().Values("name").Fold())}}, 
+    "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(p["xx1"])}}, 
+    "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(p["xx1"])}}, 
+    "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(p["xx1"])}}, 
+    "g_V_valuesXageX_fold_differenceXconstantX27X_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Difference(gremlingo.T__.Constant(27).Fold())}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXa_null_bX_differenceXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Difference(p["xx2"])}}, 
+    "g_injectXa_null_bX_differenceXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Difference(p["xx2"])}}, 
+    "g_injectX3_threeX_differenceXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Difference(p["xx2"])}}, 
+    "g_injectXnullX_disjunctXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Disjunct(gremlingo.T__.Inject(1))}}, 
+    "g_V_valuesXnameX_disjunctXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Disjunct(gremlingo.T__.V().Fold())}}, 
+    "g_V_fold_disjunctXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Disjunct(gremlingo.T__.Constant(nil))}}, 
+    "g_V_fold_disjunctXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Disjunct(gremlingo.T__.V())}}, 
+    "g_V_valuesXnameX_fold_disjunctX2X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Disjunct(2)}}, 
+    "g_V_valuesXnameX_fold_disjunctXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Disjunct(nil)}}, 
+    "g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Disjunct(gremlingo.T__.V().Values("name").Fold())}}, 
+    "g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Disjunct(gremlingo.T__.V().Values("nonexistant").Fold())}}, 
+    "g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Disjunct(gremlingo.T__.V().Values("age").Fold())}}, 
+    "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(p["xx1"])}}, 
+    "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(p["xx1"])}}, 
+    "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(p["xx1"])}}, 
+    "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(p["xx1"])}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXa_null_bX_disjunctXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct(p["xx2"])}}, 
+    "g_injectXa_null_bX_disjunctXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct(p["xx2"])}}, 
+    "g_injectX3_threeX_disjunctXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Disjunct(p["xx2"])}}, 
     "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)}}, 
@@ -610,6 +675,23 @@ 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_injectXnullX_intersectXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Intersect(gremlingo.T__.Inject(1))}}, 
+    "g_V_valuesXnameX_intersectXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Intersect(gremlingo.T__.V().Fold())}}, 
+    "g_V_fold_intersectXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Intersect(gremlingo.T__.Constant(nil))}}, 
+    "g_V_fold_intersectXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Intersect(gremlingo.T__.V())}}, 
+    "g_V_valuesXnameX_fold_intersectX2X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Intersect(2)}}, 
+    "g_V_valuesXnameX_fold_intersectXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Intersect(nil)}}, 
+    "g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Intersect(gremlingo.T__.V().Values("name").Fold())}}, 
+    "g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Intersect(gremlingo.T__.V().Values("nonexistant").Fold())}}, 
+    "g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX_order_local": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Intersect(gremlingo.T__.V().Values("age").Fold()).Order(gremlingo.Scope.Local)}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXmarkoX_intersectX___V_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Intersect(gremlingo.T__.V().Values("name").Fold())}}, 
+    "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(p["xx1"])}}, 
+    "g_V_valuesXageX_fold_intersectX___constantX27X_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Intersect(gremlingo.T__.Constant(27).Fold())}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXa_null_bX_intersectXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Intersect(p["xx2"])}}, 
+    "g_injectXa_null_bX_intersectXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Intersect(p["xx2"])}}, 
+    "g_injectX3_threeX_intersectXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Intersect(p["xx2"])}}, 
     "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()}}, 
@@ -707,6 +789,29 @@ 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(gremlingo.T__.Inject(1))}}, 
+    "g_V_valuesXnameX_mergeXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Merge(gremlingo.T__.V().Fold())}}, 
+    "g_V_fold_mergeXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Merge(gremlingo.T__.Constant(nil))}}, 
+    "g_V_fold_mergeXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Merge(gremlingo.T__.V())}}, 
+    "g_V_elementMap_mergeXconstantXaXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ElementMap().Merge(gremlingo.T__.Constant("a"))}}, 
+    "g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Merge(gremlingo.T__.V().As("a").Project("a").By("name"))}}, 
+    "g_V_fold_mergeXk_vX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Merge(p["xx1"])}}, 
+    "g_V_valuesXnameX_fold_mergeX2X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Merge(2)}}, 
+    "g_V_valuesXnameX_fold_mergeXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Merge(nil)}}, 
+    "g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Merge(gremlingo.T__.V().Values("name").Fold())}}, 
+    "g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Merge(gremlingo.T__.V().Values("nonexistant").Fold())}}, 
+    "g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Merge(gremlingo.T__.V().Values("age").Fold())}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXmarkoX_mergeXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Merge(gremlingo.T__.V().Values("name").Fold())}}, 
+    "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(p["xx1"])}}, 
+    "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(p["xx1"])}}, 
+    "g_V_valuesXageX_fold_mergeXconstantX27X_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Fold().Merge(gremlingo.T__.Constant(27).Fold())}}, 
+    "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(p["xx1"])}}, 
+    "g_injectXa_null_bX_mergeXa_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Merge(p["xx2"])}}, 
+    "g_injectXa_null_bX_mergeXa_null_cX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Merge(p["xx2"])}}, 
+    "g_injectX3_threeX_mergeXfive_three_7X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Merge(p["xx2"])}}, 
+    "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(p["xx1"])}}, 
+    "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(gremlingo.T__.V().Has("name", "lop").ElementMap())}}, 
     "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")) [...]
@@ -873,6 +978,23 @@ 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(gremlingo.T__.Inject(1))}}, 
+    "g_V_valuesXnameX_productXV_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Product(gremlingo.T__.V().Fold())}}, 
+    "g_V_fold_productXconstantXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Product(gremlingo.T__.Constant(nil))}}, 
+    "g_V_fold_productXVX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Fold().Product(gremlingo.T__.V())}}, 
+    "g_V_valuesXnameX_fold_productX2X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Product(2)}}, 
+    "g_V_valuesXnameX_fold_productXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Product(nil)}}, 
+    "g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Product(gremlingo.T__.V().Values("name").Fold())}}, 
+    "g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Fold().Product(gremlingo.T__.V().Values("nonexistant").Fold())}}, 
+    "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(gremlingo.T__.V().Values("age").Order().By(gremlingo.Order.Asc).Limit(2).Fold()).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(p["xx1"]).Unfold()}}, 
+    "g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Product(gremlingo.T__.V().Values("name").Order().Fold()).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(p["xx1"]).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(gremlingo.T__.Constant(27).Fold()).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(p["xx1"]).Unfold()}}, 
+    "g_injectXa_null_bX_productXa_cX_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Product(p["xx2"]).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(p["xx2"]).Unfold()}}, 
+    "g_injectX3_threeX_productXfive_three_7X_unfold": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Product(p["xx2"]).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"))}}, 
@@ -888,8 +1010,15 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "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()}}, 
diff --git a/gremlin-go/driver/graphTraversal.go b/gremlin-go/driver/graphTraversal.go
index ec85578b0a..d62b264a39 100644
--- a/gremlin-go/driver/graphTraversal.go
+++ b/gremlin-go/driver/graphTraversal.go
@@ -185,12 +185,24 @@ 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...)
 	return g
 }
 
+// Conjoin adds the conjoin step to the GraphTraversal.
+func (g *GraphTraversal) Conjoin(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("conjoin", args...)
+	return g
+}
+
 // ConnectedComponent adds the connectedComponent step to the GraphTraversal.
 func (g *GraphTraversal) ConnectedComponent(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("connectedComponent", args...)
@@ -234,6 +246,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,6 +403,13 @@ 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...)
@@ -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..b316645dcb 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
@@ -593,6 +603,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal conjoin method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  conjoin(...args) {
+    this.bytecode.addStep('conjoin', args);
+    return this;
+  }
+
   /**
    * Graph traversal connectedComponent method.
    * @param {...Object} args
@@ -663,6 +683,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 +942,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
@@ -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/feature-steps.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index b891897a19..8794efc456 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@ -75,6 +75,52 @@ const ignoredScenarios = {
   'g_withSideEffectXa_setX_V_both_name_storeXaX_capXaX': new IgnoreError(ignoreReason.setNotSupported),
   'g_withSideEffectXa_setX_V_both_name_aggregateXlocal_aX_capXaX': new IgnoreError(ignoreReason.setNotSupported),
   'g_V_out_in_valuesXnameX_fold_dedupXlocalX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_path_byXvaluesXnameX_toUpperX_differenceXMARKOX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXmarkoX_differenceXV_valuesXnameX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valueMapXlocationX_selectXvaluesX_unfold_differenceXseattle_vancouverX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_differenceXrippleX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_differenceXempty_listX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXageX_fold_differenceXconstantX27X_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_differenceXdave_kelvinX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXa_null_bX_differenceXa_cX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXa_null_bX_differenceXa_null_cX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectX3_threeX_differenceXfive_three_7X': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_path_byXvaluesXnameX_toUpperX_disjunctXMARKOX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valueMapXlocationX_selectXvaluesX_unfold_disjunctXseattle_vancouverX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_disjunctXmarkoX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_disjunctXstephen_markoX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_disjunctXdave_kelvinX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXa_null_bX_disjunctXa_cX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXa_null_bX_disjunctXa_null_cX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectX3_threeX_disjunctXfive_three_7X': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_path_byXvaluesXnameX_toUpperX_intersectXMARKOX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXmarkoX_intersectX___V_valuesXnameX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valueMapXlocationX_selectXvaluesX_unfold_intersectXseattle_vancouverX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXageX_fold_intersectX___constantX27X_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_intersectXdave_kelvinX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXa_null_bX_intersectXa_cX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXa_null_bX_intersectXa_null_cX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectX3_threeX_intersectXfive_three_7X': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_path_byXvaluesXnameX_toUpperX_mergeXMARKOX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXmarkoX_mergeXV_valuesXnameX_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valueMapXlocationX_selectXvaluesX_unfold_mergeXseattle_vancouverX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_mergeXempty_listX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_valuesXageX_fold_mergeXconstantX27X_foldX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_V_out_out_path_byXnameX_mergeXdave_kelvinX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXa_null_bX_mergeXa_cX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectXa_null_bX_mergeXa_null_cX': new IgnoreError(ignoreReason.setNotSupported),
+  'g_injectX3_threeX_mergeXfive_three_7X': new IgnoreError(ignoreReason.setNotSupported),
   'g_withStrategiesXProductiveByStrategyX_V_groupCount_byXageX': new IgnoreError(ignoreReason.nullKeysInMapNotSupportedWell),
   'g_V_shortestPath_edgesIncluded': new IgnoreError(ignoreReason.needsFurtherInvestigation),
   'g_V_shortestPath_edgesIncluded_edgesXoutEX': new IgnoreError(ignoreReason.needsFurtherInvestigation),
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 ef6d838d37..5078bb15be 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,24 @@ 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(__.inject(1)) }], 
+    g_V_valuesXnameX_combineXV_foldX: [function({g}) { return g.V().values("name").combine(__.V().fold()) }], 
+    g_V_fold_combineXconstantXnullXX: [function({g}) { return g.V().fold().combine(__.constant(null)) }], 
+    g_V_fold_combineXVX: [function({g}) { return g.V().fold().combine(__.V()) }], 
+    g_V_valuesXnameX_fold_combineX2X: [function({g}) { return g.V().values("name").fold().combine(2) }], 
+    g_V_valuesXnameX_fold_combineXnullX: [function({g}) { return g.V().values("name").fold().combine(null) }], 
+    g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().combine(__.V().values("name").fold()) }], 
+    g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().combine(__.V().values("nonexistant").fold()) }], 
+    g_V_valuesXageX_order_byXdescX_fold_combineXV_valuesXageX_order_byXdescX_foldX: [function({g}) { return g.V().values("age").order().by(Order.desc).fold().combine(__.V().values("age").order().by(Order.desc).fold()) }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_combineXMARKOX: [function({g, xx1}) { return g.V().out().path().by(__.values("name").toUpper()).combine(xx1) }], 
+    g_injectXxx1X_combineXV_valuesXnameX_foldX: [function({g, xx1}) { return g.inject(xx1).combine(__.V().values("name").fold()) }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_combineXseattle_vancouverX: [function({g, xx1}) { return g.V().valueMap("location").select(Column.values).unfold().combine(xx1) }], 
+    g_V_out_out_path_byXnameX_combineXempty_listX: [function({g, xx1}) { return g.V().out().out().path().by("name").combine(xx1) }], 
+    g_V_valuesXageX_order_fold_combineXconstantX27X_foldX: [function({g}) { return g.V().values("age").order().fold().combine(__.constant(27).fold()) }], 
+    g_V_out_out_path_byXnameX_combineXdave_kelvinX: [function({g, xx1}) { return g.V().out().out().path().by("name").combine(xx1) }], 
+    g_injectXa_null_bX_combineXa_cX: [function({g, xx1, xx2}) { return g.inject(xx1).combine(xx2) }], 
+    g_injectXa_null_bX_combineXa_null_cX: [function({g, xx1, xx2}) { return g.inject(xx1).combine(xx2) }], 
+    g_injectX3_threeX_combineXfive_three_7X: [function({g, xx1, xx2}) { return g.inject(xx1).combine(xx2) }], 
     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") }], 
@@ -569,6 +587,17 @@ const gremlins = {
     g_hasLabelXsoftwareX_asXaX_valuesXnameX_concatXunsesX_concatXselectXaXvaluesXlangX: [function({g}) { return g.V().hasLabel("software").as("a").values("name").concat(" uses ").concat(__.select("a").values("lang")) }], 
     g_VX1X_outE_asXaX_constantXX_concatXVX1X_valuesXnameX_concatXselectXaX_label_concatXselectXaX_inV_valuesXnameX: [function({g, vid1}) { return g.V(vid1).outE().as("a").V(vid1).values("name").concat(__.select("a").label()).concat(__.select("a").inV().values("name")) }], 
     g_addVXconstantXprefix_X_concatXVX1X_labelX_label: [function({g, vid1}) { 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"). [...]
+    g_injectXnullX_conjoinX1X: [function({g}) { return g.inject(null).conjoin("1") }], 
+    g_V_valuesXnameX_conjoinX1X: [function({g}) { return g.V().values("name").conjoin("1") }], 
+    g_V_valuesXnonexistantX_fold_conjoinX_X: [function({g}) { return g.V().values("nonexistant").fold().conjoin(";") }], 
+    g_V_valuesXnameX_order_fold_conjoinX_X: [function({g}) { return g.V().values("name").order().fold().conjoin("_") }], 
+    g_V_valuesXageX_order_fold_conjoinX_X: [function({g}) { return g.V().values("age").order().fold().conjoin(";") }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_conjoinXMARKOX: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).conjoin("MARKO") }], 
+    g_injectXmarkoX_conjoinX_X: [function({g, xx1}) { return g.inject(xx1).conjoin("-") }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_conjoinX1X: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().conjoin("1") }], 
+    g_V_out_out_path_byXnameX_conjoinXX: [function({g}) { return g.V().out().out().path().by("name").conjoin("") }], 
+    g_injectXa_null_bX_conjoinXxyzX: [function({g, xx1}) { return g.inject(xx1).conjoin("xyz") }], 
+    g_injectX3_threeX_conjoinX_X: [function({g, xx1}) { return g.inject(xx1).conjoin(";") }], 
     g_V_connectedComponent_hasXcomponentX: [function({g}) { return g.V().connectedComponent().has("gremlin.connectedComponentVertexProgram.component") }], 
     g_V_dedup_connectedComponent_hasXcomponentX: [function({g}) { return g.V().dedup().connectedComponent().has("gremlin.connectedComponentVertexProgram.component") }], 
     g_V_hasLabelXsoftwareX_connectedComponent_project_byXnameX_byXcomponentX: [function({g}) { return g.V().hasLabel("software").connectedComponent().project("name","component").by("name").by("gremlin.connectedComponentVertexProgram.component") }], 
@@ -595,9 +624,45 @@ const gremlins = {
     g_injectXdatetimeXstrXX_dateAddXminute_10X: [function({g}) { return g.inject(new Date(1690934400000)).dateAdd(DT.minute,10) }], 
     g_injectXdatetimeXstrXX_dateAddXsecond_20X: [function({g}) { return g.inject(new Date(1690934400000)).dateAdd(DT.second,20) }], 
     g_injectXdatetimeXstrXX_dateAddXday_11X: [function({g}) { return g.inject(new Date(1693958400000)).dateAdd(DT.day,11) }], 
-    g_injectXdatetimeXXX_dateDiffXdatetimeXstrXX: [function({g}) { return g.inject(new Date(1697149678043)).dateDiff(new Date(1673481600000)).is(P.gt(0)) }], 
+    g_injectXdatetimeXXX_dateDiffXdatetimeXstrXX: [function({g}) { return g.inject(new Date(1697758654341)).dateDiff(new Date(1673481600000)).is(P.gt(0)) }], 
     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(__.inject(1)) }], 
+    g_V_valuesXnameX_differenceXV_foldX: [function({g}) { return g.V().values("name").difference(__.V().fold()) }], 
+    g_V_fold_differenceXconstantXnullXX: [function({g}) { return g.V().fold().difference(__.constant(null)) }], 
+    g_V_fold_differenceXVX: [function({g}) { return g.V().fold().difference(__.V()) }], 
+    g_V_valuesXnameX_fold_differenceX2X: [function({g}) { return g.V().values("name").fold().difference(2) }], 
+    g_V_valuesXnameX_fold_differenceXnullX: [function({g}) { return g.V().values("name").fold().difference(null) }], 
+    g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().difference(__.V().values("name").fold()) }], 
+    g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().difference(__.V().values("nonexistant").fold()) }], 
+    g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX: [function({g}) { return g.V().values("age").fold().difference(__.V().values("age").fold()) }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_differenceXMARKOX: [function({g, xx1}) { return g.V().out().path().by(__.values("name").toUpper()).difference(xx1) }], 
+    g_injectXmarkoX_differenceXV_valuesXnameX_foldX: [function({g, xx1}) { return g.inject(xx1).difference(__.V().values("name").fold()) }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_differenceXseattle_vancouverX: [function({g, xx1}) { return g.V().valueMap("location").select(Column.values).unfold().difference(xx1) }], 
+    g_V_out_out_path_byXnameX_differenceXrippleX: [function({g, xx1}) { return g.V().out().out().path().by("name").difference(xx1) }], 
+    g_V_out_out_path_byXnameX_differenceXempty_listX: [function({g, xx1}) { return g.V().out().out().path().by("name").difference(xx1) }], 
+    g_V_valuesXageX_fold_differenceXconstantX27X_foldX: [function({g}) { return g.V().values("age").fold().difference(__.constant(27).fold()) }], 
+    g_V_out_out_path_byXnameX_differenceXdave_kelvinX: [function({g, xx1}) { return g.V().out().out().path().by("name").difference(xx1) }], 
+    g_injectXa_null_bX_differenceXa_cX: [function({g, xx1, xx2}) { return g.inject(xx1).difference(xx2) }], 
+    g_injectXa_null_bX_differenceXa_null_cX: [function({g, xx1, xx2}) { return g.inject(xx1).difference(xx2) }], 
+    g_injectX3_threeX_differenceXfive_three_7X: [function({g, xx1, xx2}) { return g.inject(xx1).difference(xx2) }], 
+    g_injectXnullX_disjunctXinjectX1XX: [function({g}) { return g.inject(null).disjunct(__.inject(1)) }], 
+    g_V_valuesXnameX_disjunctXV_foldX: [function({g}) { return g.V().values("name").disjunct(__.V().fold()) }], 
+    g_V_fold_disjunctXconstantXnullXX: [function({g}) { return g.V().fold().disjunct(__.constant(null)) }], 
+    g_V_fold_disjunctXVX: [function({g}) { return g.V().fold().disjunct(__.V()) }], 
+    g_V_valuesXnameX_fold_disjunctX2X: [function({g}) { return g.V().values("name").fold().disjunct(2) }], 
+    g_V_valuesXnameX_fold_disjunctXnullX: [function({g}) { return g.V().values("name").fold().disjunct(null) }], 
+    g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().disjunct(__.V().values("name").fold()) }], 
+    g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().disjunct(__.V().values("nonexistant").fold()) }], 
+    g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX: [function({g}) { return g.V().values("age").fold().disjunct(__.V().values("age").fold()) }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_disjunctXMARKOX: [function({g, xx1}) { return g.V().out().path().by(__.values("name").toUpper()).disjunct(xx1) }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_disjunctXseattle_vancouverX: [function({g, xx1}) { return g.V().valueMap("location").select(Column.values).unfold().disjunct(xx1) }], 
+    g_V_out_out_path_byXnameX_disjunctXmarkoX: [function({g, xx1}) { return g.V().out().out().path().by("name").disjunct(xx1) }], 
+    g_V_out_out_path_byXnameX_disjunctXstephen_markoX: [function({g, xx1}) { return g.V().out().out().path().by("name").disjunct(xx1) }], 
+    g_V_out_out_path_byXnameX_disjunctXdave_kelvinX: [function({g, xx1}) { return g.V().out().out().path().by("name").disjunct(xx1) }], 
+    g_injectXa_null_bX_disjunctXa_cX: [function({g, xx1, xx2}) { return g.inject(xx1).disjunct(xx2) }], 
+    g_injectXa_null_bX_disjunctXa_null_cX: [function({g, xx1, xx2}) { return g.inject(xx1).disjunct(xx2) }], 
+    g_injectX3_threeX_disjunctXfive_three_7X: [function({g, xx1, xx2}) { return g.inject(xx1).disjunct(xx2) }], 
     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) }], 
@@ -630,6 +695,23 @@ 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_injectXnullX_intersectXinjectX1XX: [function({g}) { return g.inject(null).intersect(__.inject(1)) }], 
+    g_V_valuesXnameX_intersectXV_foldX: [function({g}) { return g.V().values("name").intersect(__.V().fold()) }], 
+    g_V_fold_intersectXconstantXnullXX: [function({g}) { return g.V().fold().intersect(__.constant(null)) }], 
+    g_V_fold_intersectXVX: [function({g}) { return g.V().fold().intersect(__.V()) }], 
+    g_V_valuesXnameX_fold_intersectX2X: [function({g}) { return g.V().values("name").fold().intersect(2) }], 
+    g_V_valuesXnameX_fold_intersectXnullX: [function({g}) { return g.V().values("name").fold().intersect(null) }], 
+    g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().intersect(__.V().values("name").fold()) }], 
+    g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().intersect(__.V().values("nonexistant").fold()) }], 
+    g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX_order_local: [function({g}) { return g.V().values("age").fold().intersect(__.V().values("age").fold()).order(Scope.local) }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_intersectXMARKOX: [function({g, xx1}) { return g.V().out().path().by(__.values("name").toUpper()).intersect(xx1) }], 
+    g_injectXmarkoX_intersectX___V_valuesXnameX_foldX: [function({g, xx1}) { return g.inject(xx1).intersect(__.V().values("name").fold()) }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_intersectXseattle_vancouverX: [function({g, xx1}) { return g.V().valueMap("location").select(Column.values).unfold().intersect(xx1) }], 
+    g_V_valuesXageX_fold_intersectX___constantX27X_foldX: [function({g}) { return g.V().values("age").fold().intersect(__.constant(27).fold()) }], 
+    g_V_out_out_path_byXnameX_intersectXdave_kelvinX: [function({g, xx1}) { return g.V().out().out().path().by("name").intersect(xx1) }], 
+    g_injectXa_null_bX_intersectXa_cX: [function({g, xx1, xx2}) { return g.inject(xx1).intersect(xx2) }], 
+    g_injectXa_null_bX_intersectXa_null_cX: [function({g, xx1, xx2}) { return g.inject(xx1).intersect(xx2) }], 
+    g_injectX3_threeX_intersectXfive_three_7X: [function({g, xx1, xx2}) { return g.inject(xx1).intersect(xx2) }], 
     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() }], 
@@ -727,6 +809,29 @@ 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(__.inject(1)) }], 
+    g_V_valuesXnameX_mergeXV_foldX: [function({g}) { return g.V().values("name").merge(__.V().fold()) }], 
+    g_V_fold_mergeXconstantXnullXX: [function({g}) { return g.V().fold().merge(__.constant(null)) }], 
+    g_V_fold_mergeXVX: [function({g}) { return g.V().fold().merge(__.V()) }], 
+    g_V_elementMap_mergeXconstantXaXX: [function({g}) { return g.V().elementMap().merge(__.constant("a")) }], 
+    g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX: [function({g}) { return g.V().fold().merge(__.V().as("a").project("a").by("name")) }], 
+    g_V_fold_mergeXk_vX: [function({g, xx1}) { return g.V().fold().merge(xx1) }], 
+    g_V_valuesXnameX_fold_mergeX2X: [function({g}) { return g.V().values("name").fold().merge(2) }], 
+    g_V_valuesXnameX_fold_mergeXnullX: [function({g}) { return g.V().values("name").fold().merge(null) }], 
+    g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().merge(__.V().values("name").fold()) }], 
+    g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().merge(__.V().values("nonexistant").fold()) }], 
+    g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX: [function({g}) { return g.V().values("age").fold().merge(__.V().values("age").fold()) }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_mergeXMARKOX: [function({g, xx1}) { return g.V().out().path().by(__.values("name").toUpper()).merge(xx1) }], 
+    g_injectXmarkoX_mergeXV_valuesXnameX_foldX: [function({g, xx1}) { return g.inject(xx1).merge(__.V().values("name").fold()) }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_mergeXseattle_vancouverX: [function({g, xx1}) { return g.V().valueMap("location").select(Column.values).unfold().merge(xx1) }], 
+    g_V_out_out_path_byXnameX_mergeXempty_listX: [function({g, xx1}) { return g.V().out().out().path().by("name").merge(xx1) }], 
+    g_V_valuesXageX_fold_mergeXconstantX27X_foldX: [function({g}) { return g.V().values("age").fold().merge(__.constant(27).fold()) }], 
+    g_V_out_out_path_byXnameX_mergeXdave_kelvinX: [function({g, xx1}) { return g.V().out().out().path().by("name").merge(xx1) }], 
+    g_injectXa_null_bX_mergeXa_cX: [function({g, xx1, xx2}) { return g.inject(xx1).merge(xx2) }], 
+    g_injectXa_null_bX_mergeXa_null_cX: [function({g, xx1, xx2}) { return g.inject(xx1).merge(xx2) }], 
+    g_injectX3_threeX_mergeXfive_three_7X: [function({g, xx1, xx2}) { return g.inject(xx1).merge(xx2) }], 
+    g_V_asXnameX_projectXnameX_byXnameX_mergeXother_blueprintX: [function({g, xx1}) { return g.V().as("name").project("name").by("name").merge(xx1) }], 
+    g_V_hasXname_markoX_elementMap_mergeXV_hasXname_lopX_elementMapX: [function({g}) { return g.V().has("name","marko").elementMap().merge(__.V().has("name","lop").elementMap()) }], 
     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() }], 
@@ -893,6 +998,23 @@ 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(__.inject(1)) }], 
+    g_V_valuesXnameX_productXV_foldX: [function({g}) { return g.V().values("name").product(__.V().fold()) }], 
+    g_V_fold_productXconstantXnullXX: [function({g}) { return g.V().fold().product(__.constant(null)) }], 
+    g_V_fold_productXVX: [function({g}) { return g.V().fold().product(__.V()) }], 
+    g_V_valuesXnameX_fold_productX2X: [function({g}) { return g.V().values("name").fold().product(2) }], 
+    g_V_valuesXnameX_fold_productXnullX: [function({g}) { return g.V().values("name").fold().product(null) }], 
+    g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX: [function({g}) { return g.V().values("nonexistant").fold().product(__.V().values("name").fold()) }], 
+    g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX: [function({g}) { return g.V().values("name").fold().product(__.V().values("nonexistant").fold()) }], 
+    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(__.V().values("age").order().by(Order.asc).limit(2).fold()).unfold() }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_productXMARKOX_unfold: [function({g, xx1}) { return g.V().out().path().by(__.values("name").toUpper()).product(xx1).unfold() }], 
+    g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold: [function({g, xx1}) { return g.inject(xx1).product(__.V().values("name").order().fold()).unfold() }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_productXdulles_seattle_vancouverX_unfold: [function({g, xx1}) { return g.V().valueMap("location").select(Column.values).unfold().product(xx1).unfold() }], 
+    g_V_valuesXageX_order_byXascX_fold_productXconstantX27X_foldX_unfold: [function({g}) { return g.V().values("age").order().by(Order.asc).fold().product(__.constant(27).fold()).unfold() }], 
+    g_V_out_out_path_byXnameX_productXdave_kelvinX_unfold: [function({g, xx1}) { return g.V().out().out().path().by("name").product(xx1).unfold() }], 
+    g_injectXa_null_bX_productXa_cX_unfold: [function({g, xx1, xx2}) { return g.inject(xx1).product(xx2).unfold() }], 
+    g_injectXa_null_bX_productXa_null_cX_unfold: [function({g, xx1, xx2}) { return g.inject(xx1).product(xx2).unfold() }], 
+    g_injectX3_threeX_productXfive_three_7X_unfold: [function({g, xx1, xx2}) { return g.inject(xx1).product(xx2).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")) }], 
@@ -908,8 +1030,15 @@ const gremlins = {
     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() }], 
diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 b/gremlin-language/src/main/antlr4/Gremlin.g4
index fe38cd5567..c387b02b71 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -197,11 +197,14 @@ traversalMethod
     | traversalMethod_choose
     | traversalMethod_coalesce
     | traversalMethod_coin
+    | traversalMethod_conjoin
     | traversalMethod_connectedComponent
     | traversalMethod_constant
     | traversalMethod_count
     | traversalMethod_cyclicPath
     | traversalMethod_dedup
+    | traversalMethod_difference
+    | traversalMethod_disjunct
     | traversalMethod_drop
     | traversalMethod_elementMap
     | traversalMethod_emit
@@ -221,6 +224,7 @@ traversalMethod
     | traversalMethod_identity
     | traversalMethod_in
     | traversalMethod_inE
+    | traversalMethod_intersect
     | traversalMethod_inV
     | traversalMethod_index
     | traversalMethod_inject
@@ -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,10 @@ traversalMethod_coin
     : 'coin' LPAREN floatArgument RPAREN
     ;
 
+traversalMethod_combine
+    : 'combine' LPAREN genericLiteralArgument RPAREN #traversalMethod_combine_Object
+    ;
+
 traversalMethod_connectedComponent
     : 'connectedComponent' LPAREN RPAREN
     ;
@@ -432,6 +443,14 @@ traversalMethod_dedup
     | 'dedup' LPAREN stringLiteralVarargs RPAREN #traversalMethod_dedup_String
     ;
 
+traversalMethod_difference
+    : 'difference' LPAREN genericLiteralArgument RPAREN #traversalMethod_difference_Object
+    ;
+
+traversalMethod_disjunct
+    : 'disjunct' LPAREN genericLiteralArgument RPAREN #traversalMethod_disjunct_Object
+    ;
+
 traversalMethod_drop
     : 'drop' LPAREN RPAREN
     ;
@@ -528,6 +547,10 @@ traversalMethod_inE
     : 'inE' LPAREN stringLiteralVarargs RPAREN
     ;
 
+traversalMethod_intersect
+    : 'intersect' LPAREN genericLiteralArgument RPAREN #traversalMethod_intersect_Object
+    ;
+
 traversalMethod_inV
     : 'inV' LPAREN RPAREN
     ;
@@ -545,6 +568,10 @@ traversalMethod_is
     | 'is' LPAREN traversalPredicate RPAREN #traversalMethod_is_P
     ;
 
+traversalMethod_conjoin
+    : 'conjoin' LPAREN stringArgument RPAREN #traversalMethod_conjoin_String
+    ;
+
 traversalMethod_key
     : 'key' LPAREN RPAREN
     ;
@@ -589,6 +616,10 @@ traversalMethod_mean
     | 'mean' LPAREN traversalScopeArgument RPAREN #traversalMethod_mean_Scope
     ;
 
+traversalMethod_merge
+    : 'merge' LPAREN genericLiteralArgument RPAREN #traversalMethod_merge_Object
+    ;
+
 traversalMethod_min
     : 'min' LPAREN RPAREN #traversalMethod_min_Empty
     | 'min' LPAREN traversalScopeArgument RPAREN #traversalMethod_min_Scope
@@ -649,6 +680,10 @@ traversalMethod_peerPressure
     : 'peerPressure' LPAREN RPAREN
     ;
 
+traversalMethod_product
+    : 'product' LPAREN genericLiteralArgument RPAREN #traversalMethod_product_Object
+    ;
+
 traversalMethod_profile
     : 'profile' LPAREN RPAREN #traversalMethod_profile_Empty
     | 'profile' LPAREN stringArgument RPAREN #traversalMethod_profile_String
@@ -687,6 +722,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 +901,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 +923,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..d98b6c14e5 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,10 +391,18 @@ 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
 
+    def conjoin(self, *args):
+        self.bytecode.add_step("conjoin", *args)
+        return self
+
     def connectedComponent(self, *args):
         warnings.warn(
             "gremlin_python.process.GraphTraversalSource.connectedComponent will be replaced by "
@@ -437,6 +445,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,6 +619,10 @@ 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
@@ -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,10 +1147,18 @@ 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)
 
+    @classmethod
+    def conjoin(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).conjoin(*args)
+
     @classmethod
     def constant(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).constant(*args)
@@ -1155,6 +1191,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 +1371,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 +1427,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 +1503,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 67824c6680..65f1b6a5b0 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -537,6 +537,24 @@ 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(__.inject(1)))], 
+    'g_V_valuesXnameX_combineXV_foldX': [(lambda g:g.V().name.combine(__.V().fold()))], 
+    'g_V_fold_combineXconstantXnullXX': [(lambda g:g.V().fold().combine(__.constant(None)))], 
+    'g_V_fold_combineXVX': [(lambda g:g.V().fold().combine(__.V()))], 
+    'g_V_valuesXnameX_fold_combineX2X': [(lambda g:g.V().name.fold().combine(2))], 
+    'g_V_valuesXnameX_fold_combineXnullX': [(lambda g:g.V().name.fold().combine(None))], 
+    'g_V_valuesXnonexistantX_fold_combineXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().combine(__.V().name.fold()))], 
+    'g_V_valuesXnameX_fold_combineXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().combine(__.V().nonexistant.fold()))], 
+    'g_V_valuesXageX_order_byXdescX_fold_combineXV_valuesXageX_order_byXdescX_foldX': [(lambda g:g.V().age.order().by(Order.desc).fold().combine(__.V().age.order().by(Order.desc).fold()))], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_combineXMARKOX': [(lambda g, xx1=None:g.V().out().path().by(__.name.to_upper()).combine(xx1))], 
+    'g_injectXxx1X_combineXV_valuesXnameX_foldX': [(lambda g, xx1=None:g.inject(xx1).combine(__.V().name.fold()))], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_combineXseattle_vancouverX': [(lambda g, xx1=None:g.V().valueMap('location').select(Column.values).unfold().combine(xx1))], 
+    'g_V_out_out_path_byXnameX_combineXempty_listX': [(lambda g, xx1=None:g.V().out().out().path().by('name').combine(xx1))], 
+    'g_V_valuesXageX_order_fold_combineXconstantX27X_foldX': [(lambda g:g.V().age.order().fold().combine(__.constant(27).fold()))], 
+    'g_V_out_out_path_byXnameX_combineXdave_kelvinX': [(lambda g, xx1=None:g.V().out().out().path().by('name').combine(xx1))], 
+    'g_injectXa_null_bX_combineXa_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).combine(xx2))], 
+    'g_injectXa_null_bX_combineXa_null_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).combine(xx2))], 
+    'g_injectX3_threeX_combineXfive_three_7X': [(lambda g, xx1=None,xx2=None:g.inject(xx1).combine(xx2))], 
     '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'))], 
@@ -551,6 +569,17 @@ world.gremlins = {
     'g_hasLabelXsoftwareX_asXaX_valuesXnameX_concatXunsesX_concatXselectXaXvaluesXlangX': [(lambda g:g.V().hasLabel('software').as_('a').name.concat(' uses ').concat(__.select('a').lang))], 
     'g_VX1X_outE_asXaX_constantXX_concatXVX1X_valuesXnameX_concatXselectXaX_label_concatXselectXaX_inV_valuesXnameX': [(lambda g, vid1=None:g.V(vid1).outE().as_('a').V(vid1).name.concat(__.select('a').label()).concat(__.select('a').in_v().name))], 
     'g_addVXconstantXprefix_X_concatXVX1X_labelX_label': [(lambda g, vid1=None: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').p [...]
+    'g_injectXnullX_conjoinX1X': [(lambda g:g.inject(None).conjoin('1'))], 
+    'g_V_valuesXnameX_conjoinX1X': [(lambda g:g.V().name.conjoin('1'))], 
+    'g_V_valuesXnonexistantX_fold_conjoinX_X': [(lambda g:g.V().nonexistant.fold().conjoin(';'))], 
+    'g_V_valuesXnameX_order_fold_conjoinX_X': [(lambda g:g.V().name.order().fold().conjoin('_'))], 
+    'g_V_valuesXageX_order_fold_conjoinX_X': [(lambda g:g.V().age.order().fold().conjoin(';'))], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_conjoinXMARKOX': [(lambda g:g.V().out().path().by(__.name.to_upper()).conjoin('MARKO'))], 
+    'g_injectXmarkoX_conjoinX_X': [(lambda g, xx1=None:g.inject(xx1).conjoin('-'))], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_conjoinX1X': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().conjoin('1'))], 
+    'g_V_out_out_path_byXnameX_conjoinXX': [(lambda g:g.V().out().out().path().by('name').conjoin(''))], 
+    'g_injectXa_null_bX_conjoinXxyzX': [(lambda g, xx1=None:g.inject(xx1).conjoin('xyz'))], 
+    'g_injectX3_threeX_conjoinX_X': [(lambda g, xx1=None:g.inject(xx1).conjoin(';'))], 
     'g_V_connectedComponent_hasXcomponentX': [(lambda g:g.V().connectedComponent().has('gremlin.connectedComponentVertexProgram.component'))], 
     'g_V_dedup_connectedComponent_hasXcomponentX': [(lambda g:g.V().dedup().connectedComponent().has('gremlin.connectedComponentVertexProgram.component'))], 
     'g_V_hasLabelXsoftwareX_connectedComponent_project_byXnameX_byXcomponentX': [(lambda g:g.V().hasLabel('software').connectedComponent().project('name','component').by('name').by('gremlin.connectedComponentVertexProgram.component'))], 
@@ -577,9 +606,45 @@ world.gremlins = {
     'g_injectXdatetimeXstrXX_dateAddXminute_10X': [(lambda g:g.inject(datetime.datetime.utcfromtimestamp(1690934400000 / 1000.0)).date_add(DT.minute,10))], 
     'g_injectXdatetimeXstrXX_dateAddXsecond_20X': [(lambda g:g.inject(datetime.datetime.utcfromtimestamp(1690934400000 / 1000.0)).date_add(DT.second,20))], 
     'g_injectXdatetimeXstrXX_dateAddXday_11X': [(lambda g:g.inject(datetime.datetime.utcfromtimestamp(1693958400000 / 1000.0)).date_add(DT.day,11))], 
-    'g_injectXdatetimeXXX_dateDiffXdatetimeXstrXX': [(lambda g:g.inject(datetime.datetime.utcfromtimestamp(1697149847363 / 1000.0)).date_diff(datetime.datetime.utcfromtimestamp(1673481600000 / 1000.0)).is_(P.gt(0)))], 
+    'g_injectXdatetimeXXX_dateDiffXdatetimeXstrXX': [(lambda g:g.inject(datetime.datetime.utcfromtimestamp(1697758666905 / 1000.0)).date_diff(datetime.datetime.utcfromtimestamp(1673481600000 / 1000.0)).is_(P.gt(0)))], 
     '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(__.inject(1)))], 
+    'g_V_valuesXnameX_differenceXV_foldX': [(lambda g:g.V().name.difference(__.V().fold()))], 
+    'g_V_fold_differenceXconstantXnullXX': [(lambda g:g.V().fold().difference(__.constant(None)))], 
+    'g_V_fold_differenceXVX': [(lambda g:g.V().fold().difference(__.V()))], 
+    'g_V_valuesXnameX_fold_differenceX2X': [(lambda g:g.V().name.fold().difference(2))], 
+    'g_V_valuesXnameX_fold_differenceXnullX': [(lambda g:g.V().name.fold().difference(None))], 
+    'g_V_valuesXnonexistantX_fold_differenceXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().difference(__.V().name.fold()))], 
+    'g_V_valuesXnameX_fold_differenceXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().difference(__.V().nonexistant.fold()))], 
+    'g_V_valuesXageX_fold_differenceXV_valuesXageX_foldX': [(lambda g:g.V().age.fold().difference(__.V().age.fold()))], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_differenceXMARKOX': [(lambda g, xx1=None:g.V().out().path().by(__.name.to_upper()).difference(xx1))], 
+    'g_injectXmarkoX_differenceXV_valuesXnameX_foldX': [(lambda g, xx1=None:g.inject(xx1).difference(__.V().name.fold()))], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_differenceXseattle_vancouverX': [(lambda g, xx1=None:g.V().valueMap('location').select(Column.values).unfold().difference(xx1))], 
+    'g_V_out_out_path_byXnameX_differenceXrippleX': [(lambda g, xx1=None:g.V().out().out().path().by('name').difference(xx1))], 
+    'g_V_out_out_path_byXnameX_differenceXempty_listX': [(lambda g, xx1=None:g.V().out().out().path().by('name').difference(xx1))], 
+    'g_V_valuesXageX_fold_differenceXconstantX27X_foldX': [(lambda g:g.V().age.fold().difference(__.constant(27).fold()))], 
+    'g_V_out_out_path_byXnameX_differenceXdave_kelvinX': [(lambda g, xx1=None:g.V().out().out().path().by('name').difference(xx1))], 
+    'g_injectXa_null_bX_differenceXa_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).difference(xx2))], 
+    'g_injectXa_null_bX_differenceXa_null_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).difference(xx2))], 
+    'g_injectX3_threeX_differenceXfive_three_7X': [(lambda g, xx1=None,xx2=None:g.inject(xx1).difference(xx2))], 
+    'g_injectXnullX_disjunctXinjectX1XX': [(lambda g:g.inject(None).disjunct(__.inject(1)))], 
+    'g_V_valuesXnameX_disjunctXV_foldX': [(lambda g:g.V().name.disjunct(__.V().fold()))], 
+    'g_V_fold_disjunctXconstantXnullXX': [(lambda g:g.V().fold().disjunct(__.constant(None)))], 
+    'g_V_fold_disjunctXVX': [(lambda g:g.V().fold().disjunct(__.V()))], 
+    'g_V_valuesXnameX_fold_disjunctX2X': [(lambda g:g.V().name.fold().disjunct(2))], 
+    'g_V_valuesXnameX_fold_disjunctXnullX': [(lambda g:g.V().name.fold().disjunct(None))], 
+    'g_V_valuesXnonexistantX_fold_disjunctXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().disjunct(__.V().name.fold()))], 
+    'g_V_valuesXnameX_fold_disjunctXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().disjunct(__.V().nonexistant.fold()))], 
+    'g_V_valuesXageX_fold_disjunctXV_valuesXageX_foldX': [(lambda g:g.V().age.fold().disjunct(__.V().age.fold()))], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_disjunctXMARKOX': [(lambda g, xx1=None:g.V().out().path().by(__.name.to_upper()).disjunct(xx1))], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_disjunctXseattle_vancouverX': [(lambda g, xx1=None:g.V().valueMap('location').select(Column.values).unfold().disjunct(xx1))], 
+    'g_V_out_out_path_byXnameX_disjunctXmarkoX': [(lambda g, xx1=None:g.V().out().out().path().by('name').disjunct(xx1))], 
+    'g_V_out_out_path_byXnameX_disjunctXstephen_markoX': [(lambda g, xx1=None:g.V().out().out().path().by('name').disjunct(xx1))], 
+    'g_V_out_out_path_byXnameX_disjunctXdave_kelvinX': [(lambda g, xx1=None:g.V().out().out().path().by('name').disjunct(xx1))], 
+    'g_injectXa_null_bX_disjunctXa_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).disjunct(xx2))], 
+    'g_injectXa_null_bX_disjunctXa_null_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).disjunct(xx2))], 
+    'g_injectX3_threeX_disjunctXfive_three_7X': [(lambda g, xx1=None,xx2=None:g.inject(xx1).disjunct(xx2))], 
     '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))], 
@@ -612,6 +677,23 @@ 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_injectXnullX_intersectXinjectX1XX': [(lambda g:g.inject(None).intersect(__.inject(1)))], 
+    'g_V_valuesXnameX_intersectXV_foldX': [(lambda g:g.V().name.intersect(__.V().fold()))], 
+    'g_V_fold_intersectXconstantXnullXX': [(lambda g:g.V().fold().intersect(__.constant(None)))], 
+    'g_V_fold_intersectXVX': [(lambda g:g.V().fold().intersect(__.V()))], 
+    'g_V_valuesXnameX_fold_intersectX2X': [(lambda g:g.V().name.fold().intersect(2))], 
+    'g_V_valuesXnameX_fold_intersectXnullX': [(lambda g:g.V().name.fold().intersect(None))], 
+    'g_V_valuesXnonexistantX_fold_intersectXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().intersect(__.V().name.fold()))], 
+    'g_V_valuesXnameX_fold_intersectXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().intersect(__.V().nonexistant.fold()))], 
+    'g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX_order_local': [(lambda g:g.V().age.fold().intersect(__.V().age.fold()).order(Scope.local))], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_intersectXMARKOX': [(lambda g, xx1=None:g.V().out().path().by(__.name.to_upper()).intersect(xx1))], 
+    'g_injectXmarkoX_intersectX___V_valuesXnameX_foldX': [(lambda g, xx1=None:g.inject(xx1).intersect(__.V().name.fold()))], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_intersectXseattle_vancouverX': [(lambda g, xx1=None:g.V().valueMap('location').select(Column.values).unfold().intersect(xx1))], 
+    'g_V_valuesXageX_fold_intersectX___constantX27X_foldX': [(lambda g:g.V().age.fold().intersect(__.constant(27).fold()))], 
+    'g_V_out_out_path_byXnameX_intersectXdave_kelvinX': [(lambda g, xx1=None:g.V().out().out().path().by('name').intersect(xx1))], 
+    'g_injectXa_null_bX_intersectXa_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).intersect(xx2))], 
+    'g_injectXa_null_bX_intersectXa_null_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).intersect(xx2))], 
+    'g_injectX3_threeX_intersectXfive_three_7X': [(lambda g, xx1=None,xx2=None:g.inject(xx1).intersect(xx2))], 
     '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())], 
@@ -709,6 +791,29 @@ 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(__.inject(1)))], 
+    'g_V_valuesXnameX_mergeXV_foldX': [(lambda g:g.V().name.merge(__.V().fold()))], 
+    'g_V_fold_mergeXconstantXnullXX': [(lambda g:g.V().fold().merge(__.constant(None)))], 
+    'g_V_fold_mergeXVX': [(lambda g:g.V().fold().merge(__.V()))], 
+    'g_V_elementMap_mergeXconstantXaXX': [(lambda g:g.V().elementMap().merge(__.constant('a')))], 
+    'g_V_fold_mergeXV_asXaX_projectXaX_byXnameXX': [(lambda g:g.V().fold().merge(__.V().as_('a').project('a').by('name')))], 
+    'g_V_fold_mergeXk_vX': [(lambda g, xx1=None:g.V().fold().merge(xx1))], 
+    'g_V_valuesXnameX_fold_mergeX2X': [(lambda g:g.V().name.fold().merge(2))], 
+    'g_V_valuesXnameX_fold_mergeXnullX': [(lambda g:g.V().name.fold().merge(None))], 
+    'g_V_valuesXnonexistantX_fold_mergeXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().merge(__.V().name.fold()))], 
+    'g_V_valuesXnameX_fold_mergeXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().merge(__.V().nonexistant.fold()))], 
+    'g_V_valuesXageX_fold_mergeXV_valuesXageX_foldX': [(lambda g:g.V().age.fold().merge(__.V().age.fold()))], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_mergeXMARKOX': [(lambda g, xx1=None:g.V().out().path().by(__.name.to_upper()).merge(xx1))], 
+    'g_injectXmarkoX_mergeXV_valuesXnameX_foldX': [(lambda g, xx1=None:g.inject(xx1).merge(__.V().name.fold()))], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_mergeXseattle_vancouverX': [(lambda g, xx1=None:g.V().valueMap('location').select(Column.values).unfold().merge(xx1))], 
+    'g_V_out_out_path_byXnameX_mergeXempty_listX': [(lambda g, xx1=None:g.V().out().out().path().by('name').merge(xx1))], 
+    'g_V_valuesXageX_fold_mergeXconstantX27X_foldX': [(lambda g:g.V().age.fold().merge(__.constant(27).fold()))], 
+    'g_V_out_out_path_byXnameX_mergeXdave_kelvinX': [(lambda g, xx1=None:g.V().out().out().path().by('name').merge(xx1))], 
+    'g_injectXa_null_bX_mergeXa_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).merge(xx2))], 
+    'g_injectXa_null_bX_mergeXa_null_cX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).merge(xx2))], 
+    'g_injectX3_threeX_mergeXfive_three_7X': [(lambda g, xx1=None,xx2=None:g.inject(xx1).merge(xx2))], 
+    'g_V_asXnameX_projectXnameX_byXnameX_mergeXother_blueprintX': [(lambda g, xx1=None:g.V().as_('name').project('name').by('name').merge(xx1))], 
+    'g_V_hasXname_markoX_elementMap_mergeXV_hasXname_lopX_elementMapX': [(lambda g:g.V().has('name','marko').elementMap().merge(__.V().has('name','lop').elementMap()))], 
     '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())], 
@@ -875,6 +980,23 @@ 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(__.inject(1)))], 
+    'g_V_valuesXnameX_productXV_foldX': [(lambda g:g.V().name.product(__.V().fold()))], 
+    'g_V_fold_productXconstantXnullXX': [(lambda g:g.V().fold().product(__.constant(None)))], 
+    'g_V_fold_productXVX': [(lambda g:g.V().fold().product(__.V()))], 
+    'g_V_valuesXnameX_fold_productX2X': [(lambda g:g.V().name.fold().product(2))], 
+    'g_V_valuesXnameX_fold_productXnullX': [(lambda g:g.V().name.fold().product(None))], 
+    'g_V_valuesXnonexistantX_fold_productXV_valuesXnameX_foldX': [(lambda g:g.V().nonexistant.fold().product(__.V().name.fold()))], 
+    'g_V_valuesXnameX_fold_productXV_valuesXnonexistantX_foldX': [(lambda g:g.V().name.fold().product(__.V().nonexistant.fold()))], 
+    '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(__.V().age.order().by(Order.asc)[0:2].fold()).unfold())], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_productXMARKOX_unfold': [(lambda g, xx1=None:g.V().out().path().by(__.name.to_upper()).product(xx1).unfold())], 
+    'g_injectXmarkoX_productXV_valuesXnameX_order_foldX_unfold': [(lambda g, xx1=None:g.inject(xx1).product(__.V().name.order().fold()).unfold())], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_productXdulles_seattle_vancouverX_unfold': [(lambda g, xx1=None:g.V().valueMap('location').select(Column.values).unfold().product(xx1).unfold())], 
+    'g_V_valuesXageX_order_byXascX_fold_productXconstantX27X_foldX_unfold': [(lambda g:g.V().age.order().by(Order.asc).fold().product(__.constant(27).fold()).unfold())], 
+    'g_V_out_out_path_byXnameX_productXdave_kelvinX_unfold': [(lambda g, xx1=None:g.V().out().out().path().by('name').product(xx1).unfold())], 
+    'g_injectXa_null_bX_productXa_cX_unfold': [(lambda g, xx1=None,xx2=None:g.inject(xx1).product(xx2).unfold())], 
+    'g_injectXa_null_bX_productXa_null_cX_unfold': [(lambda g, xx1=None,xx2=None:g.inject(xx1).product(xx2).unfold())], 
+    'g_injectX3_threeX_productXfive_three_7X_unfold': [(lambda g, xx1=None,xx2=None:g.inject(xx1).product(xx2).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')))], 
@@ -890,8 +1012,15 @@ world.gremlins = {
     '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())], 
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..6a9155e2c5 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,13 +235,8 @@ 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("(null)"), s -> null));
@@ -517,7 +518,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..607f50ae1b
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Combine.feature
@@ -0,0 +1,240 @@
+# 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"
+
+  @GraphComputerVerificationInjectionNotSupported
+  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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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_valuesXnameX_fold_combineX2X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().combine(2)
+      """
+    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 as an argument, encountered"
+
+  Scenario: g_V_valuesXnameX_fold_combineXnullX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().combine(null)
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Argument provided for combine step can't be null"
+
+  @GraphComputerVerificationInjectionNotSupported
+  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] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  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] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @MultiMetaProperties
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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_order_fold_combineXconstantX27X_foldX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").order().fold().combine(__.constant(27).fold())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[27].i,d[29].i,d[32].i,d[35].i,d[27].i] |
+
+  @GraphComputerVerificationReferenceOnly
+  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/Conjoin.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Conjoin.feature
new file mode 100644
index 0000000000..e142bdb458
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Conjoin.feature
@@ -0,0 +1,155 @@
+# 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 @StepConjoin
+Feature: Step - conjoin()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_conjoinX1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).conjoin("1")
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for conjoin step can't be null"
+
+  Scenario: g_V_valuesXnameX_conjoinX1X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").conjoin("1")
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "conjoin step can only take an array or an Iterable type for incoming traversers, encountered"
+
+  Scenario: g_V_valuesXnonexistantX_fold_conjoinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().conjoin(";")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | str[] |
+
+  Scenario: g_V_valuesXnameX_order_fold_conjoinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").order().fold().conjoin("_")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | josh_lop_marko_peter_ripple_vadas |
+
+  Scenario: g_V_valuesXageX_order_fold_conjoinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").order().fold().conjoin(";")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | 27;29;32;35 |
+
+  @GraphComputerVerificationReferenceOnly
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_conjoinXMARKOX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).conjoin("MARKO")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | MARKOMARKOLOP |
+      | MARKOMARKOVADAS |
+      | MARKOMARKOJOSH |
+      | JOSHMARKORIPPLE |
+      | JOSHMARKOLOP |
+      | PETERMARKOLOP |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXmarkoX_conjoinX_X
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.inject(xx1).conjoin("-")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | marko |
+
+  @MultiMetaProperties
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_conjoinX1X
+    Given the crew graph
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().conjoin("1")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | san diego1santa cruz1brussels1santa fe |
+      | centreville1dulles1purcellville |
+      | bremen1baltimore1oakland1seattle |
+      | spremberg1kaiserslautern1aachen |
+
+  @GraphComputerVerificationReferenceOnly
+  Scenario: g_V_out_out_path_byXnameX_conjoinXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").conjoin("")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | markojoshripple |
+      | markojoshlop |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_conjoinXxyzX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And the traversal of
+      """
+      g.inject(xx1).conjoin("xyz")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | str[axyznullxyzb] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_conjoinX_X
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And the traversal of
+      """
+      g.inject(xx1).conjoin(";")
+      """
+    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/Difference.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Difference.feature
new file mode 100644
index 0000000000..82b37b1b23
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Difference.feature
@@ -0,0 +1,254 @@
+# 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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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_valuesXnameX_fold_differenceX2X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().difference(2)
+      """
+    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 as an argument, encountered"
+
+  Scenario: g_V_valuesXnameX_fold_differenceXnullX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().difference(null)
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Argument provided for difference step can't be null"
+
+  @GraphComputerVerificationMidVNotSupported
+  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[] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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[] |
+
+  @GraphComputerVerificationReferenceOnly
+  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[] |
+
+  @MultiMetaProperties
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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..610fe3fc0c
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Disjunct.feature
@@ -0,0 +1,230 @@
+# 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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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_valuesXnameX_fold_disjunctX2X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().disjunct(2)
+      """
+    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 as an argument, encountered"
+
+  Scenario: g_V_valuesXnameX_fold_disjunctXnullX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().disjunct(null)
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Argument provided for disjunct step can't be null"
+
+  @GraphComputerVerificationMidVNotSupported
+  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] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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[] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @MultiMetaProperties
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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..db6f26df9b
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Intersect.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 @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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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"
+
+  Scenario: g_V_valuesXnameX_fold_intersectX2X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().intersect(2)
+      """
+    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 as an argument, encountered"
+
+  Scenario: g_V_valuesXnameX_fold_intersectXnullX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().intersect(null)
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Argument provided for intersect step can't be null"
+
+  @GraphComputerVerificationMidVNotSupported
+  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[] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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[] |
+
+  @GraphComputerVerificationMidVNotSupported
+  Scenario: g_V_valuesXageX_fold_intersectXV_valuesXageX_foldX_order_local
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").fold().intersect(__.V().values("age").fold()).order(Scope.local)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[27].i,d[29].i,d[32].i,d[35].i] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @MultiMetaProperties
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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/Merge.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Merge.feature
new file mode 100644
index 0000000000..253b3ec0a9
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Merge.feature
@@ -0,0 +1,300 @@
+# 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
+
+  @GraphComputerVerificationMidVNotSupported
+  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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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_valuesXnameX_fold_mergeX2X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().merge(2)
+      """
+    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 as an argument, encountered"
+
+  Scenario: g_V_valuesXnameX_fold_mergeXnullX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().merge(null)
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Argument provided for merge step can't be null"
+
+  @GraphComputerVerificationMidVNotSupported
+  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] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @MultiMetaProperties
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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"}] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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..1693debd27
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Product.feature
@@ -0,0 +1,311 @@
+# 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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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"
+
+  @GraphComputerVerificationMidVNotSupported
+  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_valuesXnameX_fold_productX2X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().product(2)
+      """
+    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 as an argument, encountered"
+
+  Scenario: g_V_valuesXnameX_fold_productXnullX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").fold().product(null)
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Argument provided for product step can't be null"
+
+  @GraphComputerVerificationMidVNotSupported
+  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[] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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[] |
+
+  @GraphComputerVerificationMidVNotSupported
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @MultiMetaProperties
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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..8864378fea 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,106 @@ 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 |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |
+
+  @GraphComputerVerificationReferenceOnly
+  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] |