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

andreac pushed a commit to branch 3.8-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/3.8-dev by this push:
     new 544ed90ce0 TINKERPOP-2491 Remove auto unfold of single item results 
for range, limit, tail local scope steps (#3184)
544ed90ce0 is described below

commit 544ed90ce013810aa4073a503d5d89d24bd604d2
Author: andreachild <[email protected]>
AuthorDate: Wed Aug 20 10:07:49 2025 -0700

    TINKERPOP-2491 Remove auto unfold of single item results for range, limit, 
tail local scope steps (#3184)
    
    TINKERPOP-2491
    
    Fixed inconsistent behaviour where range(), limit(), and tail() would 
return single elements instead of collections for single-item results with 
local scope:
    - modified RangeLocalStep.applyRangeIterable() to always returns 
collections for iterable inputs regardless of number of results
    - modified documentation and sample queries to reflect changed logic
        added more feature tests and unit tests
---
 CHANGELOG.asciidoc                                 |  1 +
 docs/src/recipes/recommendation.asciidoc           |  2 +-
 docs/src/recipes/shortest-path.asciidoc            |  4 +-
 docs/src/reference/the-traversal.asciidoc          | 32 +++++--
 docs/src/upgrade/release-3.8.x.asciidoc            | 54 ++++++++++++
 .../process/traversal/step/map/RangeLocalStep.java | 24 +-----
 .../traversal/step/map/RangeLocalStepTest.java     | 97 ++++++++++++++++++++++
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 26 ++++--
 gremlin-go/driver/cucumber/gremlin.go              | 26 ++++--
 .../gremlin-javascript/test/cucumber/gremlin.js    | 26 ++++--
 gremlin-python/src/main/python/radish/gremlin.py   | 26 ++++--
 .../process/traversal/step/filter/RangeTest.java   | 30 +++----
 .../process/traversal/step/filter/TailTest.java    | 30 +++----
 .../gremlin/test/features/filter/Range.feature     | 66 ++++++++++++++-
 .../gremlin/test/features/filter/Tail.feature      | 81 +++++++++++++++---
 .../gremlin/test/features/map/MergeEdge.feature    | 16 ++--
 .../gremlin/test/features/map/MergeVertex.feature  | 16 ++--
 17 files changed, 436 insertions(+), 121 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 88540a25b3..b887c1a1ae 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -98,6 +98,7 @@ This release also includes changes from <<release-3-7-XXX, 
3.7.XXX>>.
 * Introduced `GValue` to represent parameterized values in a `GraphTraversal`
 * Added optional traversal cache to `GremlinLangScriptEngine`
 * Introduced step interfaces for all parameterizable steps
+* Removed auto-unfold of singleton collections from `range()`, `limit()`, and 
`tail()` local scope steps to improve consistency of output.
 
 == TinkerPop 3.7.0 (Gremfir Master of the Pan Flute)
 
diff --git a/docs/src/recipes/recommendation.asciidoc 
b/docs/src/recipes/recommendation.asciidoc
index f02c4e9a55..ce89794cf0 100644
--- a/docs/src/recipes/recommendation.asciidoc
+++ b/docs/src/recipes/recommendation.asciidoc
@@ -183,7 +183,7 @@ g.V().has("person","name","alice").as("alice").
       where(within("self")).count()).
       select(values).
       order(local).
-        by(desc).limit(local, 1)
+        by(desc).limit(local, 1).unfold()
 ----
 
 With the maximum value available, it can be used to chose those "person" 
vertices that have the three products in
diff --git a/docs/src/recipes/shortest-path.asciidoc 
b/docs/src/recipes/shortest-path.asciidoc
index fa4601848f..eacd3b48d3 100644
--- a/docs/src/recipes/shortest-path.asciidoc
+++ b/docs/src/recipes/shortest-path.asciidoc
@@ -168,8 +168,8 @@ result = g.withComputer().V().
   filter(count(local).is(gt(1))).
   group().
     by(project('from','to').
-         by(limit(local, 1)).
-         by(tail(local, 1))).
+         by(limit(local, 1).unfold()).
+         by(tail(local, 1).unfold())).
   unfold().
   order().
     by(select(keys).select('from').id()).
diff --git a/docs/src/reference/the-traversal.asciidoc 
b/docs/src/reference/the-traversal.asciidoc
index 84a19fb786..b7b31ea291 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -2471,10 +2471,14 @@ The examples below use the <<the-crew-toy-graph,The 
Crew>> toy data set.
 ----
 g.V().valueMap().select('location').limit(local,2) <1>
 g.V().valueMap().limit(local, 1) <2>
+g.V().valueMap().select('location').limit(local, 1) <3>
+g.V().valueMap().select('location').limit(local, 1).unfold() <4>
 ----
 
 <1> `List<String>` for each vertex containing the first two locations.
 <2> `Map<String, Object>` for each vertex, but containing only the first 
property value.
+<3> `List<String>` for each vertex containing the first location.
+<4> `String` for each vertex containing the first location (use `unfold()` to 
extract single elements from singleton collections).
 
 *Additional References*
 
@@ -3269,12 +3273,12 @@ contains additional information that will be applied if 
an existing vertex is fo
 [gremlin-groovy]
 ----
 
g.inject([[(T.id):400],[(T.label):'Dog',name:'Pixel',age:1],[updated:'2022-02-1']]).
-  mergeV(limit(local,1)). <1>
+  mergeV(limit(local,1).unfold()). <1>
   option(Merge.onCreate,range(local,1,2)). <2>
   option(Merge.onMatch,tail(local)) <3>
 g.V(400).valueMap().with(WithOptions.tokens)
 
g.inject([[(T.id):400],[(T.label):'Dog',name:'Pixel',age:1],[updated:'2022-02-1']]).
-  mergeV(limit(local,1)).
+  mergeV(limit(local,1).unfold()).
   option(Merge.onCreate,range(local,1,2)).
   option(Merge.onMatch,tail(local))  <4>
 g.V(400).valueMap().with(WithOptions.tokens)  <5>
@@ -3997,9 +4001,15 @@ second and third location for each vertex.
 
 [gremlin-groovy,theCrew]
 ----
-g.V().valueMap().select('location').range(local, 1, 3)
+g.V().valueMap().select('location').range(local, 1, 3) <1>
+g.V().valueMap().select('location').range(local, 1, 2) <2>
+g.V().valueMap().select('location').range(local, 1, 2).unfold() <3>
 ----
 
+<1> `List<String>` for each vertex containing the second and third locations.
+<2> `List<String>` for each vertex containing the second location.
+<3> `String` for each vertex containing the second location (use `unfold()` to 
extract single elements from singleton collections).
+
 *Additional References*
 
 
link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#range(long,long)++[`range(long,long)`],
@@ -4612,7 +4622,7 @@ g.V().hasLabel('person').filter(outE('created')).as('p'). 
<1>
   map(out('created').values('name').fold()).
   project('person','primary','other').
     by(select('p').by('name')).
-    by(limit(local, 1)). <2>
+    by(limit(local, 1).unfold()). <2>
     by(skip(local, 1)) <3>
 ----
 
@@ -4826,14 +4836,18 @@ The `tail()`-step can also be applied with 
`Scope.local`, in which case it opera
 ----
 
g.V().as('a').out().as('a').out().as('a').select('a').by(tail(local)).values('name')
 <1>
 
g.V().as('a').out().as('a').out().as('a').select('a').by(unfold().values('name').fold()).tail(local)
 <2>
-g.V().as('a').out().as('a').out().as('a').select('a').by(unfold().values('name').fold()).tail(local,
 2) <3>
-g.V().elementMap().tail(local) <4>
+g.V().as('a').out().as('a').out().as('a').select('a').by(unfold().values('name').fold()).tail(local,
 1) <3>
+g.V().as('a').out().as('a').out().as('a').select('a').by(unfold().values('name').fold()).tail(local,
 1).unfold() <4>
+g.V().as('a').out().as('a').out().as('a').select('a').by(unfold().values('name').fold()).tail(local,
 2) <5>
+g.V().elementMap().tail(local) <6>
 ----
 
 <1> Only the most recent name from the "a" step (`List<Vertex>` becomes 
`Vertex`).
-<2> Same result as statement 1 (`List<String>` becomes `String`).
-<3> `List<String>` for each path containing the last two names from the 'a' 
step.
-<4> `Map<String, Object>` for each vertex, but containing only the last 
property value.
+<2> `List<String>` for each path containing the last name from the 'a' step.
+<3> Same as statement 2 (`List<String>` for each path containing the last 
name).
+<4> `String` for each path containing the last name (use `unfold()` to extract 
single elements from singleton collections).
+<5> `List<String>` for each path containing the last two names from the 'a' 
step.
+<6> `Map<String, Object>` for each vertex, containing only the last property 
value.
 
 *Additional References*
 
diff --git a/docs/src/upgrade/release-3.8.x.asciidoc 
b/docs/src/upgrade/release-3.8.x.asciidoc
index 66ea41039e..14bbf710bc 100644
--- a/docs/src/upgrade/release-3.8.x.asciidoc
+++ b/docs/src/upgrade/release-3.8.x.asciidoc
@@ -509,6 +509,60 @@ The `GremlinLangScriptEngine` has been modified to treat 
float literals without
 or 'd') as Double by default. Users who need `BigDecimal` precision can still 
use the 'm' suffix (e.g., 1.0m).
 `GremlinGroovyScriptEngine` will still default to `BigDecimal` for `float` 
literals.
 
+==== Consistent Output for range(), limit(), tail()
+
+The `range(local)`, `limit(local)`, and `tail(local)` steps now consistently 
return collections rather than automatically 
+unfolding single-element results when operating on iterable collections (List, 
Set, etc.). Previously, when these steps 
+operated on collections and the result contained only one element, the step 
would return the single element directly 
+instead of a collection containing that element.
+
+This change ensures predictable return types based on the input type, making 
the behavior more consistent and intuitive.
+Note that this change only affects iterable collections - Map objects continue 
to behave as before.
+
+[WARNING]
+====
+This is a breaking change that may require modifications to existing queries. 
If your queries relied on the previous 
+behavior of receiving single elements directly from `range(local)`, 
`limit(local)`, or `tail(local)` steps, you will 
+need to add `.unfold()` after these steps to maintain the same functionality. 
Without this update, some existing queries 
+may throw a `ClassCastException` while others may return unexpected results.
+====
+
+[source,text]
+----
+// 3.7.x and earlier - inconsistent output types for collections
+gremlin> g.inject([1, 2, 3]).limit(local, 1)
+==>1  // single element returned directly
+
+gremlin> g.inject([1, 2, 3]).limit(local, 2) 
+==>[1,2]  // collection returned
+
+// 3.8.0 - consistent collection output for collections
+gremlin> g.inject([1, 2, 3]).limit(local, 1)
+==>[1]  // collection always returned
+
+gremlin> g.inject([1, 2, 3]).limit(local, 2)
+==>[1,2]  // collection returned
+
+// Map behavior unchanged in both versions
+gremlin> g.inject([a: 1, b: 2, c: 3]).limit(local, 1)
+==>[a:1]  // Map entry returned (behavior unchanged)
+----
+
+If you need the old behavior of extracting single elements from collections, 
you can add `.unfold()` after the local step:
+
+[source,text]
+----
+gremlin> g.inject([1, 2, 3]).limit(local, 1).unfold()
+==>1
+----
+
+This change affects all three local collection manipulation steps when 
operating on iterable collections:
+- `range(local, low, high)` 
+- `limit(local, count)`
+- `tail(local, count)`
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-2491[TINKERPOP-2491]
+
 ==== group() Value Traversal Semantics
 
 The `group()` step takes two `by()` modulators. The first defines the key for 
the grouping, and the second acts upon the
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
index 4b19345330..fa2a9c46f2 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
@@ -116,34 +116,18 @@ public final class RangeLocalStep<S> extends 
ScalarMapStep<S, S> implements Rang
     /**
      * Extracts specified range of elements from a Collection.
      */
-    private static Object applyRangeIterable(final Iterable<Object> iterable, 
final long low, final long high) {
-        // See if we only want a single item.  It is also possible that we 
will allow more than one item, but that the
-        // incoming container is only capable of producing a single item.  In 
that case, we will still emit a
-        // container.  This allows the result type to be predictable based on 
the step arguments.  It also allows us to
-        // avoid creating the result container for the single case.
-        boolean single = high != -1 ? (high - low == 1) : false;
-
-        final Collection resultCollection =
-                single ? null : (iterable instanceof Set) ? new 
LinkedHashSet() : new LinkedList();
-        Object result = single ? null : resultCollection;
+    private static Collection applyRangeIterable(final Iterable<Object> 
iterable, final long low, final long high) {
+        final Collection resultCollection = iterable instanceof Set ? new 
LinkedHashSet() : new LinkedList();
         long c = 0L;
         for (final Object item : iterable) {
             if (c >= low) {
                 if (c < high || high == -1) {
-                    if (single) {
-                        result = item;
-                        break;
-                    } else {
-                        resultCollection.add(item);
-                    }
+                    resultCollection.add(item);
                 } else break;
             }
             c++;
         }
-        if (null == result)
-            // We have nothing to emit, so stop traversal.
-            throw FastNoSuchElementException.instance();
-        return result;
+        return resultCollection;
     }
 
     @Override
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStepTest.java
index 359a8d19b0..c7ef28e4fe 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStepTest.java
@@ -19,7 +19,10 @@
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
 import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.tinkerpop.gremlin.process.traversal.Scope;
@@ -31,7 +34,10 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.step.GValueStepTest;
 import 
org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeStepPlaceholder;
 import org.junit.Test;
 
+import static 
org.apache.tinkerpop.gremlin.process.traversal.step.map.RangeLocalStep.applyRange;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 /**
  * @author Daniel Kuppitz (http://gremlin.guru)
@@ -100,4 +106,95 @@ public class RangeLocalStepTest extends GValueStepTest {
         assertEquals((Long) LOW_VALUE, 
((RangeStepPlaceholder.RangeLocalStepPlaceholder) 
traversal.getSteps().get(0)).asConcreteStep().getLowRange());
         assertEquals((Long) HIGH_VALUE, 
((RangeStepPlaceholder.RangeLocalStepPlaceholder) 
traversal.getSteps().get(0)).asConcreteStep().getHighRange());
     }
+
+    @Test
+    public void applyRangeShouldReturnCollectionForSingleElementFromList() {
+        // Test that range(local) returns a collection even for single element 
results
+        assertEquals(List.of(2), applyRange(List.of(1, 2, 3), 1, 2));
+    }
+
+    @Test
+    public void applyRangeShouldReturnCollectionForSingleElementFromSet() {
+        // Test that range(local) preserves Set type and returns a collection
+        assertEquals(Set.of(2), applyRange(new LinkedHashSet<>(List.of(1, 2, 
3)), 1, 2));
+    }
+
+    @Test
+    public void applyRangeShouldReturnMultipleElementsFromList() {
+        // Test that range(local) returns multiple elements as expected
+        assertEquals(List.of(2, 3, 4), applyRange(List.of(1, 2, 3, 4, 5), 1, 
4));
+    }
+
+    @Test
+    public void applyRangeShouldReturnEmptyCollectionForEmptyRange() {
+        // Test that range(local) returns empty collection when range produces 
no results
+        assertTrue(applyRange(List.of(1, 2, 3), 5, 10).isEmpty());
+    }
+
+    @Test
+    public void applyRangeShouldReturnSingletonMap() {
+        // Test that Map behavior is unchanged - should return Map with 
selected entries
+        final Map<String, Integer> input = new LinkedHashMap<>();
+        input.put("a", 1);
+        input.put("b", 2);
+        input.put("c", 3);
+
+        final Map<String, Integer> result = applyRange(input, 1, 2);
+        assertEquals(1, result.size());
+        assertEquals((Integer) 2, result.get("b"));
+    }
+
+    @Test
+    public void applyRangeShouldReturnMapWithMultipleEntries() {
+        // Test that Map behavior works correctly with multiple entries
+        final Map<String, Integer> input = new LinkedHashMap<>();
+        input.put("a", 1);
+        input.put("b", 2);
+        input.put("c", 3);
+        input.put("d", 4);
+
+        final Map<String, Integer> result = applyRange(input, 1, 3);
+        assertEquals(2, result.size());
+        assertEquals((Integer) 2, result.get("b"));
+        assertEquals((Integer) 3, result.get("c"));
+    }
+
+    @Test
+    public void applyRangeShouldHandleNonCollectionObjects() {
+        // Test that non-collection objects are returned as-is
+        final String input = "test";
+        final Object result = applyRange(input, 0, 1);
+        assertEquals(input, result);
+    }
+
+    @Test
+    public void applyRangeShouldHandleNullInput() {
+        // Test that null input is returned as-is
+        assertNull(applyRange(null, 0, 1));
+    }
+
+    @Test
+    public void applyRangeShouldHandleArrayInput() {
+        // Test that array input is converted to collection and processed
+        final Object result = applyRange(new int[]{1, 2, 3, 4, 5}, 1, 3);
+        assertEquals(List.of(2, 3), result);
+    }
+
+    @Test
+    public void applyRangeShouldHandleLimitLocalEquivalent() {
+        // Test that limit(local, n) equivalent to range(local, 0, n) returns 
collection
+        assertEquals(List.of(1), applyRange(List.of(1, 2, 3, 4, 5), 0, 1));
+    }
+
+    @Test
+    public void applyRangeShouldHandleTailLocalEquivalent() {
+        // Test that tail(local, n) equivalent behavior returns collection
+        assertEquals(List.of(5), applyRange(List.of(1, 2, 3, 4, 5), 4, 5));
+    }
+
+    @Test
+    public void applyRangeShouldHandleUnboundedRange() {
+        // Test that unbounded range (high = -1) works correctly
+        assertEquals(List.of(3, 4, 5), applyRange(List.of(1, 2, 3, 4, 5), 2, 
-1));
+    }
 }
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 5e9bf207bf..2e6452c55b 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -408,6 +408,11 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_mapXin_hasIdX1XX_limitX2X_valuesXnameX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Map<object>(__.In().HasId(p["vid1"])).Limit<object>(2).Values<object>("name")}},
 
                {"g_V_rangeX2_1X", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Range<object>(2, 1)}}, 
                {"g_V_rangeX3_2X", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Range<object>(3, 2)}}, 
+               {"g_injectXlistX1_2_3XX_rangeXlocal_1_2X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2, 3 
}).Range<object>(Scope.Local, 1, 2)}}, 
+               {"g_injectXlistX1_2_3XX_limitXlocal_1X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2, 3 
}).Limit<object>(Scope.Local, 1)}}, 
+               {"g_injectXlistX1_2_3X_limitXlocal_1X_unfold", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2, 3 
}).Limit<object>(Scope.Local, 1).Unfold<object>()}}, 
+               {"g_injectX1_2_3_4_5X_limitXlocal_1X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2 }, new List<object> { 3, 4, 5 
}).Limit<object>(Scope.Local, 1)}}, 
+               {"g_injectX1_2_3_4_5_6X_rangeXlocal_1_2X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2, 3 }, new List<object> { 4, 
5, 6 }).Range<object>(Scope.Local, 1, 2)}}, 
                {"g_V_sampleX1X_byXageX_byXT_idX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().Sample(1).By("age").By(T.Id)}}, 
                {"g_E_sampleX1X", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Sample(1)}}, 
                {"g_E_sampleX2X_byXweightX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.E().Sample(2).By("weight")}}, 
@@ -428,16 +433,21 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_valuesXnameX_order_tailX7X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().Values<object>("name").Order().Tail<object>(7)}}, 
                {"g_V_repeatXbothX_timesX3X_tailX7X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().Repeat(__.Both()).Times(3).Tail<object>(7)}}, 
                {"g_V_repeatXin_outX_timesX3X_tailX7X_count", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().Repeat(__.In().Out()).Times(3).Tail<object>(7).Count()}}, 
-               
{"g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().As("a").Out().As("a").Out().As("a").Select<object>("a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local,
 1)}}, 
-               
{"g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().As("a").Out().As("a").Out().As("a").Select<object>("a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local)}},
 
+               
{"g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().As("a").Out().As("a").Out().As("a").Select<object>("a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local,
 1).Unfold<object>()}}, 
+               
{"g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().As("a").Out().As("a").Out().As("a").Select<object>("a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local).Unfold<object>()}},
 
                
{"g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("b").Out().As("c").Select<object>("a", "b", 
"c").By("name").Tail<object>(Scope.Local, 2)}}, 
                
{"g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2varX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("b").Out().As("c").Select<object>("a", "b", 
"c").By("name").Tail<object>(Scope.Local, p["xx1"])}}, 
                
{"g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_1X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("b").Out().As("c").Select<object>("a", "b", 
"c").By("name").Tail<object>(Scope.Local, 1)}}, 
-               
{"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("a").Out().As("a").Select<object>(Pop.Mixed, 
"a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local,
 1)}}, 
-               
{"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("a").Out().As("a").Select<object>(Pop.Mixed, 
"a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local)}},
 
+               
{"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("a").Out().As("a").Select<object>(Pop.Mixed, 
"a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local,
 1).Unfold<object>()}}, 
+               
{"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("a").Out().As("a").Select<object>(Pop.Mixed, 
"a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local).Unfold<object>()}},
 
                
{"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("a").Out().As("a").Select<object>(Pop.Mixed, 
"a").By(__.Limit<object>(Scope.Local, 0)).Tail<object>(Scope.Local, 1)}}, 
                
{"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_2X",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().As("a").Out().As("a").Out().As("a").Select<object>(Pop.Mixed, 
"a").By(__.Unfold<object>().Values<object>("name").Fold()).Tail<object>(Scope.Local,
 2)}}, 
                {"g_VX1X_valuesXageX_tailXlocal_5X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V(p["vid1"]).Values<object>("age").Tail<object>(Scope.Local, 50)}}, 
+               {"g_injectXlistX1_2_3XX_tailXlocal_1X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2, 3 
}).Tail<object>(Scope.Local, 1)}}, 
+               {"g_injectXa1_b2_c3X_tailXlocal_1X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new Dictionary<object, object> {{ "a", 1 }, { "b", 2 
}, { "c", 3 }}).Tail<object>(Scope.Local, 1)}}, 
+               {"g_injectX1_2_3X_tailXlocal_1X_unfold", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2, 3 
}).Tail<object>(Scope.Local, 1).Unfold<object>()}}, 
+               {"g_injectX1_2_3_4_5_6X_tailXlocal_1X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2, 3 }, new List<object> { 4, 
5, 6 }).Tail<object>(Scope.Local, 1)}}, 
+               {"g_injectX1_2_3_4_5X_tailXlocal_2X", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(new List<object> { 1, 2, 3, 4, 5 
}).Tail<object>(Scope.Local, 2)}}, 
                
{"g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXa_eqXbXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Has("age").As("a").Out().In().Has("age").As("b").Select<object>("a", 
"b").Where("a", P.Eq("b"))}}, 
                
{"g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXa_neqXbXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Has("age").As("a").Out().In().Has("age").As("b").Select<object>("a", 
"b").Where("a", P.Neq("b"))}}, 
                
{"g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXb_hasXname_markoXX",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Has("age").As("a").Out().In().Has("age").As("b").Select<object>("a", 
"b").Where(__.As("b").Has("name", "marko"))}}, 
@@ -1110,8 +1120,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                
{"g_V_asXvX_mergeEXxx1X_optionXMerge_onMatch_xx2X_optionXMerge_outV_selectXvXX_optionXMerge_inV_selectXvXX",
 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.OnMatch, (IDictionary<object, object>) 
p["xx2"]).Option(Merge.OutV, (ITraversal) 
__.Select<object>("v")).Option(Merge.InV, (ITraversal) [...]
                
{"g_V_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_sideEffectXpropertyXweight_0XX_constantXemptyXX",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", 
"marko").As("a").AddV("person").Property("name", 
"vadas").As("b").AddE("knows").Property("weight", 1).From("a").To("b"), (g,p) 
=>g.V().MergeE((IDictionary<object, object>) p["xx1"]).Option(Merge.OnMatch, 
(ITraversal) __.SideEffect(__.Property("we [...]
                
{"g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_sideEffectXpropertyXweight_0XX_constantXemptyXX",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", 
"marko").As("a").AddV("person").Property("name", 
"vadas").As("b").AddE("knows").Property("weight", 1).From("a").To("b"), (g,p) 
=>g.MergeE((IDictionary<object, object>) p["xx1"]).Option(Merge.OnMatch, 
(ITraversal) __.SideEffect(__.Property("weight", [...]
-               
{"g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_match",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 
29).As("marko").AddV("person").Property("name", "vadas").Property("age", 
27).As("vadas").AddV("software").Property("name", "lop").Property("lang", 
"java").As("lop").AddV("person") [...]
-               
{"g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_create",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 
29).As("marko").AddV("person").Property("name", "vadas").Property("age", 
27).As("vadas").AddV("software").Property("name", "lop").Property("lang", 
"java").As("lop").AddV("person" [...]
+               
{"g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 
29).As("marko").AddV("person").Property("name", "vadas").Property("age", 
27).As("vadas").AddV("software").Property("name", "lop").Property("lang", 
"java").As( [...]
+               
{"g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 
29).As("marko").AddV("person").Property("name", "vadas").Property("age", 
27).As("vadas").AddV("software").Property("name", "lop").Property("lang", 
"java").As [...]
                
{"g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_weight_nullX_allowed",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", 
"marko").As("a").AddV("person").Property("name", 
"vadas").As("b").AddE("knows").From("a").To("b").Property("weight", 1.0d), 
(g,p) =>g.MergeE((IDictionary<object, object>) p["xx1"]).Option(Merge.OnMatch, 
(IDictionary<object, object>) p["xx2"]), (g,p) =>g.V(), (g,p) =>g.E().Ha [...]
                
{"g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_weight_nullX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", 
"marko").As("a").AddV("person").Property("name", 
"vadas").As("b").AddE("knows").From("a").To("b").Property("weight", 1.0d), 
(g,p) =>g.MergeE((IDictionary<object, object>) p["xx1"]).Option(Merge.OnMatch, 
(IDictionary<object, object>) p["xx2"]), (g,p) =>g.V(), (g,p) 
=>g.E().HasLabel(" [...]
                {"g_mergeVXemptyX_optionXonMatch_nullX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29), (g,p) 
=>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> 
{}).Option(Merge.OnMatch, (IDictionary<object, object>) null), (g,p) 
=>g.V().Has("person", "name", "marko").Has("age", 29)}}, 
@@ -1174,8 +1184,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_mergeVXname_aliceX_optionXonCreate_age_setX81XX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> 
{{ "name", "alice" }, { T.Label, "person" }}).Option(Merge.OnCreate, 
(IDictionary<object, object>) new Dictionary<object, object> {{ "age", 
CardinalityValue.Set(81) }}), (g,p) =>g.V().Has("person", "name", 
"alice").Has("age", 81), (g,p) =>g.V().Has("person", "name", [...]
                
{"g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> 
{{ "name", "alice" }, { T.Label, "person" }}).Option(Merge.OnCreate, new 
Dictionary<object, object> {{ "age", 81 }}, Cardinality.Set), (g,p) 
=>g.V().Has("person", "name", "alice").Has("age", 81), (g,p) 
=>g.V().Has("person", "name", "alice").Has("age"), [...]
                {"g_mergeV_hidden_label_key_onMatch_matched_prohibited", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> 
{}).Option(Merge.OnMatch, (IDictionary<object, object>) p["xx1"])}}, 
-               
{"g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_match",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29), (g,p) 
=>g.Inject<object>(new Dictionary<object, object> {{ T.Label, "person" }, { 
"name", "marko" }}, new Dictionary<object, object> {{ T.Label, "person" }, { 
"name", "marko" }}, new Dictionary<object, objec [...]
-               
{"g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_create",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29), (g,p) 
=>g.Inject<object>(new Dictionary<object, object> {{ T.Label, "person" }, { 
"name", "stephen" }}, new Dictionary<object, object> {{ T.Label, "person" }, { 
"name", "stephen" }}, new Dictionary<object,  [...]
+               
{"g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29), (g,p) 
=>g.Inject<object>(new Dictionary<object, object> {{ T.Label, "person" }, { 
"name", "marko" }}, new Dictionary<object, object> {{ T.Label, "person" }, { 
"name", "marko" }}, new Di [...]
+               
{"g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create",
 new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29), (g,p) 
=>g.Inject<object>(new Dictionary<object, object> {{ T.Label, "person" }, { 
"name", "stephen" }}, new Dictionary<object, object> {{ T.Label, "person" }, { 
"name", "stephen" }}, n [...]
                {"g_V_age_min", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.V().Values<object>("age").Min<object>()}}, 
                {"g_V_foo_min", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.V().Values<object>("foo").Min<object>()}}, 
                {"g_V_name_min", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.V().Values<object>("name").Min<object>()}}, 
diff --git a/gremlin-go/driver/cucumber/gremlin.go 
b/gremlin-go/driver/cucumber/gremlin.go
index 86a5f5f4d2..4d5b7339b7 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -378,6 +378,11 @@ var translationMap = map[string][]func(g 
*gremlingo.GraphTraversalSource, p map[
     "g_V_mapXin_hasIdX1XX_limitX2X_valuesXnameX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Map(gremlingo.T__.In().HasId(p["vid1"])).Limit(2).Values("name")}}, 
     "g_V_rangeX2_1X": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Range(2, 1)}}, 
     "g_V_rangeX3_2X": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Range(3, 2)}}, 
+    "g_injectXlistX1_2_3XX_rangeXlocal_1_2X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2, 
3}).Range(gremlingo.Scope.Local, 1, 2)}}, 
+    "g_injectXlistX1_2_3XX_limitXlocal_1X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2, 
3}).Limit(gremlingo.Scope.Local, 1)}}, 
+    "g_injectXlistX1_2_3X_limitXlocal_1X_unfold": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2, 
3}).Limit(gremlingo.Scope.Local, 1).Unfold()}}, 
+    "g_injectX1_2_3_4_5X_limitXlocal_1X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2}, 
[]interface{}{3, 4, 5}).Limit(gremlingo.Scope.Local, 1)}}, 
+    "g_injectX1_2_3_4_5_6X_rangeXlocal_1_2X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2, 3}, 
[]interface{}{4, 5, 6}).Range(gremlingo.Scope.Local, 1, 2)}}, 
     "g_V_sampleX1X_byXageX_byXT_idX": {func(g *gremlingo.GraphTraversalSource, 
p map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Sample(1).By("age").By(gremlingo.T.Id)}}, 
     "g_E_sampleX1X": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return g.E().Sample(1)}}, 
     "g_E_sampleX2X_byXweightX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.E().Sample(2).By("weight")}}, 
@@ -398,16 +403,21 @@ var translationMap = map[string][]func(g 
*gremlingo.GraphTraversalSource, p map[
     "g_V_valuesXnameX_order_tailX7X": {func(g *gremlingo.GraphTraversalSource, 
p map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Values("name").Order().Tail(7)}}, 
     "g_V_repeatXbothX_timesX3X_tailX7X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Repeat(gremlingo.T__.Both()).Times(3).Tail(7)}}, 
     "g_V_repeatXin_outX_timesX3X_tailX7X_count": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Repeat(gremlingo.T__.In().Out()).Times(3).Tail(7).Count()}}, 
-    
"g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select("a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local,
 1)}}, 
-    
"g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select("a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local)}},
 
+    
"g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select("a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local,
 1).Unfold()}}, 
+    
"g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select("a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local).Unfold()}},
 
     "g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2X": 
{func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("b").Out().As("c").Select("a", "b", 
"c").By("name").Tail(gremlingo.Scope.Local, 2)}}, 
     "g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2varX": 
{func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("b").Out().As("c").Select("a", "b", 
"c").By("name").Tail(gremlingo.Scope.Local, p["xx1"])}}, 
     "g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_1X": 
{func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("b").Out().As("c").Select("a", "b", 
"c").By("name").Tail(gremlingo.Scope.Local, 1)}}, 
-    
"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select(gremlingo.Pop.Mixed, 
"a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local,
 1)}}, 
-    
"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select(gremlingo.Pop.Mixed, 
"a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local)}},
 
+    
"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select(gremlingo.Pop.Mixed, 
"a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local,
 1).Unfold()}}, 
+    
"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select(gremlingo.Pop.Mixed, 
"a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local).Unfold()}},
 
     
"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select(gremlingo.Pop.Mixed, 
"a").By(gremlingo.T__.Limit(gremlingo.Scope.Local, 
0)).Tail(gremlingo.Scope.Local, 1)}}, 
     
"g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_2X":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().As("a").Out().As("a").Out().As("a").Select(gremlingo.Pop.Mixed, 
"a").By(gremlingo.T__.Unfold().Values("name").Fold()).Tail(gremlingo.Scope.Local,
 2)}}, 
     "g_VX1X_valuesXageX_tailXlocal_5X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V(p["vid1"]).Values("age").Tail(gremlingo.Scope.Local, 50)}}, 
+    "g_injectXlistX1_2_3XX_tailXlocal_1X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2, 
3}).Tail(gremlingo.Scope.Local, 1)}}, 
+    "g_injectXa1_b2_c3X_tailXlocal_1X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject(map[interface{}]interface{}{"a": 1, 
"b": 2, "c": 3 }).Tail(gremlingo.Scope.Local, 1)}}, 
+    "g_injectX1_2_3X_tailXlocal_1X_unfold": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2, 
3}).Tail(gremlingo.Scope.Local, 1).Unfold()}}, 
+    "g_injectX1_2_3_4_5_6X_tailXlocal_1X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2, 3}, 
[]interface{}{4, 5, 6}).Tail(gremlingo.Scope.Local, 1)}}, 
+    "g_injectX1_2_3_4_5X_tailXlocal_2X": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject([]interface{}{1, 2, 3, 4, 
5}).Tail(gremlingo.Scope.Local, 2)}}, 
     "g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXa_eqXbXX": 
{func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Has("age").As("a").Out().In().Has("age").As("b").Select("a", 
"b").Where("a", gremlingo.P.Eq("b"))}}, 
     "g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXa_neqXbXX": 
{func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Has("age").As("a").Out().In().Has("age").As("b").Select("a", 
"b").Where("a", gremlingo.P.Neq("b"))}}, 
     
"g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXb_hasXname_markoXX":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Has("age").As("a").Out().In().Has("age").As("b").Select("a", 
"b").Where(gremlingo.T__.As("b").Has("name", "marko"))}}, 
@@ -1080,8 +1090,8 @@ var translationMap = map[string][]func(g 
*gremlingo.GraphTraversalSource, p map[
     
"g_V_asXvX_mergeEXxx1X_optionXMerge_onMatch_xx2X_optionXMerge_outV_selectXvXX_optionXMerge_inV_selectXvXX":
 {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.OnMatch, 
p["xx2"]).Option(gremlingo.Merge.OutV, gremlingo.T_ [...]
     
"g_V_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_sideEffectXpropertyXweight_0XX_constantXemptyXX":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("person").Property("name", 
"marko").As("a").AddV("person").Property("name", 
"vadas").As("b").AddE("knows").Property("weight", 1).From("a").To("b")}, func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.V().MergeE(p["xx1"]) [...]
     
"g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_sideEffectXpropertyXweight_0XX_constantXemptyXX":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("person").Property("name", 
"marko").As("a").AddV("person").Property("name", 
"vadas").As("b").AddE("knows").Property("weight", 1).From("a").To("b")}, func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.MergeE(p["xx1"]).Optio [...]
-    
"g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_match":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("person").Property("name", 
"marko").Property("age", 29).As("marko").AddV("person").Property("name", 
"vadas").Property("age", 27).As("vadas").AddV("software").Property("name", 
"lop").Property("lang", "java").As("lop").AddV("person [...]
-    
"g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_create":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("person").Property("name", 
"marko").Property("age", 29).As("marko").AddV("person").Property("name", 
"vadas").Property("age", 27).As("vadas").AddV("software").Property("name", 
"lop").Property("lang", "java").As("lop").AddV("perso [...]
+    
"g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("person").Property("name", 
"marko").Property("age", 29).As("marko").AddV("person").Property("name", 
"vadas").Property("age", 27).As("vadas").AddV("software").Property("name", 
"lop").Property("lang", "java").A [...]
+    
"g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create":
 {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("person").Property("name", 
"marko").Property("age", 29).As("marko").AddV("person").Property("name", 
"vadas").Property("age", 27).As("vadas").AddV("software").Property("name", 
"lop").Property("lang", "java"). [...]
     
"g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_weight_nullX_allowed": 
{func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("person").Property("name", 
"marko").As("a").AddV("person").Property("name", 
"vadas").As("b").AddE("knows").From("a").To("b").Property("weight", 1.0)}, 
func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.MergeE(p["xx1"]).Option(gremlingo.Merge.OnMatch [...]
     "g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_weight_nullX": 
{func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.AddV("person").Property("name", 
"marko").As("a").AddV("person").Property("name", 
"vadas").As("b").AddE("knows").From("a").To("b").Property("weight", 1.0)}, 
func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.MergeE(p["xx1"]).Option(gremlingo.Merge.OnMatch, p["xx2 [...]
     "g_mergeVXemptyX_optionXonMatch_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.MergeV(map[interface{}]interface{}{ }).Option(gremlingo.Merge.OnMatch, nil)}, 
func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g. [...]
@@ -1144,8 +1154,8 @@ var translationMap = map[string][]func(g 
*gremlingo.GraphTraversalSource, p map[
     "g_mergeVXname_aliceX_optionXonCreate_age_setX81XX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{"name": 
"alice", gremlingo.T.Label: "person" }).Option(gremlingo.Merge.OnCreate, 
map[interface{}]interface{}{"age": gremlingo.CardinalityValue.Set(81) })}, 
func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has( 
[...]
     "g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{"name": 
"alice", gremlingo.T.Label: "person" }).Option(gremlingo.Merge.OnCreate, 
map[interface{}]interface{}{"age": 81 }, gremlingo.Cardinality.Set)}, func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.V().Has("person", "name", "ali [...]
     "g_mergeV_hidden_label_key_onMatch_matched_prohibited": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{ 
}).Option(gremlingo.Merge.OnMatch, p["xx1"])}}, 
-    
"g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_match":
 {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.Inject(map[interface{}]interface{}{gremlingo.T.Label: "person", "name": 
"marko" }, map[interface{}]int [...]
-    
"g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_create":
 {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.Inject(map[interface{}]interface{}{gremlingo.T.Label: "person", "name": 
"stephen" }, map[interface{}] [...]
+    
"g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match":
 {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.Inject(map[interface{}]interface{}{gremlingo.T.Label: "person", "name": 
"marko"  [...]
+    
"g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create":
 {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.Inject(map[interface{}]interface{}{gremlingo.T.Label: "person", "name": 
"stephe [...]
     "g_V_age_min": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Values("age").Min()}}, 
     "g_V_foo_min": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Values("foo").Min()}}, 
     "g_V_name_min": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Values("name").Min()}}, 
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 42ba624d17..873d6e921a 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
@@ -408,6 +408,11 @@ const gremlins = {
     g_V_mapXin_hasIdX1XX_limitX2X_valuesXnameX: [function({g, vid1}) { return 
g.V().map(__.in_().hasId(vid1)).limit(2).values("name") }], 
     g_V_rangeX2_1X: [function({g}) { return g.V().range(2, 1) }], 
     g_V_rangeX3_2X: [function({g}) { return g.V().range(3, 2) }], 
+    g_injectXlistX1_2_3XX_rangeXlocal_1_2X: [function({g}) { return 
g.inject([1, 2, 3]).range(Scope.local, 1, 2) }], 
+    g_injectXlistX1_2_3XX_limitXlocal_1X: [function({g}) { return g.inject([1, 
2, 3]).limit(Scope.local, 1) }], 
+    g_injectXlistX1_2_3X_limitXlocal_1X_unfold: [function({g}) { return 
g.inject([1, 2, 3]).limit(Scope.local, 1).unfold() }], 
+    g_injectX1_2_3_4_5X_limitXlocal_1X: [function({g}) { return g.inject([1, 
2], [3, 4, 5]).limit(Scope.local, 1) }], 
+    g_injectX1_2_3_4_5_6X_rangeXlocal_1_2X: [function({g}) { return 
g.inject([1, 2, 3], [4, 5, 6]).range(Scope.local, 1, 2) }], 
     g_V_sampleX1X_byXageX_byXT_idX: [function({g}) { return 
g.V().sample(1).by("age").by(T.id) }], 
     g_E_sampleX1X: [function({g}) { return g.E().sample(1) }], 
     g_E_sampleX2X_byXweightX: [function({g}) { return 
g.E().sample(2).by("weight") }], 
@@ -428,16 +433,21 @@ const gremlins = {
     g_V_valuesXnameX_order_tailX7X: [function({g}) { return 
g.V().values("name").order().tail(7) }], 
     g_V_repeatXbothX_timesX3X_tailX7X: [function({g}) { return 
g.V().repeat(__.both()).times(3).tail(7) }], 
     g_V_repeatXin_outX_timesX3X_tailX7X_count: [function({g}) { return 
g.V().repeat(__.in_().out()).times(3).tail(7).count() }], 
-    
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local,
 1) }], 
-    
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local)
 }], 
+    
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local,
 1).unfold() }], 
+    
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local).unfold()
 }], 
     g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2X: 
[function({g}) { return g.V().as("a").out().as("b").out().as("c").select("a", 
"b", "c").by("name").tail(Scope.local, 2) }], 
     g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2varX: 
[function({g, xx1}) { return 
g.V().as("a").out().as("b").out().as("c").select("a", "b", 
"c").by("name").tail(Scope.local, xx1) }], 
     g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_1X: 
[function({g}) { return g.V().as("a").out().as("b").out().as("c").select("a", 
"b", "c").by("name").tail(Scope.local, 1) }], 
-    
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local, 1) }], 
-    
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local) }], 
+    
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local, 1).unfold() }], 
+    
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local).unfold() }], 
     
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X: 
[function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.limit(Scope.local, 0)).tail(Scope.local, 1) }], 
     
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_2X:
 [function({g}) { return 
g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local, 2) }], 
     g_VX1X_valuesXageX_tailXlocal_5X: [function({g, vid1}) { return 
g.V(vid1).values("age").tail(Scope.local, 50) }], 
+    g_injectXlistX1_2_3XX_tailXlocal_1X: [function({g}) { return g.inject([1, 
2, 3]).tail(Scope.local, 1) }], 
+    g_injectXa1_b2_c3X_tailXlocal_1X: [function({g}) { return g.inject(new 
Map([["a", 1], ["b", 2], ["c", 3]])).tail(Scope.local, 1) }], 
+    g_injectX1_2_3X_tailXlocal_1X_unfold: [function({g}) { return g.inject([1, 
2, 3]).tail(Scope.local, 1).unfold() }], 
+    g_injectX1_2_3_4_5_6X_tailXlocal_1X: [function({g}) { return g.inject([1, 
2, 3], [4, 5, 6]).tail(Scope.local, 1) }], 
+    g_injectX1_2_3_4_5X_tailXlocal_2X: [function({g}) { return g.inject([1, 2, 
3, 4, 5]).tail(Scope.local, 2) }], 
     g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXa_eqXbXX: 
[function({g}) { return 
g.V().has("age").as("a").out().in_().has("age").as("b").select("a", 
"b").where("a", P.eq("b")) }], 
     g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXa_neqXbXX: 
[function({g}) { return 
g.V().has("age").as("a").out().in_().has("age").as("b").select("a", 
"b").where("a", P.neq("b")) }], 
     
g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXb_hasXname_markoXX: 
[function({g}) { return 
g.V().has("age").as("a").out().in_().has("age").as("b").select("a", 
"b").where(__.as("b").has("name", "marko")) }], 
@@ -1110,8 +1120,8 @@ const gremlins = {
     
g_V_asXvX_mergeEXxx1X_optionXMerge_onMatch_xx2X_optionXMerge_outV_selectXvXX_optionXMerge_inV_selectXvXX:
 [function({g, xx1, xx2}) { return g.addV("person").property("name", 
"marko").property("age", 29) }, function({g, xx1, xx2}) { return 
g.V().as("v").mergeE(xx1).option(Merge.onMatch, xx2).option(Merge.outV, 
__.select("v")).option(Merge.inV, __.select("v")) }], 
     
g_V_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_sideEffectXpropertyXweight_0XX_constantXemptyXX:
 [function({g, xx1}) { return g.addV("person").property("name", 
"marko").as("a").addV("person").property("name", 
"vadas").as("b").addE("knows").property("weight", 1).from_("a").to("b") }, 
function({g, xx1}) { return g.V().mergeE(xx1).option(Merge.onMatch, 
__.sideEffect(__.property("weight", 0)).constant(new Map([]))) }], 
     
g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_sideEffectXpropertyXweight_0XX_constantXemptyXX:
 [function({g, xx1}) { return g.addV("person").property("name", 
"marko").as("a").addV("person").property("name", 
"vadas").as("b").addE("knows").property("weight", 1).from_("a").to("b") }, 
function({g, xx1}) { return g.mergeE(xx1).option(Merge.onMatch, 
__.sideEffect(__.property("weight", 0)).constant(new Map([]))) }, function({g, 
xx1}) { return g.V() }, function({g, xx1}) { return g [...]
-    
g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_match:
 [function({g}) { return g.addV("person").property("name", 
"marko").property("age", 29).as("marko").addV("person").property("name", 
"vadas").property("age", 27).as("vadas").addV("software").property("name", 
"lop").property("lang", "java").as("lop").addV("person").property("name", 
"josh").property("age", 32).as("josh").addV("software").pro [...]
-    
g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_create:
 [function({g}) { return g.addV("person").property("name", 
"marko").property("age", 29).as("marko").addV("person").property("name", 
"vadas").property("age", 27).as("vadas").addV("software").property("name", 
"lop").property("lang", "java").as("lop").addV("person").property("name", 
"josh").property("age", 32).as("josh").addV("software").pr [...]
+    
g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match:
 [function({g}) { return g.addV("person").property("name", 
"marko").property("age", 29).as("marko").addV("person").property("name", 
"vadas").property("age", 27).as("vadas").addV("software").property("name", 
"lop").property("lang", "java").as("lop").addV("person").property("name", 
"josh").property("age", 32).as("josh") [...]
+    
g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create:
 [function({g}) { return g.addV("person").property("name", 
"marko").property("age", 29).as("marko").addV("person").property("name", 
"vadas").property("age", 27).as("vadas").addV("software").property("name", 
"lop").property("lang", "java").as("lop").addV("person").property("name", 
"josh").property("age", 32).as("josh" [...]
     
g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_weight_nullX_allowed: 
[function({g, xx1, xx2}) { return g.addV("person").property("name", 
"marko").as("a").addV("person").property("name", 
"vadas").as("b").addE("knows").from_("a").to("b").property("weight", 1.0) }, 
function({g, xx1, xx2}) { return g.mergeE(xx1).option(Merge.onMatch, xx2) }, 
function({g, xx1, xx2}) { return g.V() }, function({g, xx1, xx2}) { return 
g.E().hasLabel("knows") }, function({g, xx1, xx2}) { return g.E( [...]
     g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_weight_nullX: 
[function({g, xx1, xx2}) { return g.addV("person").property("name", 
"marko").as("a").addV("person").property("name", 
"vadas").as("b").addE("knows").from_("a").to("b").property("weight", 1.0) }, 
function({g, xx1, xx2}) { return g.mergeE(xx1).option(Merge.onMatch, xx2) }, 
function({g, xx1, xx2}) { return g.V() }, function({g, xx1, xx2}) { return 
g.E().hasLabel("knows") }, function({g, xx1, xx2}) { return g.E().hasLab [...]
     g_mergeVXemptyX_optionXonMatch_nullX: [function({g}) { return 
g.addV("person").property("name", "marko").property("age", 29) }, function({g}) 
{ return g.mergeV(new Map([])).option(Merge.onMatch, null) }, function({g}) { 
return g.V().has("person", "name", "marko").has("age", 29) }], 
@@ -1174,8 +1184,8 @@ const gremlins = {
     g_mergeVXname_aliceX_optionXonCreate_age_setX81XX: [function({g}) { return 
g.mergeV(new Map([["name", "alice"], [T.label, 
"person"]])).option(Merge.onCreate, new Map([["age", 
CardinalityValue.set(81)]])) }, function({g}) { return g.V().has("person", 
"name", "alice").has("age", 81) }, function({g}) { return g.V().has("person", 
"name", "alice").has("age") }, function({g}) { return g.V().has("person", 
"name", "alice").properties("age") }], 
     g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX: 
[function({g}) { return g.mergeV(new Map([["name", "alice"], [T.label, 
"person"]])).option(Merge.onCreate, new Map([["age", 81]]), Cardinality.set) }, 
function({g}) { return g.V().has("person", "name", "alice").has("age", 81) }, 
function({g}) { return g.V().has("person", "name", "alice").has("age") }, 
function({g}) { return g.V().has("person", "name", "alice").properties("age") 
}], 
     g_mergeV_hidden_label_key_onMatch_matched_prohibited: [function({g, xx1}) 
{ return g.mergeV(new Map([])).option(Merge.onMatch, xx1) }], 
-    
g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_match:
 [function({g}) { return g.addV("person").property("name", 
"marko").property("age", 29) }, function({g}) { return g.inject(new 
Map([[T.label, "person"], ["name", "marko"]]), new Map([[T.label, "person"], 
["name", "marko"]]), new Map([["created", 
"N"]])).fold().mergeV(__.limit(Scope.local, 1)).option(Merge.onCreate, 
__.range(Scope.local, 1, 2)).option(Merge.onMatch, __.ta [...]
-    
g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_create:
 [function({g}) { return g.addV("person").property("name", 
"marko").property("age", 29) }, function({g}) { return g.inject(new 
Map([[T.label, "person"], ["name", "stephen"]]), new Map([[T.label, "person"], 
["name", "stephen"]]), new Map([["created", 
"N"]])).fold().mergeV(__.limit(Scope.local, 1)).option(Merge.onCreate, 
__.range(Scope.local, 1, 2)).option(Merge.onMatch,  [...]
+    
g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match:
 [function({g}) { return g.addV("person").property("name", 
"marko").property("age", 29) }, function({g}) { return g.inject(new 
Map([[T.label, "person"], ["name", "marko"]]), new Map([[T.label, "person"], 
["name", "marko"]]), new Map([["created", 
"N"]])).fold().mergeV(__.limit(Scope.local, 1).unfold()).option(Merge.onCreate, 
__.range(Scope.local, 1,  [...]
+    
g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create:
 [function({g}) { return g.addV("person").property("name", 
"marko").property("age", 29) }, function({g}) { return g.inject(new 
Map([[T.label, "person"], ["name", "stephen"]]), new Map([[T.label, "person"], 
["name", "stephen"]]), new Map([["created", 
"N"]])).fold().mergeV(__.limit(Scope.local, 1).unfold()).option(Merge.onCreate, 
__.range(Scope.local [...]
     g_V_age_min: [function({g}) { return g.V().values("age").min() }], 
     g_V_foo_min: [function({g}) { return g.V().values("foo").min() }], 
     g_V_name_min: [function({g}) { return g.V().values("name").min() }], 
diff --git a/gremlin-python/src/main/python/radish/gremlin.py 
b/gremlin-python/src/main/python/radish/gremlin.py
index b73c682cd8..afdb0fa6d1 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -381,6 +381,11 @@ world.gremlins = {
     'g_V_mapXin_hasIdX1XX_limitX2X_valuesXnameX': [(lambda g, 
vid1=None:g.V().map(__.in_().has_id(vid1)).limit(2).values('name'))], 
     'g_V_rangeX2_1X': [(lambda g:g.V().range_(2, 1))], 
     'g_V_rangeX3_2X': [(lambda g:g.V().range_(3, 2))], 
+    'g_injectXlistX1_2_3XX_rangeXlocal_1_2X': [(lambda g:g.inject([1, 2, 
3]).range_(Scope.local, 1, 2))], 
+    'g_injectXlistX1_2_3XX_limitXlocal_1X': [(lambda g:g.inject([1, 2, 
3]).limit(Scope.local, 1))], 
+    'g_injectXlistX1_2_3X_limitXlocal_1X_unfold': [(lambda g:g.inject([1, 2, 
3]).limit(Scope.local, 1).unfold())], 
+    'g_injectX1_2_3_4_5X_limitXlocal_1X': [(lambda g:g.inject([1, 2], [3, 4, 
5]).limit(Scope.local, 1))], 
+    'g_injectX1_2_3_4_5_6X_rangeXlocal_1_2X': [(lambda g:g.inject([1, 2, 3], 
[4, 5, 6]).range_(Scope.local, 1, 2))], 
     'g_V_sampleX1X_byXageX_byXT_idX': [(lambda 
g:g.V().sample(1).by('age').by(T.id_))], 
     'g_E_sampleX1X': [(lambda g:g.E().sample(1))], 
     'g_E_sampleX2X_byXweightX': [(lambda g:g.E().sample(2).by('weight'))], 
@@ -401,16 +406,21 @@ world.gremlins = {
     'g_V_valuesXnameX_order_tailX7X': [(lambda 
g:g.V().values('name').order().tail(7))], 
     'g_V_repeatXbothX_timesX3X_tailX7X': [(lambda 
g:g.V().repeat(__.both()).times(3).tail(7))], 
     'g_V_repeatXin_outX_timesX3X_tailX7X_count': [(lambda 
g:g.V().repeat(__.in_().out()).times(3).tail(7).count())], 
-    
'g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X':
 [(lambda 
g:g.V().as_('a').out().as_('a').out().as_('a').select('a').by(__.unfold().values('name').fold()).tail(Scope.local,
 1))], 
-    
'g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX':
 [(lambda 
g:g.V().as_('a').out().as_('a').out().as_('a').select('a').by(__.unfold().values('name').fold()).tail(Scope.local))],
 
+    
'g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold':
 [(lambda 
g:g.V().as_('a').out().as_('a').out().as_('a').select('a').by(__.unfold().values('name').fold()).tail(Scope.local,
 1).unfold())], 
+    
'g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold':
 [(lambda 
g:g.V().as_('a').out().as_('a').out().as_('a').select('a').by(__.unfold().values('name').fold()).tail(Scope.local).unfold())],
 
     'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2X': 
[(lambda g:g.V().as_('a').out().as_('b').out().as_('c').select('a', 'b', 
'c').by('name').tail(Scope.local, 2))], 
     'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2varX': 
[(lambda g, xx1=None:g.V().as_('a').out().as_('b').out().as_('c').select('a', 
'b', 'c').by('name').tail(Scope.local, xx1))], 
     'g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_1X': 
[(lambda g:g.V().as_('a').out().as_('b').out().as_('c').select('a', 'b', 
'c').by('name').tail(Scope.local, 1))], 
-    
'g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X':
 [(lambda g:g.V().as_('a').out().as_('a').out().as_('a').select(Pop.mixed, 
'a').by(__.unfold().values('name').fold()).tail(Scope.local, 1))], 
-    
'g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX':
 [(lambda g:g.V().as_('a').out().as_('a').out().as_('a').select(Pop.mixed, 
'a').by(__.unfold().values('name').fold()).tail(Scope.local))], 
+    
'g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold':
 [(lambda g:g.V().as_('a').out().as_('a').out().as_('a').select(Pop.mixed, 
'a').by(__.unfold().values('name').fold()).tail(Scope.local, 1).unfold())], 
+    
'g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold':
 [(lambda g:g.V().as_('a').out().as_('a').out().as_('a').select(Pop.mixed, 
'a').by(__.unfold().values('name').fold()).tail(Scope.local).unfold())], 
     
'g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X':
 [(lambda g:g.V().as_('a').out().as_('a').out().as_('a').select(Pop.mixed, 
'a').by(__.limit(Scope.local, 0)).tail(Scope.local, 1))], 
     
'g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_2X':
 [(lambda g:g.V().as_('a').out().as_('a').out().as_('a').select(Pop.mixed, 
'a').by(__.unfold().values('name').fold()).tail(Scope.local, 2))], 
     'g_VX1X_valuesXageX_tailXlocal_5X': [(lambda g, 
vid1=None:g.V(vid1).values('age').tail(Scope.local, 50))], 
+    'g_injectXlistX1_2_3XX_tailXlocal_1X': [(lambda g:g.inject([1, 2, 
3]).tail(Scope.local, 1))], 
+    'g_injectXa1_b2_c3X_tailXlocal_1X': [(lambda g:g.inject({ 'a': 1, 'b': 2, 
'c': 3 }).tail(Scope.local, 1))], 
+    'g_injectX1_2_3X_tailXlocal_1X_unfold': [(lambda g:g.inject([1, 2, 
3]).tail(Scope.local, 1).unfold())], 
+    'g_injectX1_2_3_4_5_6X_tailXlocal_1X': [(lambda g:g.inject([1, 2, 3], [4, 
5, 6]).tail(Scope.local, 1))], 
+    'g_injectX1_2_3_4_5X_tailXlocal_2X': [(lambda g:g.inject([1, 2, 3, 4, 
5]).tail(Scope.local, 2))], 
     'g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXa_eqXbXX': 
[(lambda 
g:g.V().has('age').as_('a').out().in_().has('age').as_('b').select('a', 
'b').where('a', P.eq('b')))], 
     'g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXa_neqXbXX': 
[(lambda 
g:g.V().has('age').as_('a').out().in_().has('age').as_('b').select('a', 
'b').where('a', P.neq('b')))], 
     
'g_V_hasXageX_asXaX_out_in_hasXageX_asXbX_selectXa_bX_whereXb_hasXname_markoXX':
 [(lambda 
g:g.V().has('age').as_('a').out().in_().has('age').as_('b').select('a', 
'b').where(__.as_('b').has('name', 'marko')))], 
@@ -1083,8 +1093,8 @@ world.gremlins = {
     
'g_V_asXvX_mergeEXxx1X_optionXMerge_onMatch_xx2X_optionXMerge_outV_selectXvXX_optionXMerge_inV_selectXvXX':
 [(lambda g, xx1=None,xx2=None:g.add_v('person').property('name', 
'marko').property('age', 29)), (lambda g, 
xx1=None,xx2=None:g.V().as_('v').merge_e(xx1).option(Merge.on_match, 
xx2).option(Merge.out_v, __.select('v')).option(Merge.in_v, __.select('v')))], 
     
'g_V_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_sideEffectXpropertyXweight_0XX_constantXemptyXX':
 [(lambda g, xx1=None:g.add_v('person').property('name', 
'marko').as_('a').add_v('person').property('name', 
'vadas').as_('b').add_e('knows').property('weight', 1).from_('a').to('b')), 
(lambda g, xx1=None:g.V().merge_e(xx1).option(Merge.on_match, 
__.side_effect(__.property('weight', 0)).constant({  })))], 
     
'g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_sideEffectXpropertyXweight_0XX_constantXemptyXX':
 [(lambda g, xx1=None:g.add_v('person').property('name', 
'marko').as_('a').add_v('person').property('name', 
'vadas').as_('b').add_e('knows').property('weight', 1).from_('a').to('b')), 
(lambda g, xx1=None:g.merge_e(xx1).option(Merge.on_match, 
__.side_effect(__.property('weight', 0)).constant({  }))), (lambda g, 
xx1=None:g.V()), (lambda g, xx1=None:g.E().has_label('knows').has('wei [...]
-    
'g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_match':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 
29).as_('marko').add_v('person').property('name', 'vadas').property('age', 
27).as_('vadas').add_v('software').property('name', 'lop').property('lang', 
'java').as_('lop').add_v('person').property('name', 'josh').property('age', 
32).as_('josh').add_v('software').prope [...]
-    
'g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_create':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 
29).as_('marko').add_v('person').property('name', 'vadas').property('age', 
27).as_('vadas').add_v('software').property('name', 'lop').property('lang', 
'java').as_('lop').add_v('person').property('name', 'josh').property('age', 
32).as_('josh').add_v('software').prop [...]
+    
'g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 
29).as_('marko').add_v('person').property('name', 'vadas').property('age', 
27).as_('vadas').add_v('software').property('name', 'lop').property('lang', 
'java').as_('lop').add_v('person').property('name', 'josh').property('age', 
32).as_('josh').ad [...]
+    
'g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 
29).as_('marko').add_v('person').property('name', 'vadas').property('age', 
27).as_('vadas').add_v('software').property('name', 'lop').property('lang', 
'java').as_('lop').add_v('person').property('name', 'josh').property('age', 
32).as_('josh').a [...]
     
'g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_weight_nullX_allowed': 
[(lambda g, xx1=None,xx2=None:g.add_v('person').property('name', 
'marko').as_('a').add_v('person').property('name', 
'vadas').as_('b').add_e('knows').from_('a').to('b').property('weight', 1.0)), 
(lambda g, xx1=None,xx2=None:g.merge_e(xx1).option(Merge.on_match, xx2)), 
(lambda g, xx1=None,xx2=None:g.V()), (lambda g, 
xx1=None,xx2=None:g.E().has_label('knows')), (lambda g, 
xx1=None,xx2=None:g.E().has_label('k [...]
     'g_mergeEXlabel_knows_out_marko_in_vadasX_optionXonMatch_weight_nullX': 
[(lambda g, xx1=None,xx2=None:g.add_v('person').property('name', 
'marko').as_('a').add_v('person').property('name', 
'vadas').as_('b').add_e('knows').from_('a').to('b').property('weight', 1.0)), 
(lambda g, xx1=None,xx2=None:g.merge_e(xx1).option(Merge.on_match, xx2)), 
(lambda g, xx1=None,xx2=None:g.V()), (lambda g, 
xx1=None,xx2=None:g.E().has_label('knows')), (lambda g, 
xx1=None,xx2=None:g.E().has_label('knows').h [...]
     'g_mergeVXemptyX_optionXonMatch_nullX': [(lambda 
g:g.add_v('person').property('name', 'marko').property('age', 29)), (lambda 
g:g.merge_v({  }).option(Merge.on_match, None)), (lambda g:g.V().has('person', 
'name', 'marko').has('age', 29))], 
@@ -1147,8 +1157,8 @@ world.gremlins = {
     'g_mergeVXname_aliceX_optionXonCreate_age_setX81XX': [(lambda 
g:g.merge_v({ 'name': 'alice', T.label: 'person' }).option(Merge.on_create, { 
'age': CardinalityValue.set_(81) })), (lambda g:g.V().has('person', 'name', 
'alice').has('age', 81)), (lambda g:g.V().has('person', 'name', 
'alice').has('age')), (lambda g:g.V().has('person', 'name', 
'alice').properties('age'))], 
     'g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX': 
[(lambda g:g.merge_v({ 'name': 'alice', T.label: 'person' 
}).option(Merge.on_create, { 'age': 81 }, Cardinality.set_)), (lambda 
g:g.V().has('person', 'name', 'alice').has('age', 81)), (lambda 
g:g.V().has('person', 'name', 'alice').has('age')), (lambda 
g:g.V().has('person', 'name', 'alice').properties('age'))], 
     'g_mergeV_hidden_label_key_onMatch_matched_prohibited': [(lambda g, 
xx1=None:g.merge_v({  }).option(Merge.on_match, xx1))], 
-    
'g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_match':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 29)), 
(lambda g:g.inject({ T.label: 'person', 'name': 'marko' }, { T.label: 'person', 
'name': 'marko' }, { 'created': 'N' }).fold().merge_v(__.limit(Scope.local, 
1)).option(Merge.on_create, __.range_(Scope.local, 1, 
2)).option(Merge.on_match, __.tail(Scope.local))), (lambda 
g:g.V().has('person', 'n [...]
-    
'g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_create':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 29)), 
(lambda g:g.inject({ T.label: 'person', 'name': 'stephen' }, { T.label: 
'person', 'name': 'stephen' }, { 'created': 'N' 
}).fold().merge_v(__.limit(Scope.local, 1)).option(Merge.on_create, 
__.range_(Scope.local, 1, 2)).option(Merge.on_match, __.tail(Scope.local))), 
(lambda g:g.V().has('person [...]
+    
'g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 29)), 
(lambda g:g.inject({ T.label: 'person', 'name': 'marko' }, { T.label: 'person', 
'name': 'marko' }, { 'created': 'N' }).fold().merge_v(__.limit(Scope.local, 
1).unfold()).option(Merge.on_create, __.range_(Scope.local, 1, 
2).unfold()).option(Merge.on_match, __.tail(Scope.lo [...]
+    
'g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create':
 [(lambda g:g.add_v('person').property('name', 'marko').property('age', 29)), 
(lambda g:g.inject({ T.label: 'person', 'name': 'stephen' }, { T.label: 
'person', 'name': 'stephen' }, { 'created': 'N' 
}).fold().merge_v(__.limit(Scope.local, 1).unfold()).option(Merge.on_create, 
__.range_(Scope.local, 1, 2).unfold()).option(Merge.on_match, __.tail(Sco [...]
     'g_V_age_min': [(lambda g:g.V().values('age').min_())], 
     'g_V_foo_min': [(lambda g:g.V().values('foo').min_())], 
     'g_V_name_min': [(lambda g:g.V().values('name').min_())], 
diff --git 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeTest.java
 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeTest.java
index 2f30ae2911..25cb0edab5 100644
--- 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeTest.java
+++ 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeTest.java
@@ -66,13 +66,13 @@ public abstract class RangeTest extends 
AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, List<String>> 
get_g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_2X();
 
-    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_1X();
+    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_1X_unfold();
 
     public abstract Traversal<Vertex, List<String>> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_3X();
 
-    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_2X();
+    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_2X_unfold();
 
-    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_4_5X();
+    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_4_5X_unfold();
 
     public abstract Traversal<Vertex, Map<String, String>> 
get_g_V_asXaX_in_asXbX_in_asXcX_selectXa_b_cX_byXnameX_limitXlocal_2X();
 
@@ -206,8 +206,8 @@ public abstract class RangeTest extends 
AbstractGremlinProcessTest {
      */
     @Test
     @LoadGraphWith(MODERN)
-    public void 
g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_1X()
 {
-        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_1X();
+    public void 
g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_1X_unfold()
 {
+        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_1X_unfold();
         printTraversalForm(traversal);
         final Set<String> expected = new HashSet<>(Arrays.asList("ripple", 
"lop"));
         final Set<List<String>> actual = new HashSet(traversal.toList());
@@ -235,8 +235,8 @@ public abstract class RangeTest extends 
AbstractGremlinProcessTest {
      */
     @Test
     @LoadGraphWith(MODERN)
-    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_2X()
 {
-        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_2X();
+    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_2X_unfold()
 {
+        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_2X_unfold();
         printTraversalForm(traversal);
         int counter = 0;
         while (traversal.hasNext()) {
@@ -252,8 +252,8 @@ public abstract class RangeTest extends 
AbstractGremlinProcessTest {
      */
     @Test
     @LoadGraphWith(MODERN)
-    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_4_5X()
 {
-        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_4_5X();
+    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_4_5X_unfold()
 {
+        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_4_5X_unfold();
         printTraversalForm(traversal);
         assertEquals(Arrays.asList(), traversal.toList());
     }
@@ -402,8 +402,8 @@ public abstract class RangeTest extends 
AbstractGremlinProcessTest {
         }
 
         @Override
-        public Traversal<Vertex, String> 
get_g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_1X()
 {
-            return 
g.V().as("a").in().as("a").in().as("a").<List<String>>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).limit(local, 1);
+        public Traversal<Vertex, String> 
get_g_V_asXaX_in_asXaX_in_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_limitXlocal_1X_unfold()
 {
+            return 
g.V().as("a").in().as("a").in().as("a").<List<String>>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).limit(local, 1).unfold();
         }
 
         @Override
@@ -412,13 +412,13 @@ public abstract class RangeTest extends 
AbstractGremlinProcessTest {
         }
 
         @Override
-        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_2X()
 {
-            return 
g.V().as("a").out().as("a").out().as("a").<List<String>>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).range(local, 1, 2);
+        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_1_2X_unfold()
 {
+            return 
g.V().as("a").out().as("a").out().as("a").<List<String>>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).range(local, 1, 2).unfold();
         }
 
         @Override
-        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_4_5X()
 {
-            return 
g.V().as("a").out().as("a").out().as("a").<List<String>>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).range(local, 4, 5);
+        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_rangeXlocal_4_5X_unfold()
 {
+            return 
g.V().as("a").out().as("a").out().as("a").<List<String>>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).range(local, 4, 5).unfold();
         }
 
         @Override
diff --git 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailTest.java
 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailTest.java
index 71ed67d2b5..4dffe2734b 100644
--- 
a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailTest.java
+++ 
b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailTest.java
@@ -66,11 +66,11 @@ public abstract class TailTest extends 
AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, List<String>> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_2X();
 
-    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X();
+    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold();
 
-    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX();
+    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold();
 
-    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X();
+    public abstract Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X_unfold();
 
     public abstract Traversal<Vertex, Map<String, String>> 
get_g_V_asXaX_out_asXbX_out_asXcX_selectXa_b_cX_byXnameX_tailXlocal_2X();
 
@@ -170,8 +170,8 @@ public abstract class TailTest extends 
AbstractGremlinProcessTest {
      */
     @Test
     @LoadGraphWith(MODERN)
-    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X()
 {
-        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X();
+    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold()
 {
+        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold();
         printTraversalForm(traversal);
         final Set<String> expected = new HashSet(Arrays.asList("ripple", 
"lop"));
         final Set<String> actual = new HashSet(traversal.toList());
@@ -183,8 +183,8 @@ public abstract class TailTest extends 
AbstractGremlinProcessTest {
      */
     @Test
     @LoadGraphWith(MODERN)
-    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX()
 {
-        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX();
+    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold()
 {
+        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold();
         printTraversalForm(traversal);
         final Set<String> expected = new HashSet(Arrays.asList("ripple", 
"lop"));
         final Set<String> actual = new HashSet(traversal.toList());
@@ -196,8 +196,8 @@ public abstract class TailTest extends 
AbstractGremlinProcessTest {
      */
     @Test
     @LoadGraphWith(MODERN)
-    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X()
 {
-        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X();
+    public void 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X_unfold()
 {
+        final Traversal<Vertex, String> traversal = 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X_unfold();
         printTraversalForm(traversal);
         final Set<String> expected = new HashSet();
         final Set<String> actual = new HashSet(traversal.toList());
@@ -283,18 +283,18 @@ public abstract class TailTest extends 
AbstractGremlinProcessTest {
         }
 
         @Override
-        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X()
 {
-            return 
g.V().as("a").out().as("a").out().as("a").<String>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).tail(local, 1);
+        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold()
 {
+            return 
g.V().as("a").out().as("a").out().as("a").<String>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).tail(local, 1).unfold();
         }
 
         @Override
-        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX()
 {
-            return 
g.V().as("a").out().as("a").out().as("a").<String>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).tail(local);
+        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold()
 {
+            return 
g.V().as("a").out().as("a").out().as("a").<String>select(Pop.mixed, 
"a").by(unfold().values("name").fold()).tail(local).unfold();
         }
 
         @Override
-        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X()
 {
-            return 
g.V().as("a").out().as("a").out().as("a").<String>select(Pop.mixed, 
"a").by(limit(local, 0)).tail(local, 1);
+        public Traversal<Vertex, String> 
get_g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXlimitXlocal_0XX_tailXlocal_1X_unfold()
 {
+            return 
g.V().as("a").out().as("a").out().as("a").<String>select(Pop.mixed, 
"a").by(limit(local, 0)).tail(local, 1).unfold();
         }
 
         @Override
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
index e54f473fbe..0bbc215bc0 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
@@ -266,7 +266,9 @@ Feature: Step - range()
       g.V().fold().range(Scope.local, 6, 7)
       """
     When iterated to list
-    Then the result should be empty
+    Then the result should be unordered
+      | result |
+      | l[] |
 
   Scenario: g_V_outE_valuesXweightX_fold_orderXlocalX_skipXlocal_2X
     Given the modern graph
@@ -347,3 +349,65 @@ Feature: Step - range()
       """
     When iterated next
     Then the traversal will raise an error with message containing text of 
"Not a legal range: [3, 2]"
+
+  # Test consistent collection output for range(local) - single element should 
return collection
+  Scenario: g_injectXlistX1_2_3XX_rangeXlocal_1_2X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2, 3]).range(Scope.local, 1, 2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[2].i] |
+
+  # Test consistent collection output for limit(local) - single element should 
return collection
+  Scenario: g_injectXlistX1_2_3XX_limitXlocal_1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2, 3]).limit(Scope.local, 1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[1].i] |
+
+  # Test unfold() can be used to extract single elements from collections
+  Scenario: g_injectXlistX1_2_3X_limitXlocal_1X_unfold
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2, 3]).limit(Scope.local, 1).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+
+  # Test multiple collections with consistent output
+  Scenario: g_injectX1_2_3_4_5X_limitXlocal_1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2], [3, 4, 5]).limit(Scope.local, 1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[1].i] |
+      | l[d[3].i] |
+
+  # Test range(local) with multiple collections
+  Scenario: g_injectX1_2_3_4_5_6X_rangeXlocal_1_2X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2, 3], [4, 5, 6]).range(Scope.local, 1, 2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[2].i] |
+      | l[d[5].i] |
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Tail.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Tail.feature
index 1fb3d215bd..c91aa9bdc4 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Tail.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Tail.feature
@@ -103,11 +103,11 @@ Feature: Step - tail()
       | d[7].l |
 
   @GraphComputerVerificationReferenceOnly
-  Scenario: 
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X
+  Scenario: 
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold
     Given the modern graph
     And the traversal of
       """
-      
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local,
 1)
+      
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local,
 1).unfold()
       """
     When iterated to list
     Then the result should be unordered
@@ -116,11 +116,11 @@ Feature: Step - tail()
       | lop |
 
   @GraphComputerVerificationReferenceOnly
-  Scenario: 
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX
+  Scenario: 
g_V_asXaX_out_asXaX_out_asXaX_selectXaX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold
     Given the modern graph
     And the traversal of
       """
-      
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local)
+      
g.V().as("a").out().as("a").out().as("a").select("a").by(__.unfold().values("name").fold()).tail(Scope.local).unfold()
       """
     When iterated to list
     Then the result should be unordered
@@ -166,11 +166,11 @@ Feature: Step - tail()
       | m[{"c":"lop"}] |
 
   @GraphComputerVerificationReferenceOnly
-  Scenario: 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X
+  Scenario: 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocal_1X_unfold
     Given the modern graph
     And the traversal of
       """
-      g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local, 1)
+      g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local, 1).unfold()
       """
     When iterated to list
     Then the result should be unordered
@@ -179,11 +179,11 @@ Feature: Step - tail()
       | lop |
 
   @GraphComputerVerificationReferenceOnly
-  Scenario: 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX
+  Scenario: 
g_V_asXaX_out_asXaX_out_asXaX_selectXmixed_aX_byXunfold_valuesXnameX_foldX_tailXlocalX_unfold
     Given the modern graph
     And the traversal of
       """
-      g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local)
+      g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.unfold().values("name").fold()).tail(Scope.local).unfold()
       """
     When iterated to list
     Then the result should be unordered
@@ -198,7 +198,7 @@ Feature: Step - tail()
       """
       g.V().as("a").out().as("a").out().as("a").select(Pop.mixed, 
"a").by(__.limit(Scope.local, 0)).tail(Scope.local, 1)
       """
-    When iterated to list
+    When iterated next
     Then the result should be empty
 
   @GraphComputerVerificationReferenceOnly
@@ -224,4 +224,65 @@ Feature: Step - tail()
     When iterated to list
     Then the result should be unordered
       | result |
-      | d[29].i |
\ No newline at end of file
+      | d[29].i |
+
+  # Test consistent collection output for tail(local) - single element should 
return collection
+  Scenario: g_injectXlistX1_2_3XX_tailXlocal_1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2, 3]).tail(Scope.local, 1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[3].i] |
+
+  # Test that Map local tail 1 - should still return single entry
+  Scenario: g_injectXa1_b2_c3X_tailXlocal_1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(["a": 1, "b": 2, "c": 3]).tail(Scope.local, 1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"c": 3}] |
+
+  # Test unfold() can be used to extract single elements from collections for 
tail
+  Scenario: g_injectX1_2_3X_tailXlocal_1X_unfold
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2, 3]).tail(Scope.local, 1).unfold()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[3].i |
+
+  # Test tail(local) with multiple collections
+  Scenario: g_injectX1_2_3_4_5_6X_tailXlocal_1X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2, 3], [4, 5, 6]).tail(Scope.local, 1)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[3].i] |
+      | l[d[6].i] |
+
+  # Test tail(local) with multiple elements from collections
+  Scenario: g_injectX1_2_3_4_5X_tailXlocal_2X
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject([1, 2, 3, 4, 5]).tail(Scope.local, 2)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | l[d[4].i,d[5].i] |
\ No newline at end of file
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeEdge.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeEdge.feature
index c8af843930..6d8fe7c488 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeEdge.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeEdge.feature
@@ -864,7 +864,7 @@ Feature: Step - mergeE()
     And the graph should return 1 for count of 
"g.E().hasLabel(\"knows\").has(\"weight\",0)"
     And the graph should return 0 for count of "g.V().has(\"weight\")"
 
-    Scenario: 
g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_match
+    Scenario: 
g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match
     Given the empty graph
     And the graph initializer of
       """
@@ -886,9 +886,9 @@ Feature: Step - mergeE()
       """
       g.union(select("m"), select("m"), constant([created: "N"])).
         fold().
-        mergeE(__.limit(Scope.local,1)).
-          option(Merge.onCreate, __.range(Scope.local, 1, 2)).
-          option(Merge.onMatch, __.tail(Scope.local))
+        mergeE(__.limit(Scope.local,1).unfold()).
+          option(Merge.onCreate, __.range(Scope.local, 1, 2).unfold()).
+          option(Merge.onMatch, __.tail(Scope.local).unfold())
       """
     When iterated to list
     Then the result should have a count of 1
@@ -897,7 +897,7 @@ Feature: Step - mergeE()
     And the graph should return 1 for count of "g.E().has(\"created\",\"N\")"
     And the graph should return 1 for count of 
"g.V().has(\"person\",\"name\",\"marko\").outE(\"knows\").has(\"created\",\"N\").inV().has(\"person\",\"name\",\"vadas\")"
 
-   Scenario: 
g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2XX_optionXonMatch_tailXlocalXX_to_create
+   Scenario: 
g_unionXselectXmX_selectXmX_constantXcreated_NXX_fold_mergeEXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create
     Given the empty graph
     And the graph initializer of
       """
@@ -919,9 +919,9 @@ Feature: Step - mergeE()
       """
       g.union(select("m"), select("m"), constant([created:"N"])).
         fold().
-        mergeE(__.limit(Scope.local,1)).
-          option(Merge.onCreate, __.range(Scope.local, 1, 2)).
-          option(Merge.onMatch, __.tail(Scope.local))
+        mergeE(__.limit(Scope.local,1).unfold()).
+          option(Merge.onCreate, __.range(Scope.local, 1, 2).unfold()).
+          option(Merge.onMatch, __.tail(Scope.local).unfold())
       """
     When iterated to list
     Then the result should have a count of 1
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeVertex.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeVertex.feature
index 5c5b74a181..713f711cb0 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeVertex.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeVertex.feature
@@ -925,7 +925,7 @@ Feature: Step - mergeV()
     When iterated to list
     Then the traversal will raise an error with message containing text of 
"Property key can not be a hidden key: ~label"
 
-  Scenario: 
g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_match
+  Scenario: 
g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_match
     Given the empty graph
     And the graph initializer of
       """
@@ -935,16 +935,16 @@ Feature: Step - mergeV()
       """
       g.inject([T.label:"person", name:"marko"], [T.label:"person", 
name:"marko"], [created:"N"]).
         fold().
-        mergeV(__.limit(Scope.local,1)).
-          option(Merge.onCreate, __.range(Scope.local, 1, 2)).
-          option(Merge.onMatch, __.tail(Scope.local))
+        mergeV(__.limit(Scope.local,1).unfold()).
+          option(Merge.onCreate, __.range(Scope.local, 1, 2).unfold()).
+          option(Merge.onMatch, __.tail(Scope.local).unfold())
       """
     When iterated to list
     Then the result should have a count of 1
     And the graph should return 1 for count of 
"g.V().has(\"person\",\"name\",\"marko\").has(\"created\",\"N\")"
     And the graph should return 1 for count of "g.V()"
 
-  Scenario: 
g_injectXlist1_list2X_mergeVXlimitXlocal_1XX_optionXonCreate_rangeXlocal_1_2X_optionXonMatch_tailXlocalXX_to_create
+  Scenario: 
g_injectXlist1_list2X_mergeVXlimitXlocal_1X_unfoldX_optionXonCreate_rangeXlocal_1_2X_unfoldX_optionXonMatch_tailXlocalX_unfoldX_to_create
     Given the empty graph
     And the graph initializer of
       """
@@ -954,9 +954,9 @@ Feature: Step - mergeV()
       """
       g.inject([T.label:"person", name:"stephen"], [T.label:"person", 
name:"stephen"], [created:"N"]).
         fold().
-        mergeV(__.limit(Scope.local,1)).
-          option(Merge.onCreate, __.range(Scope.local, 1, 2)).
-          option(Merge.onMatch, __.tail(Scope.local))
+        mergeV(__.limit(Scope.local,1).unfold()).
+          option(Merge.onCreate, __.range(Scope.local, 1, 2).unfold()).
+          option(Merge.onMatch, __.tail(Scope.local).unfold())
       """
     When iterated to list
     Then the result should have a count of 1

Reply via email to