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 01:14:32 UTC

[tinkerpop] branch TINKERPOP-2978-3 updated (c0beabc3ce -> 1e2c1a1bf7)

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 c0beabc3ce remove traversal parameter for list functions
 discard a4da4fcc43 revert collectionutil
 discard 5da6785a39 Implement list functions.
     add 83f7f76d13 Change typescript support to the more recent DefinitelyTyped CTR
     add 700b7e7784 Added post-release step for release manager to consider typescript CTR
     add aa42d746b2 Bump github.com/cucumber/godog from 0.12.6 to 0.13.0 in /gremlin-go (#2214)
     add 06bb17d23b Bump golang.org/x/text from 0.12.0 to 0.13.0 in /gremlin-go (#2230)
     add 8688ef61c0 Bump @types/node from 20.5.0 to 20.8.6 in /gremlint (#2290)
     add 9c1002054c Merge branch '3.5-dev' into 3.6-dev
     add c5488fa19a Merge branch '3.6-dev'
     add 3fd6e78662 Upgrade docs/gremlint node to 18 and npm audit fix (#2295)
     add 501337ae8a Bump xunit from 2.4.2 to 2.5.3 in /gremlin-dotnet
     add b10347762c Merge branch 'dependabot/nuget/gremlin-dotnet/3.5-dev/xunit-2.5.3' into 3.5-dev
     add 1e51ac8665 Bump xunit.runner.visualstudio from 2.5.1 to 2.5.3 in /gremlin-dotnet
     add 873a47dcad Merge branch 'dependabot/nuget/gremlin-dotnet/3.5-dev/xunit.runner.visualstudio-2.5.3' into 3.5-dev
     add 3a5dedb3f5 Merge branch '3.5-dev' into 3.6-dev
     add 78075f37a5 Merge branch '3.6-dev'
     add 96ac0ac81a Bump gherkin from 26.0.3 to 27.0.0 in /gremlin-dotnet
     add eb1962db2a Merge branch 'dependabot/nuget/gremlin-dotnet/3.5-dev/gherkin-27.0.0' into 3.5-dev
     add d0a19dbc9c Bump BenchmarkDotNet from 0.13.8 to 0.13.9 in /gremlin-dotnet
     add 733bec970b Merge branch 'dependabot/nuget/gremlin-dotnet/3.5-dev/BenchmarkDotNet-0.13.9' into 3.5-dev
     add 76b4cfab3b Merge branch '3.5-dev' into 3.6-dev
     add 1222c257b6 Merge branch '3.6-dev'
     add ed9b6c5aa8 Squashed docs/gremlint dependabots:
     add 81775cbcaf Change substring() to use `startIndex, endIndex` instead of `startIndex, length` (#2296)
     add 3cf2f94446 [TINKERPOP-2979] added datetime() (#2289)
     add de4ac90dda [TINKERPOP-2423] Do not use XOR in hashCode computation when redundant parameters are used (#2254)
     add 3c4418ba24 Merge branch '3.6-dev'
     new 1e2c1a1bf7 Implement list functions. fix traversalmethodvisitortest issues with list comparison update tag for crew graph remove traversal constructor, fix typo, remove unused file remove traversal parameter for list functions ignore tests as set not implemented for gremlin-js update signature for dotnet

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   (c0beabc3ce)
            \
             N -- N -- N   refs/heads/TINKERPOP-2978-3 (1e2c1a1bf7)

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:
 CHANGELOG.asciidoc                                 |   2 +
 docs/gremlint/package-lock.json                    | 685 +++++++++------------
 docs/gremlint/package.json                         |  10 +-
 docs/site/home/community.html                      |   8 +-
 docs/src/dev/developer/release.asciidoc            |   1 +
 docs/src/dev/provider/gremlin-semantics.asciidoc   |   8 +-
 docs/src/upgrade/release-3.7.x.asciidoc            |  68 +-
 .../tinkerpop/gremlin/jsr223/CoreImports.java      |   1 +
 .../language/grammar/GenericLiteralVisitor.java    |   2 +
 .../traversal/dsl/graph/GraphTraversal.java        |  18 +-
 .../gremlin/process/traversal/dsl/graph/__.java    |   4 +-
 .../process/traversal/step/map/GraphStep.java      |   8 +-
 .../process/traversal/step/map/PropertiesStep.java |  15 +-
 .../process/traversal/step/map/SubstringStep.java  |  43 +-
 .../process/traversal/step/map/VertexStep.java     |  15 +-
 .../step/sideEffect/SideEffectCapStep.java         |   9 +-
 .../tinkerpop/gremlin/util/DatetimeHelper.java     |   7 +
 .../grammar/GeneralLiteralVisitorTest.java         |  12 +
 .../process/traversal/step/map/GraphStepTest.java  |  27 +
 .../traversal/step/map/PropertiesStepTest.java     |  42 ++
 .../traversal/step/map/SubstringStepTest.java      |  28 +-
 .../process/traversal/step/map/VertexStepTest.java |  28 +
 .../step/sideEffect/SideEffectCapStepTest.java     |  28 +
 .../Process/Traversal/GraphTraversal.cs            |  16 +-
 .../src/Gremlin.Net/Process/Traversal/__.cs        |   4 +-
 .../Gremlin.Net.Benchmarks.csproj                  |   2 +-
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs |  12 +-
 .../Gremlin.Net.IntegrationTest.csproj             |   6 +-
 .../Gremlin.Net.Template.IntegrationTest.csproj    |   4 +-
 .../Gremlin.Net.UnitTest.csproj                    |   4 +-
 gremlin-go/driver/cucumber/gremlin.go              |  12 +-
 gremlin-go/go.mod                                  |  12 +-
 gremlin-go/go.sum                                  |  48 +-
 .../gremlin-javascript/test/cucumber/gremlin.js    |  12 +-
 gremlin-language/src/main/antlr4/Gremlin.g4        |   1 +
 gremlin-python/src/main/python/radish/gremlin.py   |  12 +-
 .../gremlin/test/features/map/DateDiff.feature     |  10 +
 .../gremlin/test/features/map/Substring.feature    |  46 +-
 gremlint/package-lock.json                         |  34 +-
 39 files changed, 715 insertions(+), 589 deletions(-)


[tinkerpop] 01/01: Implement list functions. fix traversalmethodvisitortest issues with list comparison update tag for crew graph remove traversal constructor, fix typo, remove unused file remove traversal parameter for list functions ignore tests as set not implemented for gremlin-js update signature for dotnet

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 1e2c1a1bf7aa35b3b8bec90399e11a1279d87493
Author: Ken Hu <10...@users.noreply.github.com>
AuthorDate: Mon Sep 18 13:25:56 2023 -0700

    Implement list functions.
    fix traversalmethodvisitortest issues with list comparison
    update tag for crew graph
    remove traversal constructor, fix typo, remove unused file
    remove traversal parameter for list functions
    ignore tests as set not implemented for gremlin-js
    update signature for dotnet
---
 .../dev/future/proposal-3-remove-closures.asciidoc |  34 ++-
 docs/src/dev/provider/gremlin-semantics.asciidoc   | 250 +++++++++++++++++-
 docs/src/reference/the-traversal.asciidoc          | 137 +++++++++-
 docs/src/upgrade/release-3.7.x.asciidoc            |  28 +-
 .../grammar/DefaultGremlinBaseVisitor.java         |  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/DifferenceStep.java |  99 +++++++
 .../process/traversal/step/map/DisjunctStep.java   | 109 ++++++++
 .../process/traversal/step/map/IntersectStep.java  | 100 +++++++
 .../process/traversal/step/map/JoinStep.java       |  80 ++++++
 .../process/traversal/step/map/ProductStep.java    | 103 ++++++++
 .../process/traversal/step/map/ReverseStep.java    |  36 ++-
 .../traversal/step/map/TraversalMergeStep.java     | 131 +++++++++
 .../process/traversal/util/BytecodeHelper.java     |  14 +
 .../process/traversal/util/ListFunction.java       | 199 ++++++++++++++
 .../gremlin/util/iterator/IteratorUtils.java       |   4 +
 .../grammar/TraversalMethodVisitorTest.java        |  73 +++++
 ...{ReverseStepTest.java => DisjunctStepTest.java} |  18 +-
 .../traversal/step/map/ReverseStepTest.java        |  20 +-
 .../Process/Traversal/GraphTraversal.cs            |  67 ++++-
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 121 ++++++++-
 gremlin-go/driver/anonymousTraversal.go            |  49 ++++
 gremlin-go/driver/cucumber/gremlin.go              | 121 ++++++++-
 gremlin-go/driver/graphTraversal.go                |  43 +++
 .../lib/process/graph-traversal.js                 |  70 +++++
 .../test/cucumber/feature-steps.js                 |  46 ++++
 .../gremlin-javascript/test/cucumber/gremlin.js    | 121 ++++++++-
 gremlin-language/src/main/antlr4/Gremlin.g4        |  55 +++-
 .../gremlin_python/process/graph_traversal.py      |  52 ++++
 gremlin-python/src/main/python/radish/gremlin.py   | 121 ++++++++-
 gremlin-server/src/assembly/standalone.xml         |   8 -
 .../tinkerpop/gremlin/features/StepDefinition.java |  17 +-
 .../gremlin/test/features/map/Combine.feature      | 222 ++++++++++++++++
 .../gremlin/test/features/map/Difference.feature   | 236 +++++++++++++++++
 .../gremlin/test/features/map/Disjunct.feature     | 212 +++++++++++++++
 .../gremlin/test/features/map/Intersect.feature    | 208 +++++++++++++++
 .../gremlin/test/features/map/Join.feature         | 155 +++++++++++
 .../gremlin/test/features/map/Merge.feature        | 282 ++++++++++++++++++++
 .../gremlin/test/features/map/Product.feature      | 293 +++++++++++++++++++++
 .../gremlin/test/features/map/Reverse.feature      | 114 +++++++-
 43 files changed, 4304 insertions(+), 89 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..8201e11d6a 100644
--- a/docs/src/dev/provider/gremlin-semantics.asciidoc
+++ b/docs/src/dev/provider/gremlin-semantics.asciidoc
@@ -725,6 +725,43 @@ link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/o
 link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/service/ServiceRegistry.java[ServiceRegistry],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#call-step[reference]
 
+[[combine-step]]
+=== combine()
+
+*Description:* Appends one list to the other and returns the result to the Traversal Stream.
+
+*Syntax:* `combine(Object)` | `combine(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A list is returned after the combine operation is applied so duplicates are allowed. `Merge` can be used instead if
+duplicates aren't wanted. This step only applies to list types which means that non-iterable types (including null)
+will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/CombineStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#combine-step[reference],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#merge-step[reference],
+
 [[concat-step]]
 === concat()
 
@@ -871,6 +908,77 @@ can return any of:
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#dedup-step[reference]
 
+[[difference-step]]
+=== difference()
+
+*Description:* Adds the difference of two lists to the Traversal Stream. 
+
+*Syntax:* `difference(Object)` | `difference(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+Set difference (`A-B`) is an ordered operation. The incoming traverser is treated as `A` and the provided argument is
+treated as `B`. A set is returned after the difference operation is applied so there won't be duplicates. This step only
+applies to list types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DifferenceStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#difference-step[reference]
+
+[[disjunct-step]]
+=== disjunct()
+
+*Description:* Adds the disjunct set to the Traversal Stream.
+
+*Syntax:* `disjunct(Object)` | `disjunct(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A set is returned after the disjunct operation is applied so there won't be duplicates. This step only applies to list
+types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DisjunctStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#disjunct-step[reference]
+
 [[element-step]]
 === element()
 
@@ -917,6 +1025,76 @@ Null values from the incoming traverser are not processed and remain as null whe
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LengthStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#length-step[reference]
 
+[[intersect-step]]
+=== intersect()
+
+*Description:* Adds the intersection to the Traversal Stream.
+
+*Syntax:* `intersect(Object)` | `intersect(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A set is returned after the intersect operation is applied so there won't be duplicates. This step only applies to list
+types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IntersectStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#intersect-step[reference]
+
+[[join-step]]
+=== join()
+
+*Description:* Joins every element in a list together into a String. 
+
+*Syntax:* `join(String)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`String`
+|=========================================================
+
+*Arguments:*
+
+* `String` - A delimiter to use to join the elements together. Can't be null.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+Every element in the list (including nulls) is converted to a String. The delimiter is inserted between neighboring
+elements to form the final result. This step only applies to list types which means that non-iterable types (including
+null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/JoinStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#join-step[reference]
+
 [[lTrim-step]]
 === lTrim()
 
@@ -943,6 +1121,41 @@ Null values from the incoming traverser are not processed and remain as null whe
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LTrimStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#lTrim-step[reference]
 
+[[merge-step]]
+=== merge()
+
+*Description:* Adds the union of two sets to the Traversal Stream.
+
+*Syntax:* `merge(Object)` | `merge(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`Set`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A set is returned after the merge operation is applied so there won't be duplicates. This step only applies to list
+types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/MergeStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#merge-step[reference]
+
 [[merge-e-step]]
 === mergeE()
 
@@ -1085,6 +1298,41 @@ resolve to a `Map`.
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeVertexStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#mergev-step[reference]
 
+[[product-step]]
+=== product()
+
+*Description:* Adds the cartesian product to the Traversal Stream.
+
+*Syntax:* `product(Object)` | `product(Traversal)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`array`/`Iterable` |`List(List)`
+|=========================================================
+
+*Arguments:*
+
+* `Object` - A list of items (as an Iterable or an array).
+* `Traversal` - A traversal that will produce a list of items.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+A list of lists is returned after the product operation is applied with the inner list being a result pair. This step only
+applies to list types which means that non-iterable types (including null) will cause exceptions to be thrown.
+
+*Exceptions*
+
+* If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+* If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/ProductStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#product-step[reference]
+
 [[replace-step]]
 === replace()
 
@@ -1113,7 +1361,7 @@ Null values from the incoming traverser are not processed and remain as null whe
 See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReplaceStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#replace-step[reference]
 
-
+[[reverse-step]]
 === reverse()
 
 *Description:* Returns a reversed string of the incoming string traverser
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index 76eb708543..54f1931144 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -1140,6 +1140,25 @@ g.V().coin(1.0)
 
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#coin-double-++[`coin(double)`]
 
+[[combine-step]]
+=== Combine Step
+
+The `combine()`-step (*map*) combines the elements of the incoming list traverser and the provided list argument into
+one list. This is also known as appending or concatenating. This step only expects list data (array or Iterable) and
+will throw an `IllegalArgumentException` if any other type is encountered (including null). This differs from the
+`merge` step in that it allows duplicates to exist.
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().combine(["james","jen","marko","vadas"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#combine-Object++[`combine(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#combine-Traversal++[`combine(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#combine-step++[`Semantics`]
+
 [[concat-step]]
 === Concat Step
 
@@ -1382,6 +1401,45 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`],
 link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#dedup-step++[`Semantics`]
 
+[[difference-step]]
+=== Difference Step
+
+The `difference()`-step (*map*) calculates the difference between the incoming list traverser and the provided list
+argument. More specifically, this provides the set operation A-B where A is the traverser and B is the argument. This
+step only expects list data (array or Iterable) and will throw an `IllegalArgumentException` if any other type is
+encountered (including null).
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().difference(["lop","ripple"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#difference-Object++[`difference(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#difference-Traversal++[`difference(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#difference-step++[`Semantics`]
+
+[[disjunct-step]]
+=== Disjunct Step
+
+The `disjunct()`-step (*map*) calculates the disjunct set between the incoming list traverser and the provided list
+argument. This step only expects list data (array or Iterable) and will throw an `IllegalArgumentException` if any other
+type is encountered (including null).
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().disjunct(["lop","peter","sam"]) <1>
+----
+
+<1> Find the unique names between two group of names
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#disjunct-Object++[`disjunct(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#disjunct-Traversal++[`disjunct(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#disjunct-step++[`Semantics`]
+
 [[drop-step]]
 === Drop Step
 
@@ -1881,6 +1939,24 @@ inject(1,2).map {it.get() + 1}.map {g.V(it.get()).next()}.values('name')
 
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#inject-E...-++[`inject(Object)`]
 
+[[intersect-step]]
+=== Intersect Step
+
+The `intersect()`-step (*map*) calculates the intersection between the incoming list traverser and the provided list
+argument. This step only expects list data (array or Iterable) and will throw an `IllegalArgumentException` if any other
+type is encountered (including null).
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().intersect(["marko","josh","james","jen"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#intersect-Object++[`intersect(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#intersect-Traversal++[`intersect(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#intersect-step++[`Semantics`]
+
 anchor:_gremlin_i_o[]
 [[io-step]]
 === IO Step
@@ -2089,6 +2165,24 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#is-org.apache.tinkerpop.gremlin.process.traversal.P-++[`is(P)`],
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`]
 
+[[join-step]]
+=== Join Step
+
+The `join()`-step (*map*) joins together the elements in the incoming list traverser together with the provided argument
+as a delimiter. The resulting `String` is added to the Traversal Stream. This step only expects list data (array or
+Iterable) in the incoming traverser and will throw an `IllegalArgumentException` if any other type is encountered
+(including null). However, null is allowed as an element within the list and is converted to "null".
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().join("+")
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#join-String++[`join(String)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#join-step++[`Semantics`]
+
 [[key-step]]
 === Key Step
 
@@ -2614,6 +2708,25 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#mean-org.apache.tinkerpop.gremlin.process.traversal.Scope-++[`mean(Scope)`],
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html++[`Scope`]
 
+[[merge-step]]
+=== Merge Step
+
+The `merge()`-step (*map*) merges the elements of the incoming list traverser and the provided list argument into one
+list. This is also known as the union operation. This step only expects list data (array or Iterable) and will throw
+an `IllegalArgumentException` if any other type is encountered (including null). This differs from the `combine`
+step in that it doesn't allow duplicates.
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().merge(["james","jen","marko","vadas"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#merge-Object++[`merge(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#merge-Traversal++[`merge(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#merge-step++[`Semantics`]
+
 [[mergeedge-step]]
 === MergeEdge Step
 
@@ -3347,6 +3460,24 @@ configuration keys from the `PeerPressure` class and is automatically imported t
 
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#peerPressure--++[`peerPressure()`]
 
+[[product-step]]
+=== Product Step
+
+The `product()`-step (*map*) calculates the cartesian product between the incoming list traverser and the provided list
+argument. This step only expects list data (array or Iterable) and will throw an `IllegalArgumentException` if any
+other type is encountered (including null).
+
+[gremlin-groovy,modern]
+----
+g.V().values("name").fold().product(["james","jen"])
+----
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#product-Object++[`product(Object)`]
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#product-Traversal++[`product(Traversal)`]
+link:++https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#product-step++[`Semantics`]
+
 [[profile-step]]
 === Profile Step
 
@@ -3759,12 +3890,14 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre
 [[reverse-step]]
 === Reverse Step
 
-The `reverse()`-step (*map*) returns a reversed string of the incoming string traverser. Null values are not processed and remain
-as null when returned. If the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown.
+The `reverse()`-step (*map*) returns a reversed of the incoming list traverser. Single values (including null) are not
+processed and are added back to the Traversal Stream unchanged. If the incoming traverser is a String value then the
+reversed String will be returned.
 
 [gremlin-groovy,modern]
 ----
 g.V().values("name").reverse()
+g.V().values("name").fold().reverse()
 ----
 
 link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#reverse--++[`reverse()`]
diff --git a/docs/src/upgrade/release-3.7.x.asciidoc b/docs/src/upgrade/release-3.7.x.asciidoc
index 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..d121da91c1 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,10 @@ 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}
 	 */
@@ -343,6 +347,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 +519,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}
 	 */
@@ -527,6 +543,10 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
 	 * {@inheritDoc}
 	 */
 	@Override public T visitTraversalMethod_is_P(final GremlinParser.TraversalMethod_is_PContext ctx) { notImplemented(ctx); return null; }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override public T visitTraversalMethod_join_String(final GremlinParser.TraversalMethod_join_StringContext ctx) { notImplemented(ctx); return null; }
 	/**
 	 * {@inheritDoc}
 	 */
@@ -583,6 +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..42c7736581 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}
      */
@@ -490,6 +498,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 +850,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}
      */
@@ -863,6 +895,14 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
         return graphTraversal.is(antlr.traversalPredicateVisitor.visitTraversalPredicate(ctx.traversalPredicate()));
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_join_String(final GremlinParser.TraversalMethod_join_StringContext ctx) {
+        return graphTraversal.join(antlr.argumentVisitor.parseString(ctx.stringArgument()));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -1018,6 +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..c27ade111e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -86,6 +86,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsDateStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsStringStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CallStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CoalesceStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.CombineStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConcatStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConstantStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
@@ -93,6 +94,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DateAddStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DateDiffStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DedupLocalStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.DifferenceStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.DisjunctStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeOtherVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ElementMapStep;
@@ -103,7 +106,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IdStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IndexStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.IntersectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LTrimStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.JoinStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LabelStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaCollectingBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaFlatMapStep;
@@ -124,6 +129,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProductStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProjectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyKeyStep;
@@ -146,6 +152,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.ToLowerStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ToUpperStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalFlatMapStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMapStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMergeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalSelectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TreeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TrimStep;
@@ -197,6 +204,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -1549,15 +1557,13 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     /**
-     * Returns a reversed string of the incoming string traverser. Null values are not processed and
-     * remain as null when returned. If the incoming traverser is a non-String value then an
-     * {@code IllegalArgumentException} will be thrown.
+     * Returns the reverse of the incoming traverser. Null values are not processed and remain as null when returned.
      *
      * @return the traversal with an appended {@link ReverseStep}.
      * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#reverse-step" target="_blank">Reference Documentation - Reverse Step</a>
      * @since 3.7.1
      */
-    public default GraphTraversal<S, String> reverse() {
+    public default GraphTraversal<S, E> reverse() {
         this.asAdmin().getBytecode().addStep(Symbols.reverse);
         return this.asAdmin().addStep(new ReverseStep<>(this.asAdmin()));
     }
@@ -1672,6 +1678,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 JoinStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#join-step" target="_blank">Reference Documentation - Join Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, String> join(final String delimiter) {
+        this.asAdmin().getBytecode().addStep(Symbols.join, delimiter);
+        return this.asAdmin().addStep(new JoinStep<>(this.asAdmin(), delimiter));
+    }
+
+    /**
+     * Merges the list traverser and list argument. Also known as union.
+     *
+     * @return the traversal with an appended {@link TraversalMergeStep}.
+     * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#merge-step" target="_blank">Reference Documentation - Merge Step</a>
+     * @since 3.7.1
+     */
+    public default GraphTraversal<S, E> merge(final Object values) {
+        this.asAdmin().getBytecode().addStep(Symbols.merge, 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 join = "join";
         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..4d37a32950 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
@@ -41,6 +41,7 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -652,14 +653,20 @@ public class __ {
         return __.<A>start().rTrim();
     }
 
-
     /**
      * @see GraphTraversal#reverse()
      */
-    public static <A> GraphTraversal<A, String> reverse() {
+    public static <A> GraphTraversal<A, A> reverse() {
         return __.<A>start().reverse();
     }
 
+    /**
+     * @see GraphTraversal#reverse()
+     */
+//    public static <A> GraphTraversal<A, List<?>> reverse() {
+//        return __.<A>start().reverse();
+//    }
+
     /**
      * @see GraphTraversal#replace(String, String)
      */
@@ -716,6 +723,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#join(String)
+     */
+    public static <A> GraphTraversal<A, String> join(final String values) {
+        return __.<A>start().join(values);
+    }
+
+    /**
+     * @see GraphTraversal#merge(Object)
+     */
+    public static <A> GraphTraversal<A, 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..7ee8a1bb5f
--- /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 != parameterItems) ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, valueTraversal);
+
+        final List combined = new ArrayList(listA);
+        combined.addAll(listB);
+
+        return combined;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public CombineStep<S, E> clone() {
+        final CombineStep<S, E> clone = (CombineStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStep.java
new file mode 100644
index 0000000000..f394bd799e
--- /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 != parameterItems) ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, valueTraversal);
+        final Set differenceSet = new HashSet();
+
+        for (Object element : setA) {
+            if (!setB.contains(element)) {
+                differenceSet.add(element);
+            }
+        }
+
+        return differenceSet;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public DifferenceStep<S, E> clone() {
+        final DifferenceStep<S, E> clone = (DifferenceStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStep.java
new file mode 100644
index 0000000000..10725330f2
--- /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 != parameterItems) ? convertArgumentToSet(parameterItems) : convertTraversalToSet(traverser, this.valueTraversal);
+        final Set disjunctSet = new HashSet();
+
+        if (setA.size() == 0) {
+            return setB;
+        } else if (setB.size() == 0) {
+            return setA;
+        } else {
+            for (Object item : setA) {
+                if (!setB.contains(item)) {
+                    disjunctSet.add(item);
+                }
+            }
+
+            for (Object item : setB) {
+                if (!setA.contains(item)) {
+                    disjunctSet.add(item);
+                }
+            }
+        }
+
+        return disjunctSet;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public DisjunctStep<S, E> clone() {
+        final DisjunctStep<S, E> clone = (DisjunctStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStep.java
new file mode 100644
index 0000000000..7a3ad16090
--- /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 != parameterItems) ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, this.valueTraversal);
+        final Set intersection = new HashSet();
+
+        for (Object element : setB) {
+            if (setA.contains(element)) {
+                intersection.add(element);
+            }
+        }
+
+        return intersection;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public IntersectStep<S, E> clone() {
+        final IntersectStep<S, E> clone = (IntersectStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/JoinStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/JoinStep.java
new file mode 100644
index 0000000000..f766353657
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/JoinStep.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the result of joining every element in the traverser using the delimiter argument.
+ */
+public final class JoinStep<S> extends ScalarMapStep<S, String> implements ListFunction {
+    private String delimiter;
+
+    public JoinStep(final Traversal.Admin traversal, final String delimiter) {
+        super(traversal);
+        if (null == delimiter) { throw new IllegalArgumentException("Input delimiter to join step can't be null."); }
+        this.delimiter = delimiter;
+    }
+
+    @Override
+    public String getStepName() { return "join"; }
+
+    @Override
+    protected String map(Traverser.Admin<S> traverser) {
+        final Collection elements = convertTraverserToCollection(traverser);
+
+        final StringBuilder joinResult = new StringBuilder();
+
+        for (Object elem : elements) {
+            joinResult.append(String.valueOf(elem)).append(delimiter);
+        }
+
+        if (joinResult.length() != 0) {
+            joinResult.delete(joinResult.length() - delimiter.length(), joinResult.length());
+        }
+
+        return joinResult.toString();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return Collections.singleton(TraverserRequirement.OBJECT); }
+
+    @Override
+    public JoinStep<S> clone() {
+        final JoinStep<S> clone = (JoinStep<S>) super.clone();
+        clone.delimiter = this.delimiter;
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, delimiter);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStep.java
new file mode 100644
index 0000000000..c78794f8af
--- /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 != parameterItems) ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, this.valueTraversal);
+        final List elements = new ArrayList();
+
+        for (Object elementInA : listA) {
+            for (Object elementInB : listB) {
+                final List pair = new ArrayList(2);
+                pair.add(elementInA);
+                pair.add(elementInB);
+                elements.add(pair);
+            }
+        }
+
+        return elements;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public ProductStep<S, E> clone() {
+        final ProductStep<S, E> clone = (ProductStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java
index 0d7258b796..fc1a143341 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java
@@ -21,35 +21,45 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 
+import static org.apache.tinkerpop.gremlin.util.CollectionUtil.asList;
+
 /**
- * Reference implementation for reverse() step, a mid-traversal step which returns a reversed string.
- * Null values are not processed and remain as null when returned. If the incoming traverser is a non-String value
- * then an {@code IllegalArgumentException} will be thrown.
+ * Reference implementation for reverse() step, a mid-traversal step which returns the reverse value.
+ * Null values are not processed and remain as null when returned.
  *
  * @author David Bechberger (http://bechberger.com)
  * @author Yang Xia (http://github.com/xiazcy)
  */
-public final class ReverseStep<S> extends ScalarMapStep<S, String> {
+public final class ReverseStep<S, E> extends ScalarMapStep<S, E> {
 
     public ReverseStep(final Traversal.Admin traversal) {
         super(traversal);
     }
 
     @Override
-    protected String map(final Traverser.Admin<S> traverser) {
-        final S item = traverser.get();
-        // throws when incoming traverser isn't a string
-        if (null != item && !(item instanceof String)) {
-            throw new IllegalArgumentException(
-                    String.format("The reverse() step can only take string as argument, encountered %s", item.getClass()));
-        }
+    protected E map(final Traverser.Admin<S> traverser) {
+        final S items = traverser.get();
 
-        // we will pass null values to next step
-        return null == item? null : new StringBuilder(((String) item)).reverse().toString();
+        if (null == items) {
+            return null;
+        } else if (items instanceof String) {
+            return (E) new StringBuilder(((String) items)).reverse().toString();
+        } else if ((items instanceof Iterable) || (items instanceof Iterator) || items.getClass().isArray()) {
+            final List itemsAsList = IteratorUtils.asList(items);
+            Collections.reverse(itemsAsList);
+            return (E) itemsAsList;
+        } else {
+            // null traversers are passed on without throwing an exception so the same should be done with other types.
+            return (E) items;
+        }
     }
 
     @Override
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStep.java
new file mode 100644
index 0000000000..82400674e3
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalMergeStep.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ListFunction;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A map step that returns the merger of the traverser and the provided arguments without duplicates. This is commonly
+ * known as a union.
+ */
+public final class TraversalMergeStep<S, E> extends ScalarMapStep<S, E> implements TraversalParent, ListFunction {
+    private Traversal.Admin<S, E> valueTraversal;
+    private Object parameterItems;
+    public TraversalMergeStep(final Traversal.Admin traversal, final Object values) {
+        super(traversal);
+
+        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 = (parameterItems != null) ? parameterItems : TraversalUtil.apply(traverser, valueTraversal);
+            if (!(mapB instanceof Map)) {
+                throw new IllegalArgumentException(
+                        String.format(
+                                "%s step expected provided argument to evaluate to a Map, encountered %s",
+                                getStepName(),
+                                mapB.getClass()));
+            }
+
+            final Map mergedMap = new HashMap(mapA);
+            mergedMap.putAll((Map) mapB);
+            return (E) mergedMap;
+        } else {
+            final Collection listA = convertTraverserToCollection(traverser);
+
+            if (parameterItems instanceof Map) {
+                throw new IllegalArgumentException(getStepName() + " step type mismatch: expected argument to be Iterable but got Map");
+            }
+            final Collection listB =
+                    (null != parameterItems)
+                            ? convertArgumentToCollection(parameterItems) : convertTraversalToCollection(traverser, this.valueTraversal);
+
+            final Set elements = new HashSet();
+
+            elements.addAll(listA);
+            elements.addAll(listB);
+
+            return (E) elements;
+        }
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return (null == valueTraversal) ? Collections.emptyList() : Collections.singletonList(valueTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() { return this.getSelfAndChildRequirements(); }
+
+    @Override
+    public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+        super.setTraversal(parentTraversal);
+        if (valueTraversal != null) { this.integrateChild(this.valueTraversal); }
+    }
+
+    @Override
+    public TraversalMergeStep<S, E> clone() {
+        final TraversalMergeStep<S, E> clone = (TraversalMergeStep<S, E>) super.clone();
+        if (null != this.valueTraversal) {
+            clone.valueTraversal = this.valueTraversal.clone();
+        } else if (this.parameterItems instanceof Map) {
+            clone.parameterItems = new HashMap((Map) this.parameterItems);
+        } else {
+            clone.parameterItems = this.parameterItems;
+        }
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        return Objects.hash(result, valueTraversal, parameterItems);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
index e1b7c436af..172ec880a0 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
@@ -68,6 +68,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsDateStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsStringStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CallStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CoalesceStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.CombineStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConcatStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConstantStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
@@ -75,6 +76,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DateAddStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DateDiffStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.DedupLocalStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.DifferenceStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.DisjunctStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ElementMapStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ElementStep;
@@ -84,6 +87,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IdStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IndexStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.IntersectStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.JoinStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LTrimStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LabelStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaCollectingBarrierStep;
@@ -104,6 +109,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProductStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProjectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyKeyStep;
@@ -126,6 +132,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.ToLowerStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ToUpperStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalFlatMapStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMapStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalMergeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TraversalSelectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TreeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TrimStep;
@@ -230,6 +237,13 @@ public final class BytecodeHelper {
             put(GraphTraversal.Symbols.dateDiff, Collections.singletonList(DateDiffStep.class));
             put(GraphTraversal.Symbols.all, Collections.singletonList(AllStep.class));
             put(GraphTraversal.Symbols.any, Collections.singletonList(AnyStep.class));
+            put(GraphTraversal.Symbols.combine, Collections.singletonList(CombineStep.class));
+            put(GraphTraversal.Symbols.difference, Collections.singletonList(DifferenceStep.class));
+            put(GraphTraversal.Symbols.disjunct, Collections.singletonList(DisjunctStep.class));
+            put(GraphTraversal.Symbols.merge, Collections.singletonList(TraversalMergeStep.class));
+            put(GraphTraversal.Symbols.join, Collections.singletonList(JoinStep.class));
+            put(GraphTraversal.Symbols.product, Collections.singletonList(ProductStep.class));
+            put(GraphTraversal.Symbols.intersect, Collections.singletonList(IntersectStep.class));
             put(GraphTraversal.Symbols.group, Arrays.asList(GroupStep.class, GroupSideEffectStep.class));
             put(GraphTraversal.Symbols.groupCount, Arrays.asList(GroupCountStep.class, GroupCountSideEffectStep.class));
             put(GraphTraversal.Symbols.tree, Arrays.asList(TreeStep.class, TreeSideEffectStep.class));
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ListFunction.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ListFunction.java
new file mode 100644
index 0000000000..ab693b9e29
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ListFunction.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.util;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * List functions are a separate paradigm for Steps as they behave in a Scope.Local manner by default. This class
+ * provides helper methods that are common amongst these steps and should be used to keep behavior consistent in terms
+ * of handling of incoming traversers and argument types.
+ */
+public interface ListFunction {
+
+    /**
+     * Turn an iterable type into a collection. Doesn't wrap any non-iterable type into an iterable (e.g. single Object
+     * into list), but will transform one iterable type to another (e.g. array to list).
+     *
+     * @param iterable an Iterable or array.
+     * @return The iterable type as a Collection or null if argument isn't iterable.
+     */
+    public static Collection asCollection(Object iterable) {
+        if (iterable instanceof Collection) {
+            return (Collection) iterable;
+        } else if ((iterable != null && iterable.getClass().isArray()) || iterable instanceof Iterable) {
+            return (Collection) IteratorUtils.asList(iterable);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Turn an iterable type into a set. Doesn't wrap any non-iterable type into an iterable (e.g. single Object
+     * into set), but will transform one iterable type to another (e.g. array to set).
+     *
+     * @param iterable an Iterable or array.
+     * @return The iterable type as a Collection or null if argument isn't iterable.
+     */
+    public static Set asSet(Object iterable) {
+        if (iterable instanceof Iterable || iterable != null && iterable.getClass().isArray()) {
+            return IteratorUtils.asSet(iterable);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Template method used for retrieving the implementing Step's name.
+     *
+     * @return this step's name.
+     */
+    public String getStepName();
+
+    public default Collection convertArgumentToCollection(Object arg) {
+        if (null == arg) {
+            throw new IllegalArgumentException(
+                    String.format("Argument provided for %s step can't be null.", getStepName()));
+        }
+
+        final Collection incoming = asCollection(arg);
+
+        if (null == incoming) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s step can only take an array or an Iterable as an argument, encountered %s",
+                            getStepName(),
+                            arg.getClass()));
+        }
+
+        return incoming;
+    }
+
+    public default <S> Collection convertTraverserToCollection(Traverser.Admin<S> traverser) {
+        final S items = traverser.get();
+
+        if (null == items) {
+            throw new IllegalArgumentException(
+                    String.format("Incoming traverser for %s step can't be null.", getStepName()));
+        }
+
+        final Collection incoming = asCollection(items);
+
+        if (null == incoming) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s step can only take an array or an Iterable type for incoming traversers, encountered %s",
+                            getStepName(),
+                            items.getClass()));
+        }
+
+        return incoming;
+    }
+
+    public default <S, E> Collection convertTraversalToCollection(Traverser.Admin<S> traverser, final Traversal.Admin<S, E> traversal) {
+        final Object array = TraversalUtil.apply(traverser, traversal);
+
+        if (null == array) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Provided traversal argument for %s step must yield an iterable type, not null",
+                            getStepName()));
+        }
+
+        final Collection input = asCollection(array);
+
+        if (null == input) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Provided traversal argument for %s step must yield an iterable type, encountered %s",
+                            getStepName(),
+                            array.getClass()));
+        }
+
+        return input;
+    }
+
+    public default Set convertArgumentToSet(Object arg) {
+        if (null == arg) {
+            throw new IllegalArgumentException(
+                    String.format("Argument provided for %s step can't be null.", getStepName()));
+        }
+
+        final Set incoming = asSet(arg);
+
+        if (null == incoming) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s step can only take an array or an Iterable as an argument, encountered %s",
+                            getStepName(),
+                            arg.getClass()));
+        }
+
+        return incoming;
+    }
+
+    public default <S> Set convertTraverserToSet(Traverser.Admin<S> traverser) {
+        final S items = traverser.get();
+
+        if (null == items) {
+            throw new IllegalArgumentException(
+                    String.format("Incoming traverser for %s step can't be null.", getStepName()));
+        }
+
+        final Set incoming = asSet(items);
+
+        if (null == incoming) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s step can only take an array or an Iterable type for incoming traversers, encountered %s",
+                            getStepName(),
+                            items.getClass()));
+        }
+
+        return incoming;
+    }
+
+    public default <S, E> Set convertTraversalToSet(Traverser.Admin<S> traverser, final Traversal.Admin<S, E> traversal) {
+        final Object array = TraversalUtil.apply(traverser, traversal);
+
+        if (null == array) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Provided traversal argument for %s step must yield an iterable type, not null",
+                            getStepName()));
+        }
+
+        final Set input = asSet(array);
+
+        if (null == input) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Provided traversal argument for %s step must yield an iterable type, encountered %s",
+                            getStepName(),
+                            array.getClass()));
+        }
+
+        return input;
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/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..2acfce2ac9 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_join_Object() throws Exception {
+        compare(g.V().values("name").fold().join(";"),
+                eval("g.V().values(\"name\").fold().join(\";\")"));
+    }
+
     @Test
     public void shouldParseTraversalMethod_key() throws Exception {
         compare(g.V().key(), eval("g.V().key()"));
@@ -589,6 +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/ReverseStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java
similarity index 66%
copy from gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
copy to gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java
index 1d508d1b1d..5b0d292cd9 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStepTest.java
@@ -29,23 +29,13 @@ import java.util.List;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
-/**
- * @author Yang Xia (http://github.com/xiazcy)
- */
-public class ReverseStepTest extends StepTest {
+public class DisjunctStepTest extends StepTest {
 
     @Override
-    protected List<Traversal> getTraversals() {return Collections.singletonList(__.reverse());}
-
-    @Test
-    public void testReturnTypes() {
-        assertEquals("tset", __.__("test").reverse().next());
-        assertArrayEquals(new String[]{"dlrow olleh", "tset", "321.on", null, ""},
-                __.inject("hello world", "test", "no.123", null, "").reverse().toList().toArray());
+    protected List<Traversal> getTraversals() {
+        return Collections.singletonList(__.disjunct("test"));
     }
 
-    @Test(expected = IllegalArgumentException.class)
-    public void shouldThrowWithIncomingArrayList() {__.__(Arrays.asList("abc", "def")).reverse().next();}
-
 }
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
index 1d508d1b1d..875f0481e2 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStepTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
@@ -25,10 +26,13 @@ import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * @author Yang Xia (http://github.com/xiazcy)
@@ -40,12 +44,24 @@ public class ReverseStepTest extends StepTest {
 
     @Test
     public void testReturnTypes() {
+        assertEquals(Collections.emptyList(), __.__(Collections.emptyList()).reverse().next());
         assertEquals("tset", __.__("test").reverse().next());
         assertArrayEquals(new String[]{"dlrow olleh", "tset", "321.on", null, ""},
                 __.inject("hello world", "test", "no.123", null, "").reverse().toList().toArray());
     }
 
-    @Test(expected = IllegalArgumentException.class)
-    public void shouldThrowWithIncomingArrayList() {__.__(Arrays.asList("abc", "def")).reverse().next();}
+//    @Test
+//    public void shouldAcceptPrimitiveArrayTraverser() {
+//        List result = (List) __.__(new long[] {10L, 7L}).reverse().next();
+//        assertEquals(7L, result.get(0));
+//        assertEquals(10L, result.get(1));
+//        assertEquals(2, result.size());
+//    }
+
+    @Test
+    public void shouldAcceptObjectArrayTraverser() {
+        List result = (List) __.__(Arrays.asList(2, "hello", 10L)).reverse().next();
+        assertArrayEquals(new Object[] {10L, "hello", 2}, result.toArray());
+    }
 
 }
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index d232bff33d..e38831e7ff 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>
@@ -658,6 +667,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 +1171,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>
@@ -1162,6 +1198,15 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, TEnd>(this);
         }
 
+        /// <summary>
+        ///     Adds the join step to this <see cref="GraphTraversal{SType, EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, TEnd> Join<TNewEnd> (string delimiter)
+        {
+            Bytecode.AddStep("join", delimiter);
+            return Wrap<TStart, TEnd>(this);
+        }
+
         /// <summary>
         ///     Adds the key step to this <see cref="GraphTraversal{SType, EType}" />.
         /// </summary>
@@ -1319,6 +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..6fac6b0a6d 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -564,6 +564,22 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_coalesceXoutXlikesX_outXknowsX_inXcreatedXX_groupCount_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Coalesce<object>(__.Out("likes"),__.Out("knows"),__.Out("created")).GroupCount<object>().By("name")}}, 
                {"g_V_coalesceXoutEXknowsX_outEXcreatedXX_otherV_path_byXnameX_byXlabelX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Coalesce<object>(__.OutE("knows"),__.OutE("created")).OtherV().Path().By("name").By(T.Label)}}, 
                {"g_V_outXcreatedX_order_byXnameX_coalesceXname_constantXxXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out("created").Order().By("name").Coalesce<object>(__.Values<object>("name"),__.Constant<object>("x"))}}, 
+               {"g_injectXnullX_combineXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Combine(__.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_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")}}, 
@@ -604,9 +620,41 @@ 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(1697675377393)).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_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_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 +687,32 @@ 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_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_injectXnullX_joinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Join("1")}}, 
+               {"g_V_valuesXnameX_joinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Join("1")}}, 
+               {"g_V_valuesXnonexistantX_fold_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("nonexistant").Fold().Join(";")}}, 
+               {"g_V_valuesXnameX_order_fold_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Order().Fold().Join("_")}}, 
+               {"g_V_valuesXageX_order_fold_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().Fold().Join(";")}}, 
+               {"g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Path().By(__.Values<object>("name").ToUpper()).Join("MARKO")}}, 
+               {"g_injectXmarkoX_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Join("-")}}, 
+               {"g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().ValueMap<object,object>("location").Select<object>(Column.Values).Unfold<object>().Join("1")}}, 
+               {"g_V_out_out_path_byXnameX_joinXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Path().By("name").Join("")}}, 
+               {"g_injectXa_null_bX_joinXxyzX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Join("xyz")}}, 
+               {"g_injectX3_threeX_joinX_X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Join(";")}}, 
                {"g_injectXfeature_test_nullX_length", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("feature","test",null).Length()}}, 
                {"g_injectXListXa_bXX_length", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Length()}}, 
                {"g_V_valuesXnameX_length", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Length()}}, 
@@ -736,6 +810,27 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_injectXnull_10_20_nullX_mean", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null,p["xx1"],p["xx2"],null).Mean<object>()}}, 
                {"g_injectXlistXnull_10_20_nullXX_meanXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Mean<object>(Scope.Local)}}, 
                {"g_VX1X_valuesXageX_meanXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Values<object>("age").Mean<object>(Scope.Local)}}, 
+               {"g_injectXnullX_mergeXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Merge(__.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_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 +997,21 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_peerPressure_hasXclusterX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().PeerPressure().Has("gremlin.peerPressureVertexProgram.cluster")}}, 
                {"g_V_peerPressure_withXpropertyName_clusterX_withXedges_outEXknowsXX_pageRankX1X_byXrankX_withXedges_outEXknowsX_withXtimes_2X_group_byXclusterX_byXrank_sumX_limitX100X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().PeerPressure().With("~tinkerpop.peerPressure.propertyName","cluster").With("~tinkerpop.peerPressure.edges",__.OutE("knows")).PageRank(1.0).With("~tinkerpop.pageRank.propertyName","rank").With("~tinkerpop.pageRank [...]
                {"g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withyXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name","ripple").In("created").PeerPressure().With("~tinkerpop.peerPressure.edges",__.OutE()).With("~tinkerpop.peerPressure.propertyName","cluster").Repeat(__.Union<object>(__.Identity(),__.Both())).Times(2).Dedup().Va [...]
+               {"g_injectXnullX_productXinjectX1XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Product(__.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_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 +1027,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..31a014c0ba 100644
--- a/gremlin-go/driver/anonymousTraversal.go
+++ b/gremlin-go/driver/anonymousTraversal.go
@@ -87,6 +87,8 @@ type AnonymousTraversal interface {
 	Coalesce(args ...interface{}) *GraphTraversal
 	// Coin adds the coin step to the GraphTraversal.
 	Coin(args ...interface{}) *GraphTraversal
+	// Combine adds the combine step to the GraphTraversal.
+	Combine(args ...interface{}) *GraphTraversal
 	// Concat adds the Concat step to the GraphTraversal.
 	Concat(args ...interface{}) *GraphTraversal
 	// ConnectedComponent adds the connectedComponent step to the GraphTraversal.
@@ -99,6 +101,10 @@ type AnonymousTraversal interface {
 	CyclicPath(args ...interface{}) *GraphTraversal
 	// Dedup adds the dedup step to the GraphTraversal.
 	Dedup(args ...interface{}) *GraphTraversal
+	// Difference adds the difference step to the GraphTraversal.
+	Difference(args ...interface{}) *GraphTraversal
+	// Disjunct adds the disjunct step to the GraphTraversal.
+	Disjunct(args ...interface{}) *GraphTraversal
 	// Drop adds the drop step to the GraphTraversal.
 	Drop(args ...interface{}) *GraphTraversal
 	// Element adds the element step to the GraphTraversal.
@@ -147,8 +153,12 @@ type AnonymousTraversal interface {
 	Index(args ...interface{}) *GraphTraversal
 	// Inject adds the inject step to the GraphTraversal.
 	Inject(args ...interface{}) *GraphTraversal
+	// Intersect adds the intersect step to the GraphTraversal.
+	Intersect(args ...interface{}) *GraphTraversal
 	// Is adds the is step to the GraphTraversal.
 	Is(args ...interface{}) *GraphTraversal
+	// Join adds the join step to the GraphTraversal.
+	Join(args ...interface{}) *GraphTraversal
 	// Key adds the key step to the GraphTraversal.
 	Key(args ...interface{}) *GraphTraversal
 	// Label adds the label step to the GraphTraversal.
@@ -173,6 +183,8 @@ type AnonymousTraversal interface {
 	Max(args ...interface{}) *GraphTraversal
 	// Mean adds the mean step to the GraphTraversal.
 	Mean(args ...interface{}) *GraphTraversal
+	// Merge adds the merge step to the GraphTraversal.
+	Merge(args ...interface{}) *GraphTraversal
 	// MergeE adds the mergeE step to the GraphTraversal.
 	MergeE(args ...interface{}) *GraphTraversal
 	// MergeV adds the mergeV step to the GraphTraversal.
@@ -205,6 +217,8 @@ type AnonymousTraversal interface {
 	Path(args ...interface{}) *GraphTraversal
 	// PeerPressure adds the peerPressure step to the GraphTraversal.
 	PeerPressure(args ...interface{}) *GraphTraversal
+	// Product adds the product step to the GraphTraversal.
+	Product(args ...interface{}) *GraphTraversal
 	// Profile adds the profile step to the GraphTraversal.
 	Profile(args ...interface{}) *GraphTraversal
 	// Program adds the program step to the GraphTraversal.
@@ -418,6 +432,11 @@ func (anonymousTraversal *anonymousTraversal) Coin(args ...interface{}) *GraphTr
 	return anonymousTraversal.graphTraversal().Coin(args...)
 }
 
+// Combine adds the combine step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Combine(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Combine(args...)
+}
+
 // Concat adds the Concat step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Concat(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Concat(args...)
@@ -458,6 +477,16 @@ func (anonymousTraversal *anonymousTraversal) Dedup(args ...interface{}) *GraphT
 	return anonymousTraversal.graphTraversal().Dedup(args...)
 }
 
+// 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,11 +607,21 @@ func (anonymousTraversal *anonymousTraversal) Inject(args ...interface{}) *Graph
 	return anonymousTraversal.graphTraversal().Inject(args...)
 }
 
+// Intersect adds the intersect step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Intersect(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Intersect(args...)
+}
+
 // Is adds the is step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Is(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Is(args...)
 }
 
+// Join adds the join step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Join(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Join(args...)
+}
+
 // Key adds the key step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Key(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Key(args...)
@@ -643,6 +682,11 @@ func (anonymousTraversal *anonymousTraversal) Mean(args ...interface{}) *GraphTr
 	return anonymousTraversal.graphTraversal().Mean(args...)
 }
 
+// Merge adds the merge step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Merge(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Merge(args...)
+}
+
 // MergeE adds the mergeE step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) MergeE(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().MergeE(args...)
@@ -723,6 +767,11 @@ func (anonymousTraversal *anonymousTraversal) PeerPressure(args ...interface{})
 	return anonymousTraversal.graphTraversal().PeerPressure(args...)
 }
 
+// Product adds the product step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Product(args ...interface{}) *GraphTraversal {
+	return anonymousTraversal.graphTraversal().Product(args...)
+}
+
 // Profile adds the profile step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) Profile(args ...interface{}) *GraphTraversal {
 	return anonymousTraversal.graphTraversal().Profile(args...)
diff --git a/gremlin-go/driver/cucumber/gremlin.go b/gremlin-go/driver/cucumber/gremlin.go
index a1b837ada1..fde8dc69e5 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -535,6 +535,22 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_V_coalesceXoutXlikesX_outXknowsX_inXcreatedXX_groupCount_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Coalesce(gremlingo.T__.Out("likes"), gremlingo.T__.Out("knows"), gremlingo.T__.Out("created")).GroupCount().By("name")}}, 
     "g_V_coalesceXoutEXknowsX_outEXcreatedXX_otherV_path_byXnameX_byXlabelX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Coalesce(gremlingo.T__.OutE("knows"), gremlingo.T__.OutE("created")).OtherV().Path().By("name").By(gremlingo.T.Label)}}, 
     "g_V_outXcreatedX_order_byXnameX_coalesceXname_constantXxXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out("created").Order().By("name").Coalesce(gremlingo.T__.Values("name"), gremlingo.T__.Constant("x"))}}, 
+    "g_injectXnullX_combineXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Combine(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_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")}}, 
@@ -575,9 +591,41 @@ 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(1697675388836)).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_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_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 +658,32 @@ 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_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_injectXnullX_joinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Join("1")}}, 
+    "g_V_valuesXnameX_joinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Join("1")}}, 
+    "g_V_valuesXnonexistantX_fold_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("nonexistant").Fold().Join(";")}}, 
+    "g_V_valuesXnameX_order_fold_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Order().Fold().Join("_")}}, 
+    "g_V_valuesXageX_order_fold_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().Fold().Join(";")}}, 
+    "g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Path().By(gremlingo.T__.Values("name").ToUpper()).Join("MARKO")}}, 
+    "g_injectXmarkoX_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Join("-")}}, 
+    "g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().ValueMap("location").Select(gremlingo.Column.Values).Unfold().Join("1")}}, 
+    "g_V_out_out_path_byXnameX_joinXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Out().Out().Path().By("name").Join("")}}, 
+    "g_injectXa_null_bX_joinXxyzX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Join("xyz")}}, 
+    "g_injectX3_threeX_joinX_X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Join(";")}}, 
     "g_injectXfeature_test_nullX_length": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("feature", "test", nil).Length()}}, 
     "g_injectXListXa_bXX_length": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Length()}}, 
     "g_V_valuesXnameX_length": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("name").Length()}}, 
@@ -707,6 +781,27 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_injectXnull_10_20_nullX_mean": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil, p["xx1"], p["xx2"], nil).Mean()}}, 
     "g_injectXlistXnull_10_20_nullXX_meanXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Mean(gremlingo.Scope.Local)}}, 
     "g_VX1X_valuesXageX_meanXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Values("age").Mean(gremlingo.Scope.Local)}}, 
+    "g_injectXnullX_mergeXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Merge(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_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 +968,21 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_V_peerPressure_hasXclusterX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().PeerPressure().Has("gremlin.peerPressureVertexProgram.cluster")}}, 
     "g_V_peerPressure_withXpropertyName_clusterX_withXedges_outEXknowsXX_pageRankX1X_byXrankX_withXedges_outEXknowsX_withXtimes_2X_group_byXclusterX_byXrank_sumX_limitX100X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().PeerPressure().With("~tinkerpop.peerPressure.propertyName", "cluster").With("~tinkerpop.peerPressure.edges", gremlingo.T__.OutE("knows")).PageRank(1.0).With("~tinkerpop.pageRank.propertyName", "rank").With("~ti [...]
     "g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withyXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", "ripple").In("created").PeerPressure().With("~tinkerpop.peerPressure.edges", gremlingo.T__.OutE()).With("~tinkerpop.peerPressure.propertyName", "cluster").Repeat(gremlingo.T__.Union(gremlingo.T__.Identity(),  [...]
+    "g_injectXnullX_productXinjectX1XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Product(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_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 +998,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..ed287c5453 100644
--- a/gremlin-go/driver/graphTraversal.go
+++ b/gremlin-go/driver/graphTraversal.go
@@ -185,6 +185,12 @@ func (g *GraphTraversal) Coin(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Combine adds the combine step to the GraphTraversal.
+func (g *GraphTraversal) Combine(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("combine", args...)
+	return g
+}
+
 // Concat adds the concat step to the GraphTraversal.
 func (g *GraphTraversal) Concat(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("concat", args...)
@@ -234,6 +240,18 @@ func (g *GraphTraversal) Dedup(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Difference adds the difference step to the GraphTraversal.
+func (g *GraphTraversal) Difference(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("difference", args...)
+	return g
+}
+
+// Disjunct adds the disjunct step to the GraphTraversal.
+func (g *GraphTraversal) Disjunct(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("disjunct", args...)
+	return g
+}
+
 // Drop adds the drop step to the GraphTraversal.
 func (g *GraphTraversal) Drop(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("drop", args...)
@@ -379,12 +397,25 @@ func (g *GraphTraversal) Inject(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Intersect adds the intersect step to the GraphTraversal.
+func (g *GraphTraversal) Intersect(args ...interface{}) *GraphTraversal {
+	// Force int32 serialization for valid number values for server compatibility
+	g.Bytecode.AddStep("intersect", args...)
+	return g
+}
+
 // Is adds the is step to the GraphTraversal.
 func (g *GraphTraversal) Is(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("is", args...)
 	return g
 }
 
+// Join adds the join step to the GraphTraversal.
+func (g *GraphTraversal) Join(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("join", args...)
+	return g
+}
+
 // Key adds the key step to the GraphTraversal.
 func (g *GraphTraversal) Key(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("key", args...)
@@ -457,6 +488,12 @@ func (g *GraphTraversal) Mean(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Merge adds the merge step to the GraphTraversal.
+func (g *GraphTraversal) Merge(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("merge", args...)
+	return g
+}
+
 // MergeE adds the mergeE step to the GraphTraversal.
 func (g *GraphTraversal) MergeE(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("mergeE", args...)
@@ -553,6 +590,12 @@ func (g *GraphTraversal) PeerPressure(args ...interface{}) *GraphTraversal {
 	return g
 }
 
+// Product adds the product step to the GraphTraversal.
+func (g *GraphTraversal) Product(args ...interface{}) *GraphTraversal {
+	g.Bytecode.AddStep("product", args...)
+	return g
+}
+
 // Profile adds the profile step to the GraphTraversal.
 func (g *GraphTraversal) Profile(args ...interface{}) *GraphTraversal {
 	g.Bytecode.AddStep("profile", args...)
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
index d6ebf0f273..2bb33443ae 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
@@ -583,6 +583,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal combine method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  combine(...args) {
+    this.bytecode.addStep('combine', args);
+    return this;
+  }
+
   /**
    * Graph traversal concat method.
    * @param {...Object} args
@@ -663,6 +673,26 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal difference method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  difference(...args) {
+    this.bytecode.addStep('difference', args);
+    return this;
+  }
+
+  /**
+   * Graph traversal disjunct method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  disjunct(...args) {
+    this.bytecode.addStep('disjunct', args);
+    return this;
+  }
+
   /**
    * Graph traversal drop method.
    * @param {...Object} args
@@ -902,6 +932,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal intersect method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  intersect(...args) {
+    this.bytecode.addStep('intersect', args);
+    return this;
+  }
+
   /**
    * Graph traversal is method.
    * @param {...Object} args
@@ -912,6 +952,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal join method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  join(...args) {
+    this.bytecode.addStep('join', args);
+    return this;
+  }
+
   /**
    * Graph traversal key method.
    * @param {...Object} args
@@ -1032,6 +1082,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal merge method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  merge(...args) {
+    this.bytecode.addStep('merge', args);
+    return this;
+  }
+
   /**
    * Graph traversal mergeE method.
    * @param {...Object} args
@@ -1192,6 +1252,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal product method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  product(...args) {
+    this.bytecode.addStep('product', args);
+    return this;
+  }
+
   /**
    * Graph traversal profile method.
    * @param {...Object} args
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/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..c94b80be4f 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -555,6 +555,22 @@ const gremlins = {
     g_V_coalesceXoutXlikesX_outXknowsX_inXcreatedXX_groupCount_byXnameX: [function({g}) { return g.V().coalesce(__.out("likes"),__.out("knows"),__.out("created")).groupCount().by("name") }], 
     g_V_coalesceXoutEXknowsX_outEXcreatedXX_otherV_path_byXnameX_byXlabelX: [function({g}) { return g.V().coalesce(__.outE("knows"),__.outE("created")).otherV().path().by("name").by(T.label) }], 
     g_V_outXcreatedX_order_byXnameX_coalesceXname_constantXxXX: [function({g}) { return g.V().out("created").order().by("name").coalesce(__.values("name"),__.constant("x")) }], 
+    g_injectXnullX_combineXinjectX1XX: [function({g}) { return g.inject(null).combine(__.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_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") }], 
@@ -595,9 +611,41 @@ 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(1697675349004)).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_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_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 +678,32 @@ 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_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_injectXnullX_joinX1X: [function({g}) { return g.inject(null).join("1") }], 
+    g_V_valuesXnameX_joinX1X: [function({g}) { return g.V().values("name").join("1") }], 
+    g_V_valuesXnonexistantX_fold_joinX_X: [function({g}) { return g.V().values("nonexistant").fold().join(";") }], 
+    g_V_valuesXnameX_order_fold_joinX_X: [function({g}) { return g.V().values("name").order().fold().join("_") }], 
+    g_V_valuesXageX_order_fold_joinX_X: [function({g}) { return g.V().values("age").order().fold().join(";") }], 
+    g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX: [function({g}) { return g.V().out().path().by(__.values("name").toUpper()).join("MARKO") }], 
+    g_injectXmarkoX_joinX_X: [function({g, xx1}) { return g.inject(xx1).join("-") }], 
+    g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X: [function({g}) { return g.V().valueMap("location").select(Column.values).unfold().join("1") }], 
+    g_V_out_out_path_byXnameX_joinXX: [function({g}) { return g.V().out().out().path().by("name").join("") }], 
+    g_injectXa_null_bX_joinXxyzX: [function({g, xx1}) { return g.inject(xx1).join("xyz") }], 
+    g_injectX3_threeX_joinX_X: [function({g, xx1}) { return g.inject(xx1).join(";") }], 
     g_injectXfeature_test_nullX_length: [function({g}) { return g.inject("feature","test",null).length() }], 
     g_injectXListXa_bXX_length: [function({g, xx1}) { return g.inject(xx1).length() }], 
     g_V_valuesXnameX_length: [function({g}) { return g.V().values("name").length() }], 
@@ -727,6 +801,27 @@ const gremlins = {
     g_injectXnull_10_20_nullX_mean: [function({g, xx1, xx2}) { return g.inject(null,xx1,xx2,null).mean() }], 
     g_injectXlistXnull_10_20_nullXX_meanXlocalX: [function({g, xx1}) { return g.inject(xx1).mean(Scope.local) }], 
     g_VX1X_valuesXageX_meanXlocalX: [function({g, vid1}) { return g.V(vid1).values("age").mean(Scope.local) }], 
+    g_injectXnullX_mergeXinjectX1XX: [function({g}) { return g.inject(null).merge(__.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_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 +988,21 @@ const gremlins = {
     g_V_peerPressure_hasXclusterX: [function({g}) { return g.V().peerPressure().has("gremlin.peerPressureVertexProgram.cluster") }], 
     g_V_peerPressure_withXpropertyName_clusterX_withXedges_outEXknowsXX_pageRankX1X_byXrankX_withXedges_outEXknowsX_withXtimes_2X_group_byXclusterX_byXrank_sumX_limitX100X: [function({g}) { return g.V().peerPressure().with_("~tinkerpop.peerPressure.propertyName","cluster").with_("~tinkerpop.peerPressure.edges",__.outE("knows")).pageRank(1.0).with_("~tinkerpop.pageRank.propertyName","rank").with_("~tinkerpop.pageRank.edges",__.outE("knows")).with_("~tinkerpop.pageRank.times",1).group().by [...]
     g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withyXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX: [function({g}) { return g.V().has("name","ripple").in_("created").peerPressure().with_("~tinkerpop.peerPressure.edges",__.outE()).with_("~tinkerpop.peerPressure.propertyName","cluster").repeat(__.union(__.identity(),__.both())).times(2).dedup().valueMap("name","cluster") }], 
+    g_injectXnullX_productXinjectX1XX: [function({g}) { return g.inject(null).product(__.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_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 +1018,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..79d97620e0 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -202,6 +202,8 @@ traversalMethod
     | traversalMethod_count
     | traversalMethod_cyclicPath
     | traversalMethod_dedup
+    | traversalMethod_difference
+    | traversalMethod_disjunct
     | traversalMethod_drop
     | traversalMethod_elementMap
     | traversalMethod_emit
@@ -221,10 +223,12 @@ traversalMethod
     | traversalMethod_identity
     | traversalMethod_in
     | traversalMethod_inE
+    | traversalMethod_intersect
     | traversalMethod_inV
     | traversalMethod_index
     | traversalMethod_inject
     | traversalMethod_is
+    | traversalMethod_join
     | traversalMethod_key
     | traversalMethod_label
     | traversalMethod_limit
@@ -259,6 +263,9 @@ traversalMethod
     | traversalMethod_sack
     | traversalMethod_sample
     | traversalMethod_select
+    | traversalMethod_combine
+    | traversalMethod_product
+    | traversalMethod_merge
     | traversalMethod_shortestPath
     | traversalMethod_sideEffect
     | traversalMethod_simplePath
@@ -339,16 +346,16 @@ traversalMethod_aggregate
     ;
 
 traversalMethod_all
-	: 'all' LPAREN traversalPredicate RPAREN #traversalMethod_all_P
-	;
+    : 'all' LPAREN traversalPredicate RPAREN #traversalMethod_all_P
+    ;
 
 traversalMethod_and
     : 'and' LPAREN nestedTraversalList RPAREN
     ;
 
 traversalMethod_any
-	: 'any' LPAREN traversalPredicate RPAREN #traversalMethod_any_P
-	;
+    : 'any' LPAREN traversalPredicate RPAREN #traversalMethod_any_P
+    ;
 
 traversalMethod_as
     : 'as' LPAREN stringArgument (COMMA stringLiteralVarargs)? RPAREN
@@ -410,6 +417,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_join
+    : 'join' LPAREN stringArgument RPAREN #traversalMethod_join_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..9457f711df 100644
--- a/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
@@ -391,6 +391,10 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("coin", *args)
         return self
 
+    def combine(self, *args):
+        self.bytecode.add_step("combine", *args)
+        return self
+
     def concat(self, *args):
         self.bytecode.add_step("concat", *args)
         return self
@@ -437,6 +441,14 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("dedup", *args)
         return self
 
+    def difference(self, *args):
+        self.bytecode.add_step("difference", *args)
+        return self
+
+    def disjunct(self, *args):
+        self.bytecode.add_step("disjunct", *args)
+        return self
+
     def drop(self, *args):
         self.bytecode.add_step("drop", *args)
         return self
@@ -603,10 +615,18 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("inject", *args)
         return self
 
+    def intersect(self, *args):
+        self.bytecode.add_step("intersect", *args)
+        return self
+
     def is_(self, *args):
         self.bytecode.add_step("is", *args)
         return self
 
+    def join(self, *args):
+        self.bytecode.add_step("join", *args)
+        return self
+
     def key(self, *args):
         self.bytecode.add_step("key", *args)
         return self
@@ -655,6 +675,10 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("mean", *args)
         return self
 
+    def merge(self, *args):
+        self.bytecode.add_step("merge", *args)
+        return self
+
     def merge_e(self, *args):
         self.bytecode.add_step("mergeE", *args)
         return self
@@ -754,6 +778,10 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("peerPressure", *args)
         return self
 
+    def product(self, *args):
+        self.bytecode.add_step("product", *args)
+        return self
+
     def profile(self, *args):
         self.bytecode.add_step("profile", *args)
         return self
@@ -1119,6 +1147,10 @@ class __(object, metaclass=MagicType):
     def coin(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).coin(*args)
 
+    @classmethod
+    def combine(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).combine(*args)
+
     @classmethod
     def concat(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).concat(*args)
@@ -1155,6 +1187,14 @@ class __(object, metaclass=MagicType):
     def dedup(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).dedup(*args)
 
+    @classmethod
+    def difference(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).difference(*args)
+
+    @classmethod
+    def disjunct(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).disjunct(*args)
+
     @classmethod
     def drop(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).drop(*args)
@@ -1327,6 +1367,10 @@ class __(object, metaclass=MagicType):
     def inject(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).inject(*args)
 
+    @classmethod
+    def intersect(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).intersect(*args)
+
     @classmethod
     def is_(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).is_(*args)
@@ -1379,6 +1423,10 @@ class __(object, metaclass=MagicType):
     def mean(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).mean(*args)
 
+    @classmethod
+    def merge(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).merge(*args)
+
     @classmethod
     def merge_e(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).merge_e(*args)
@@ -1451,6 +1499,10 @@ class __(object, metaclass=MagicType):
     def path(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).path(*args)
 
+    @classmethod
+    def product(cls, *args):
+        return cls.graph_traversal(None, None, Bytecode()).product(*args)
+
     @classmethod
     def project(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).project(*args)
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index 67824c6680..bb1d42a262 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -537,6 +537,22 @@ world.gremlins = {
     'g_V_coalesceXoutXlikesX_outXknowsX_inXcreatedXX_groupCount_byXnameX': [(lambda g:g.V().coalesce(__.out('likes'),__.out('knows'),__.out('created')).groupCount().by('name'))], 
     'g_V_coalesceXoutEXknowsX_outEXcreatedXX_otherV_path_byXnameX_byXlabelX': [(lambda g:g.V().coalesce(__.outE('knows'),__.outE('created')).otherV().path().by('name').by(T.label))], 
     'g_V_outXcreatedX_order_byXnameX_coalesceXname_constantXxXX': [(lambda g:g.V().out('created').order().by('name').coalesce(__.name,__.constant('x')))], 
+    'g_injectXnullX_combineXinjectX1XX': [(lambda g:g.inject(None).combine(__.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_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'))], 
@@ -577,9 +593,41 @@ 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(1697675361465 / 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_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_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 +660,32 @@ 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_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_injectXnullX_joinX1X': [(lambda g:g.inject(None).join('1'))], 
+    'g_V_valuesXnameX_joinX1X': [(lambda g:g.V().name.join('1'))], 
+    'g_V_valuesXnonexistantX_fold_joinX_X': [(lambda g:g.V().nonexistant.fold().join(';'))], 
+    'g_V_valuesXnameX_order_fold_joinX_X': [(lambda g:g.V().name.order().fold().join('_'))], 
+    'g_V_valuesXageX_order_fold_joinX_X': [(lambda g:g.V().age.order().fold().join(';'))], 
+    'g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX': [(lambda g:g.V().out().path().by(__.name.to_upper()).join('MARKO'))], 
+    'g_injectXmarkoX_joinX_X': [(lambda g, xx1=None:g.inject(xx1).join('-'))], 
+    'g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X': [(lambda g:g.V().valueMap('location').select(Column.values).unfold().join('1'))], 
+    'g_V_out_out_path_byXnameX_joinXX': [(lambda g:g.V().out().out().path().by('name').join(''))], 
+    'g_injectXa_null_bX_joinXxyzX': [(lambda g, xx1=None:g.inject(xx1).join('xyz'))], 
+    'g_injectX3_threeX_joinX_X': [(lambda g, xx1=None:g.inject(xx1).join(';'))], 
     'g_injectXfeature_test_nullX_length': [(lambda g:g.inject('feature','test',None).length())], 
     'g_injectXListXa_bXX_length': [(lambda g, xx1=None:g.inject(xx1).length())], 
     'g_V_valuesXnameX_length': [(lambda g:g.V().name.length())], 
@@ -709,6 +783,27 @@ world.gremlins = {
     'g_injectXnull_10_20_nullX_mean': [(lambda g, xx1=None,xx2=None:g.inject(None,xx1,xx2,None).mean())], 
     'g_injectXlistXnull_10_20_nullXX_meanXlocalX': [(lambda g, xx1=None:g.inject(xx1).mean(Scope.local))], 
     'g_VX1X_valuesXageX_meanXlocalX': [(lambda g, vid1=None:g.V(vid1).age.mean(Scope.local))], 
+    'g_injectXnullX_mergeXinjectX1XX': [(lambda g:g.inject(None).merge(__.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_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 +970,21 @@ world.gremlins = {
     'g_V_peerPressure_hasXclusterX': [(lambda g:g.V().peerPressure().has('gremlin.peerPressureVertexProgram.cluster'))], 
     'g_V_peerPressure_withXpropertyName_clusterX_withXedges_outEXknowsXX_pageRankX1X_byXrankX_withXedges_outEXknowsX_withXtimes_2X_group_byXclusterX_byXrank_sumX_limitX100X': [(lambda g:g.V().peerPressure().with_('~tinkerpop.peerPressure.propertyName','cluster').with_('~tinkerpop.peerPressure.edges',__.outE('knows')).pageRank(float(1.0)).with_('~tinkerpop.pageRank.propertyName','rank').with_('~tinkerpop.pageRank.edges',__.outE('knows')).with_('~tinkerpop.pageRank.times',1).group().by('cl [...]
     'g_V_hasXname_rippleX_inXcreatedX_peerPressure_withXedges_outEX_withyXpropertyName_clusterX_repeatXunionXidentity__bothX_timesX2X_dedup_valueMapXname_clusterX': [(lambda g:g.V().has('name','ripple').in_('created').peerPressure().with_('~tinkerpop.peerPressure.edges',__.outE()).with_('~tinkerpop.peerPressure.propertyName','cluster').repeat(__.union(__.identity(),__.both())).times(2).dedup().valueMap('name','cluster'))], 
+    'g_injectXnullX_productXinjectX1XX': [(lambda g:g.inject(None).product(__.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_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 +1000,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..f7b39f4334
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Combine.feature
@@ -0,0 +1,222 @@
+# 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"
+
+  @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/Difference.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Difference.feature
new file mode 100644
index 0000000000..de4d2ce2e2
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Difference.feature
@@ -0,0 +1,236 @@
+# 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"
+
+  @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..28b4510f3d
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Disjunct.feature
@@ -0,0 +1,212 @@
+# 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"
+
+  @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..bc09ddb633
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Intersect.feature
@@ -0,0 +1,208 @@
+# 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"
+
+  @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/Join.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Join.feature
new file mode 100644
index 0000000000..109d268a8c
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Join.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 @StepJoin
+Feature: Step - join()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXnullX_joinX1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null).join("1")
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "Incoming traverser for join step can't be null"
+
+  Scenario: g_V_valuesXnameX_joinX1X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").join("1")
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of "join step can only take an array or an Iterable type for incoming traversers, encountered "
+
+  Scenario: g_V_valuesXnonexistantX_fold_joinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("nonexistant").fold().join(";")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | str[] |
+
+  Scenario: g_V_valuesXnameX_order_fold_joinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("name").order().fold().join("_")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | josh_lop_marko_peter_ripple_vadas |
+
+  Scenario: g_V_valuesXageX_order_fold_joinX_X
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").order().fold().join(";")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | 27;29;32;35 |
+
+  @GraphComputerVerificationReferenceOnly
+  Scenario: g_V_out_path_byXvaluesXnameX_toUpperX_joinXMARKOX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().path().by(values("name").toUpper()).join("MARKO")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | MARKOMARKOLOP |
+      | MARKOMARKOVADAS |
+      | MARKOMARKOJOSH |
+      | JOSHMARKORIPPLE |
+      | JOSHMARKOLOP |
+      | PETERMARKOLOP |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXmarkoX_joinX_X
+    Given the modern graph
+    And using the parameter xx1 defined as "l[marko]"
+    And the traversal of
+      """
+      g.inject(xx1).join("-")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | marko |
+
+  @MultiMetaProperties
+  Scenario: g_V_valueMapXlocationX_selectXvaluesX_unfold_joinX1X
+    Given the crew graph
+    And the traversal of
+      """
+      g.V().valueMap("location").select(values).unfold().join("1")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | san diego1santa cruz1brussels1santa fe |
+      | centreville1dulles1purcellville |
+      | bremen1baltimore1oakland1seattle |
+      | spremberg1kaiserslautern1aachen |
+
+  @GraphComputerVerificationReferenceOnly
+  Scenario: g_V_out_out_path_byXnameX_joinXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().path().by("name").join("")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | markojoshripple |
+      | markojoshlop |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXa_null_bX_joinXxyzX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[a,null,b]"
+    And the traversal of
+      """
+      g.inject(xx1).join("xyz")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | str[axyznullxyzb] |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX3_threeX_joinX_X
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[3].i,three]"
+    And the traversal of
+      """
+      g.inject(xx1).join(";")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | 3;three |
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Merge.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Merge.feature
new file mode 100644
index 0000000000..d75478f647
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Merge.feature
@@ -0,0 +1,282 @@
+# 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"
+
+  @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..7d16a4fa6c
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Product.feature
@@ -0,0 +1,293 @@
+# 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"
+
+  @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] |