You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2021/09/02 18:44:25 UTC

[tinkerpop] 01/01: TINKERPOP-2605 Fixed issues with null and inject()

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

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

commit 8503708f229091c21044e9e3d2a7bd5cbd82c1a1
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Mon Aug 30 15:10:11 2021 -0400

    TINKERPOP-2605 Fixed issues with null and inject()
---
 CHANGELOG.asciidoc                                 |  3 +
 .../traversal/dsl/graph/GraphTraversal.java        |  6 +-
 .../traversal/dsl/graph/GraphTraversalSource.java  |  6 +-
 .../traversal/translator/DotNetTranslator.java     |  9 +-
 .../traversal/translator/GroovyTranslator.java     | 27 ++++--
 .../gremlin/structure/util/StringFactory.java      |  6 +-
 .../gremlin/util/iterator/ArrayIterator.java       |  5 +-
 .../traversal/translator/DotNetTranslatorTest.java | 14 +++-
 .../translator/JavascriptTranslatorTest.java       |  5 ++
 .../gremlin/util/iterator/ArrayIteratorTest.java   | 32 +++++++
 gremlin-dotnet/build/generate.groovy               | 98 ++++++++++++----------
 .../Process/Traversal/GraphTraversal.cs            | 15 +++-
 .../Process/Traversal/GraphTraversalSource.cs      | 16 +++-
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs |  6 ++
 gremlin-javascript/build/generate.groovy           | 52 +++++++-----
 .../gremlin-javascript/test/cucumber/gremlin.js    |  6 ++
 gremlin-python/build/generate.groovy               | 55 +++++++-----
 gremlin-python/src/main/python/radish/gremlin.py   |  6 ++
 gremlin-test/features/sideEffect/Inject.feature    | 75 ++++++++++++++++-
 .../traversal/step/sideEffect/InjectTest.java      | 88 +++++++++++++++++++
 20 files changed, 419 insertions(+), 111 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 6557c8b..0155cfc 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -33,6 +33,9 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Improved handling of `null` when passed to `P` predicates.
 * Handled `null` for mathematical reducing operations of `sum()`, `mean()`, `max()` and `min()`.
 * Allowed `null` values in `Memory` for `GraphComputer`.
+* Fixed problems with `inject(null)` variations where `null` was the only value being submitted.
+* Fixed problem with `GroovyTranslator` and `inject(null,null)` which could be interpreted as the Groovy JDK extension `inject(Object,Closure).
+* Fixed error where certain variants of `inject()` with `null` might not properly construct a traversal in .NET.
 * Refined `DotNetTranslator` to be more explicit with `null` arguments to ensure that the right overloads are called.
 * Created `GremlinParser` to construct `Traversal` objects from `gremlin-language`.
 
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index 63a394e..f52c30f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -1284,8 +1284,10 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
      * @since 3.0.0-incubating
      */
     public default GraphTraversal<S, E> inject(final E... injections) {
-        this.asAdmin().getBytecode().addStep(Symbols.inject, injections);
-        return this.asAdmin().addStep(new InjectStep<>(this.asAdmin(), injections));
+        // a single null is [null]
+        final E[] s = null == injections ? (E[]) new Object[] { null } : injections;
+        this.asAdmin().getBytecode().addStep(Symbols.inject, s);
+        return this.asAdmin().addStep(new InjectStep<>(this.asAdmin(), s));
     }
 
     /**
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
index 64fff5d..b7471b1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
@@ -352,10 +352,12 @@ public class GraphTraversalSource implements TraversalSource {
      * Spawns a {@link GraphTraversal} starting it with arbitrary values.
      */
     public <S> GraphTraversal<S, S> inject(S... starts) {
+        // a single null is [null]
+        final S[] s = null == starts ? (S[]) new Object[] { null } : starts;
         final GraphTraversalSource clone = this.clone();
-        clone.bytecode.addStep(GraphTraversal.Symbols.inject, starts);
+        clone.bytecode.addStep(GraphTraversal.Symbols.inject, s);
         final GraphTraversal.Admin<S, S> traversal = new DefaultGraphTraversal<>(clone);
-        return traversal.addStep(new InjectStep<S>(traversal, starts));
+        return traversal.addStep(new InjectStep<S>(traversal, s));
     }
 
     /**
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslator.java
index d4dcc35..d6ac2eb 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslator.java
@@ -304,18 +304,22 @@ public final class DotNetTranslator implements Translator.ScriptTranslator {
         @Override
         protected Script produceScript(final String traversalSource, final Bytecode o) {
             script.append(traversalSource);
+            int instructionPosition = 0;
             for (final Bytecode.Instruction instruction : o.getInstructions()) {
                 final String methodName = instruction.getOperator();
                 // perhaps too many if/then conditions for specifying generics. doesnt' seem like there is a clear
                 // way to refactor this more nicely though.
+                //
+                // inject() only has types when called with it when its used as a start step
                 if (0 == instruction.getArguments().length) {
-                    if (methodName.equals(GraphTraversal.Symbols.fold) && o.getSourceInstructions().size() + o.getStepInstructions().size() > 1)
+                    if (methodName.equals(GraphTraversal.Symbols.fold) && o.getSourceInstructions().size() + o.getStepInstructions().size() > 1 ||
+                            (methodName.equals(GraphTraversal.Symbols.inject) && instructionPosition > 0))
                         script.append(".").append(resolveSymbol(methodName).replace("<object>", "")).append("()");
                     else
                         script.append(".").append(resolveSymbol(methodName)).append("()");
                 } else {
                     if (methodsWithArgsNotNeedingGeneric.contains(methodName) ||
-                            (methodName.equals(GraphTraversal.Symbols.inject) && Arrays.stream(instruction.getArguments()).noneMatch(Objects::isNull)))
+                            (methodName.equals(GraphTraversal.Symbols.inject) && (Arrays.stream(instruction.getArguments()).noneMatch(Objects::isNull) || instructionPosition > 0)))
                         script.append(".").append(resolveSymbol(methodName).replace("<object>", "").replace("<object,object>", "")).append("(");
                     else
                         script.append(".").append(resolveSymbol(methodName)).append("(");
@@ -359,6 +363,7 @@ public final class DotNetTranslator implements Translator.ScriptTranslator {
                     }
                     script.setCharAtEnd(')');
                 }
+                instructionPosition++;
             }
             return script;
         }
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
index f11378b..c0a9f08 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
@@ -28,6 +28,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
 import org.apache.tinkerpop.gremlin.process.traversal.Script;
 import org.apache.tinkerpop.gremlin.process.traversal.TextP;
 import org.apache.tinkerpop.gremlin.process.traversal.Translator;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy;
 import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
@@ -311,21 +314,31 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
         }
 
         @Override
-        protected Script produceScript(final String traversalSource, final Bytecode o) {
+        protected Script produceScript(final String traversalSource, final Bytecode bytecode) {
             script.append(traversalSource);
-            for (final Bytecode.Instruction instruction : o.getInstructions()) {
+            for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
                 final String methodName = instruction.getOperator();
                 if (0 == instruction.getArguments().length) {
                     script.append(".").append(methodName).append("()");
                 } else {
                     script.append(".").append(methodName).append("(");
 
-                    final Iterator<Object> itty = Arrays.stream(instruction.getArguments()).iterator();
-                    while(itty.hasNext()) {
-                        convertToScript(itty.next());
-                        if (itty.hasNext()) script.append(",");
+                    // special case inject(null, null) or else groovy might guess the JDK collection extension form
+                    if (methodName.equals(GraphTraversal.Symbols.inject)) {
+                        final Iterator<Object> itty = Arrays.stream(instruction.getArguments()).iterator();
+                        while (itty.hasNext()) {
+                            final Object o = itty.next();
+                            if (null == o) script.append("(Object)");
+                            convertToScript(o);
+                            if (itty.hasNext()) script.append(",");
+                        }
+                    } else {
+                        final Iterator<Object> itty = Arrays.stream(instruction.getArguments()).iterator();
+                        while (itty.hasNext()) {
+                            convertToScript(itty.next());
+                            if (itty.hasNext()) script.append(",");
+                        }
                     }
-
                     script.append(")");
                 }
             }
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
index dfab163..49206cf 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
@@ -218,7 +218,6 @@ public final class StringFactory {
     public static String stepString(final Step<?, ?> step, final Object... arguments) {
         final StringBuilder builder = new StringBuilder(step.getClass().getSimpleName());
         final List<String> strings = Stream.of(arguments)
-                .filter(o -> null != o)
                 .filter(o -> {
                     if (o instanceof TraversalRing)
                         return !((TraversalRing) o).isEmpty();
@@ -227,10 +226,10 @@ public final class StringFactory {
                     else if (o instanceof Map)
                         return !((Map) o).isEmpty();
                     else
-                        return !o.toString().isEmpty();
+                        return !Objects.toString(o).isEmpty();
                 })
                 .map(o -> {
-                    final String string = o.toString();
+                    final String string = Objects.toString(o);
                     return hasLambda(string) ? "lambda" : string;
                 }).collect(Collectors.toList());
         if (!strings.isEmpty()) {
@@ -239,7 +238,6 @@ public final class StringFactory {
             builder.append(')');
         }
         if (!step.getLabels().isEmpty()) builder.append('@').append(step.getLabels());
-        //builder.append("^").append(step.getId());
         return builder.toString();
     }
 
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/iterator/ArrayIterator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/iterator/ArrayIterator.java
index 7d5f959..3d87f34 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/iterator/ArrayIterator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/iterator/ArrayIterator.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementExce
 import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Iterator;
+import java.util.Objects;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -33,7 +34,7 @@ public final class ArrayIterator<T> implements Iterator<T>, Serializable {
     private int current = 0;
 
     public ArrayIterator(final T[] array) {
-        this.array = array;
+        this.array = Objects.requireNonNull(array);
     }
 
     @Override
@@ -53,6 +54,6 @@ public final class ArrayIterator<T> implements Iterator<T>, Serializable {
 
     @Override
     public String toString() {
-        return Arrays.asList(array).toString();
+        return array.length == 1 && null == array[0] ? "[null]" : Arrays.asList(array).toString();
     }
 }
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java
index 3e5654c..1b0fd71 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java
@@ -88,8 +88,20 @@ public class DotNetTranslatorTest {
 
     @Test
     public void shouldTranslateInject() {
-        final String script = translator.translate(g.inject(10,20,null,20,10,10).asAdmin().getBytecode()).getScript();
+        String script = translator.translate(g.inject(10,20,null,20,10,10).asAdmin().getBytecode()).getScript();
         assertEquals("g.Inject<object>(10,20,null,20,10,10)", script);
+        script = translator.translate(g.inject().asAdmin().getBytecode()).getScript();
+        assertEquals("g.Inject<object>()", script);
+        script = translator.translate(g.inject((Object) null).asAdmin().getBytecode()).getScript();
+        assertEquals("g.Inject<object>(null)", script);
+        script = translator.translate(g.inject(null, null).asAdmin().getBytecode()).getScript();
+        assertEquals("g.Inject<object>(null,null)", script);
+        script = translator.translate(g.V().values("age").inject().asAdmin().getBytecode()).getScript();
+        assertEquals("g.V().Values<object>(\"age\").Inject()", script);
+        script = translator.translate(g.V().values("age").inject(null).asAdmin().getBytecode()).getScript();
+        assertEquals("g.V().Values<object>(\"age\").Inject(null)", script);
+        script = translator.translate(g.V().values("age").inject(null, null).asAdmin().getBytecode()).getScript();
+        assertEquals("g.V().Values<object>(\"age\").Inject(null,null)", script);
     }
 
     @Test
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/JavascriptTranslatorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/JavascriptTranslatorTest.java
index 5990418..8ae9f4c 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/JavascriptTranslatorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/JavascriptTranslatorTest.java
@@ -115,6 +115,11 @@ public class JavascriptTranslatorTest {
     }
 
     @Test
+    public void shouldHaveNull() {
+        translator.translate(g.inject(null, null).asAdmin().getBytecode()).getScript();
+    }
+
+    @Test
     public void shouldEscapeStrings() {
         final String script = translator.translate(g.addV("customer")
                 .property("customer_id", 501L)
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/iterator/ArrayIteratorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/iterator/ArrayIteratorTest.java
index 2293277..d2027e3 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/iterator/ArrayIteratorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/iterator/ArrayIteratorTest.java
@@ -78,4 +78,36 @@ public class ArrayIteratorTest {
         final Iterator<String> itty = new ArrayIterator<>(arr);
         assertEquals("[test1, test2, test3]", itty.toString());
     }
+
+    @Test(expected = NullPointerException.class)
+    public void shouldNotAllowNullConstruction() {
+        new ArrayIterator<>(null);
+    }
+
+    @Test
+    public void shouldAllowNullInArray() {
+        final String[] arr = new String[3];
+        arr[0] = "test1";
+        arr[1] = null;
+        arr[2] = "test3";
+
+        final Iterator<String> itty = new ArrayIterator<>(arr);
+        assertEquals("[test1, null, test3]", itty.toString());
+    }
+
+    @Test
+    public void shouldAllowSingleNullInArray() {
+        final String[] arr = new String[1];
+
+        final Iterator<String> itty = new ArrayIterator<>(arr);
+        assertEquals("[null]", itty.toString());
+    }
+
+    @Test
+    public void shouldAllowZeroNullInArray() {
+        final String[] arr = new String[0];
+
+        final Iterator<String> itty = new ArrayIterator<>(arr);
+        assertEquals("[]", itty.toString());
+    }
 }
diff --git a/gremlin-dotnet/build/generate.groovy b/gremlin-dotnet/build/generate.groovy
index ad7a160..5fa64fa 100644
--- a/gremlin-dotnet/build/generate.groovy
+++ b/gremlin-dotnet/build/generate.groovy
@@ -104,52 +104,64 @@ radishGremlinFile.withWriter('UTF-8') { Writer writer ->
             '            new Dictionary<string, List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>>>\n' +
             '            {')
 
+    // Groovy can't process certain null oriented calls because it gets confused with the right overload to call
+    // at runtime. using this approach for now as these are the only such situations encountered so far. a better
+    // solution may become necessary as testing of nulls expands.
+    def staticTranslate = [
+            g_injectXnull_nullX: "               {\"g_injectXnull_nullX\", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null,null)}}, ",
+            g_VX1X_valuesXageX_injectXnull_nullX: "               {\"g_VX1X_valuesXageX_injectXnull_nullX\", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p[\"xx1\"]).Values<object>(\"age\").Inject(null,null)}}, "
+    ]
+
     gremlins.each { k,v ->
-        writer.write("               {\"")
-        writer.write(k)
-        writer.write("\", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {")
-        def collected = v.collect{
-            def t = gremlinGroovyScriptEngine.eval(it, bindings)
-            [t, t.bytecode.bindings.keySet()]
-        }
+        if (staticTranslate.containsKey(k)) {
+            writer.writeLine(staticTranslate[k])
+        } else {
+            writer.write("               {\"")
+            writer.write(k)
+            writer.write("\", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {")
+            def collected = v.collect {
+                def t = gremlinGroovyScriptEngine.eval(it, bindings)
+                [t, t.bytecode.bindings.keySet()]
+            }
 
-        def gremlinItty = collected.iterator()
-        while (gremlinItty.hasNext()) {
-            def t = gremlinItty.next()[0]
-            writer.write("(g,p) =>")
-            writer.write(translator.translate(t.bytecode).script.
-                    replace("xx1", "p[\"xx1\"]").
-                    replace("xx2", "p[\"xx2\"]").
-                    replace("xx3", "p[\"xx3\"]").
-                    replace("v1", "(Vertex) p[\"v1\"]").
-                    replace("v2", "(Vertex) p[\"v2\"]").
-                    replace("v3", "(Vertex) p[\"v3\"]").
-                    replace("v4", "(Vertex) p[\"v4\"]").
-                    replace("v5", "(Vertex) p[\"v5\"]").
-                    replace("v6", "(Vertex) p[\"v6\"]").
-                    replace("vid1", "p[\"vid1\"]").
-                    replace("vid2", "p[\"vid2\"]").
-                    replace("vid3", "p[\"vid3\"]").
-                    replace("vid4", "p[\"vid4\"]").
-                    replace("vid5", "p[\"vid5\"]").
-                    replace("vid6", "p[\"vid6\"]").
-                    replace("e7", "p[\"e7\"]").
-                    replace("e10", "p[\"e10\"]").
-                    replace("e11", "p[\"e11\"]").
-                    replace("eid7", "p[\"eid7\"]").
-                    replace("eid10", "p[\"eid10\"]").
-                    replace("eid11", "p[\"eid11\"]").
-                    replace("l1", "(IFunction) p[\"l1\"]").
-                    replace("l2", "(IFunction) p[\"l2\"]").
-                    replace("pred1", "(IPredicate) p[\"pred1\"]").
-                    replace("c1", "(IComparator) p[\"c1\"]").
-                    replace("c2", "(IComparator) p[\"c2\"]"))
-            if (gremlinItty.hasNext())
-                writer.write(', ')
-            else
-                writer.write("}")
+            def gremlinItty = collected.iterator()
+            while (gremlinItty.hasNext()) {
+                def t = gremlinItty.next()[0]
+                writer.write("(g,p) =>")
+                writer.write(translator.translate(t.bytecode).script.
+                        replace("xx1", "p[\"xx1\"]").
+                        replace("xx2", "p[\"xx2\"]").
+                        replace("xx3", "p[\"xx3\"]").
+                        replace("v1", "(Vertex) p[\"v1\"]").
+                        replace("v2", "(Vertex) p[\"v2\"]").
+                        replace("v3", "(Vertex) p[\"v3\"]").
+                        replace("v4", "(Vertex) p[\"v4\"]").
+                        replace("v5", "(Vertex) p[\"v5\"]").
+                        replace("v6", "(Vertex) p[\"v6\"]").
+                        replace("vid1", "p[\"vid1\"]").
+                        replace("vid2", "p[\"vid2\"]").
+                        replace("vid3", "p[\"vid3\"]").
+                        replace("vid4", "p[\"vid4\"]").
+                        replace("vid5", "p[\"vid5\"]").
+                        replace("vid6", "p[\"vid6\"]").
+                        replace("e7", "p[\"e7\"]").
+                        replace("e10", "p[\"e10\"]").
+                        replace("e11", "p[\"e11\"]").
+                        replace("eid7", "p[\"eid7\"]").
+                        replace("eid10", "p[\"eid10\"]").
+                        replace("eid11", "p[\"eid11\"]").
+                        replace("l1", "(IFunction) p[\"l1\"]").
+                        replace("l2", "(IFunction) p[\"l2\"]").
+                        replace("pred1", "(IPredicate) p[\"pred1\"]").
+                        replace("c1", "(IComparator) p[\"c1\"]").
+                        replace("c2", "(IComparator) p[\"c2\"]"))
+                if (gremlinItty.hasNext())
+                    writer.write(', ')
+                else
+                    writer.write("}")
+            }
+            writer.writeLine('}, ')
         }
-        writer.writeLine('}, ')
     }
     writer.writeLine('            };\n')
 
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index 8f6df56..2bc4de8 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -885,9 +885,18 @@ namespace Gremlin.Net.Process.Traversal
         /// </summary>
         public GraphTraversal<S, E> Inject (params E[] injections)
         {
-            var args = new List<object>(0 + injections.Length) {};
-            args.AddRange(injections.Cast<object>());
-            Bytecode.AddStep("inject", args.ToArray());
+            // null injections is treated as g.inject(null) meaning inject a single null traverser
+            if (injections == null)
+            {
+                Bytecode.AddStep("inject", new object[1] { null });
+            }
+            else
+            {
+                var args = new List<object>(0 + injections.Length) {};
+                args.AddRange(injections.Cast<object>());
+                Bytecode.AddStep("inject", args.ToArray());
+            }
+
             return Wrap<S, E>(this);
         }
 
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
index db4c521..c74e826 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
@@ -351,9 +351,19 @@ namespace Gremlin.Net.Process.Traversal
         public GraphTraversal<S, S> Inject<S>(params S[] starts)
         {
             var traversal = new GraphTraversal<S, S>(TraversalStrategies, new Bytecode(Bytecode));
-            var args = new List<object>(0 + starts.Length) {};
-            args.AddRange(starts.Cast<object>());
-            traversal.Bytecode.AddStep("inject", args.ToArray());
+
+            // null starts is treated as g.inject(null) meaning inject a single null traverser
+            if (starts == null)
+            {
+                traversal.Bytecode.AddStep("inject", new object[1] { null });
+            }
+            else
+            {
+                var args = new List<object>(0 + starts.Length) {};
+                args.AddRange(starts.Cast<object>());
+                traversal.Bytecode.AddStep("inject", args.ToArray());
+            }
+
             return traversal;
         }
 
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index cc043f2..dac2353 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -711,6 +711,12 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_injectXnull_1_3_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null,1,3,null)}}, 
                {"g_injectX10_20_null_20_10_10X_groupCountXxX_dedup_asXyX_projectXa_bX_by_byXselectXxX_selectXselectXyXXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(10,20,null,20,10,10).GroupCount("x").Dedup().As("y").Project<object>("a","b").By().By(__.Select<object>("x").Select<object>(__.Select<object>("y")))}}, 
                {"g_injectXname_marko_age_nullX_selectXname_ageX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Select<object>("name","age")}}, 
+               {"g_injectXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null,null)}}, 
+               {"g_injectXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null)}}, 
+               {"g_inject", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>()}}, 
+               {"g_VX1X_valuesXageX_injectXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["xx1"]).Values<object>("age").Inject(null,null)}}, 
+               {"g_VX1X_valuesXageX_injectXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["xx1"]).Values<object>("age").Inject(null)}}, 
+               {"g_VX1X_valuesXageX_inject", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["xx1"]).Values<object>("age").Inject()}}, 
                {"g_io_readXkryoX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Io<object>("data/tinkerpop-modern.kryo").Read(), (g,p) =>g.V(), (g,p) =>g.E()}}, 
                {"g_io_read_withXreader_gryoX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Io<object>("data/tinkerpop-modern.kryo").With("~tinkerpop.io.reader","gryo").Read(), (g,p) =>g.V(), (g,p) =>g.E()}}, 
                {"g_io_readXgraphsonX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Io<object>("data/tinkerpop-modern.json").Read(), (g,p) =>g.V(), (g,p) =>g.E()}}, 
diff --git a/gremlin-javascript/build/generate.groovy b/gremlin-javascript/build/generate.groovy
index 7a374c0..c82b14d 100644
--- a/gremlin-javascript/build/generate.groovy
+++ b/gremlin-javascript/build/generate.groovy
@@ -93,30 +93,42 @@ radishGremlinFile.withWriter('UTF-8') { Writer writer ->
                     'const TextP = traversalModule.TextP\n' +
                     'const WithOptions = traversalModule.withOptions\n')
 
+    // Groovy can't process certain null oriented calls because it gets confused with the right overload to call
+    // at runtime. using this approach for now as these are the only such situations encountered so far. a better
+    // solution may become necessary as testing of nulls expands.
+    def staticTranslate = [
+            g_injectXnull_nullX: "    g_injectXnull_nullX: [function({g}) { return g.inject(null,null) }], ",
+            g_VX1X_valuesXageX_injectXnull_nullX: "    g_VX1X_valuesXageX_injectXnull_nullX: [function({g, xx1}) { return g.V(xx1).values(\"age\").inject(null,null) }], "
+    ]
+
     writer.writeLine('const gremlins = {')
     gremlins.each { k,v ->
-        writer.write("    ")
-        writer.write(k)
-        writer.write(": [")
-        def collected = v.collect{
-            def t = gremlinGroovyScriptEngine.eval(it, bindings)
-            [t, t.bytecode.bindings.keySet()]
-        }
-        def uniqueBindings = collected.collect{it[1]}.flatten().unique()
-        def gremlinItty = collected.iterator()
-        while (gremlinItty.hasNext()) {
-            def t = gremlinItty.next()[0]
-            writer.write("function({g")
-            if (!uniqueBindings.isEmpty()) {
-                writer.write(", ")
-                writer.write(uniqueBindings.join(", "))
+        if (staticTranslate.containsKey(k)) {
+            writer.writeLine(staticTranslate[k])
+        } else {
+            writer.write("    ")
+            writer.write(k)
+            writer.write(": [")
+            def collected = v.collect {
+                def t = gremlinGroovyScriptEngine.eval(it, bindings)
+                [t, t.bytecode.bindings.keySet()]
+            }
+            def uniqueBindings = collected.collect { it[1] }.flatten().unique()
+            def gremlinItty = collected.iterator()
+            while (gremlinItty.hasNext()) {
+                def t = gremlinItty.next()[0]
+                writer.write("function({g")
+                if (!uniqueBindings.isEmpty()) {
+                    writer.write(", ")
+                    writer.write(uniqueBindings.join(", "))
+                }
+                writer.write("}) { return ")
+                writer.write(translator.translate(t.bytecode).script)
+                writer.write(" }")
+                if (gremlinItty.hasNext()) writer.write(', ')
             }
-            writer.write("}) { return ")
-            writer.write(translator.translate(t.bytecode).script)
-            writer.write(" }")
-            if (gremlinItty.hasNext()) writer.write(', ')
+            writer.writeLine('], ')
         }
-        writer.writeLine('], ')
     }
     writer.writeLine('}\n')
 
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 7548afe..feb52ff 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
@@ -700,6 +700,12 @@ const gremlins = {
     g_injectXnull_1_3_nullX: [function({g}) { return g.inject(null,1,3,null) }], 
     g_injectX10_20_null_20_10_10X_groupCountXxX_dedup_asXyX_projectXa_bX_by_byXselectXxX_selectXselectXyXXX: [function({g}) { return g.inject(10,20,null,20,10,10).groupCount("x").dedup().as("y").project("a","b").by().by(__.select("x").select(__.select("y"))) }], 
     g_injectXname_marko_age_nullX_selectXname_ageX: [function({g, xx1}) { return g.inject(xx1).select("name","age") }], 
+    g_injectXnull_nullX: [function({g}) { return g.inject(null,null) }], 
+    g_injectXnullX: [function({g}) { return g.inject(null) }], 
+    g_inject: [function({g}) { return g.inject() }], 
+    g_VX1X_valuesXageX_injectXnull_nullX: [function({g, xx1}) { return g.V(xx1).values("age").inject(null,null) }], 
+    g_VX1X_valuesXageX_injectXnullX: [function({g, xx1}) { return g.V(xx1).values("age").inject(null) }], 
+    g_VX1X_valuesXageX_inject: [function({g, xx1}) { return g.V(xx1).values("age").inject() }], 
     g_io_readXkryoX: [function({g}) { return g.io("data/tinkerpop-modern.kryo").read() }, function({g}) { return g.V() }, function({g}) { return g.E() }], 
     g_io_read_withXreader_gryoX: [function({g}) { return g.io("data/tinkerpop-modern.kryo").with_("~tinkerpop.io.reader","gryo").read() }, function({g}) { return g.V() }, function({g}) { return g.E() }], 
     g_io_readXgraphsonX: [function({g}) { return g.io("data/tinkerpop-modern.json").read() }, function({g}) { return g.V() }, function({g}) { return g.E() }], 
diff --git a/gremlin-python/build/generate.groovy b/gremlin-python/build/generate.groovy
index 05507d5..bac3d1b 100644
--- a/gremlin-python/build/generate.groovy
+++ b/gremlin-python/build/generate.groovy
@@ -77,31 +77,44 @@ radishGremlinFile.withWriter('UTF-8') { Writer writer ->
                     'from gremlin_python.process.graph_traversal import __\n' +
                     'from gremlin_python.structure.graph import Graph\n' +
                     'from gremlin_python.process.traversal import Barrier, Cardinality, P, TextP, Pop, Scope, Column, Order, Direction, T, Pick, Operator, IO, WithOptions\n')
+
+    // Groovy can't process certain null oriented calls because it gets confused with the right overload to call
+    // at runtime. using this approach for now as these are the only such situations encountered so far. a better
+    // solution may become necessary as testing of nulls expands.
+    def staticTranslate = [
+            g_injectXnull_nullX: "    'g_injectXnull_nullX': [(lambda g: g.inject(None,None))], ",
+            g_VX1X_valuesXageX_injectXnull_nullX: "    'g_VX1X_valuesXageX_injectXnull_nullX': [(lambda g, xx1=None: g.V(xx1).values('age').inject(None,None))], "
+    ]
+
     writer.writeLine('world.gremlins = {')
     gremlins.each { k,v ->
-        writer.write("    '")
-        writer.write(k)
-        writer.write("': [")
-        def collected = v.collect{
-            def t = gremlinGroovyScriptEngine.eval(it, bindings)
-            [t, t.bytecode.bindings.keySet()]
-        }
-        def uniqueBindings = collected.collect{it[1]}.flatten().unique()
-        def gremlinItty = collected.iterator()
-        while (gremlinItty.hasNext()) {
-            def t = gremlinItty.next()[0]
-            writer.write("(lambda g")
-            if (!uniqueBindings.isEmpty()) {
-                writer.write(", ")
-                writer.write(uniqueBindings.join("=None,"))
-                writer.write("=None")
+        if (staticTranslate.containsKey(k)) {
+            writer.writeLine(staticTranslate[k])
+        } else {
+            writer.write("    '")
+            writer.write(k)
+            writer.write("': [")
+            def collected = v.collect {
+                def t = gremlinGroovyScriptEngine.eval(it, bindings)
+                [t, t.bytecode.bindings.keySet()]
+            }
+            def uniqueBindings = collected.collect { it[1] }.flatten().unique()
+            def gremlinItty = collected.iterator()
+            while (gremlinItty.hasNext()) {
+                def t = gremlinItty.next()[0]
+                writer.write("(lambda g")
+                if (!uniqueBindings.isEmpty()) {
+                    writer.write(", ")
+                    writer.write(uniqueBindings.join("=None,"))
+                    writer.write("=None")
+                }
+                writer.write(":")
+                writer.write(translator.translate(t.bytecode).script)
+                writer.write(")")
+                if (gremlinItty.hasNext()) writer.write(', ')
             }
-            writer.write(":")
-            writer.write(translator.translate(t.bytecode).script)
-            writer.write(")")
-            if (gremlinItty.hasNext()) writer.write(', ')
+            writer.writeLine('], ')
         }
-        writer.writeLine('], ')
     }
     writer.writeLine('}')
 }
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index b4e6d81..defbf6b 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -685,6 +685,12 @@ world.gremlins = {
     'g_injectXnull_1_3_nullX': [(lambda g:g.inject(None,1,3,None))], 
     'g_injectX10_20_null_20_10_10X_groupCountXxX_dedup_asXyX_projectXa_bX_by_byXselectXxX_selectXselectXyXXX': [(lambda g:g.inject(10,20,None,20,10,10).groupCount('x').dedup().as_('y').project('a','b').by().by(__.select('x').select(__.select('y'))))], 
     'g_injectXname_marko_age_nullX_selectXname_ageX': [(lambda g, xx1=None:g.inject(xx1).select('name','age'))], 
+    'g_injectXnull_nullX': [(lambda g: g.inject(None,None))], 
+    'g_injectXnullX': [(lambda g:g.inject(None))], 
+    'g_inject': [(lambda g:g.inject())], 
+    'g_VX1X_valuesXageX_injectXnull_nullX': [(lambda g, xx1=None: g.V(xx1).values('age').inject(None,None))], 
+    'g_VX1X_valuesXageX_injectXnullX': [(lambda g, xx1=None:g.V(xx1).age.inject(None))], 
+    'g_VX1X_valuesXageX_inject': [(lambda g, xx1=None:g.V(xx1).age.inject())], 
     'g_io_readXkryoX': [(lambda g:g.io('data/tinkerpop-modern.kryo').read()), (lambda g:g.V()), (lambda g:g.E())], 
     'g_io_read_withXreader_gryoX': [(lambda g:g.io('data/tinkerpop-modern.kryo').with_('~tinkerpop.io.reader','gryo').read()), (lambda g:g.V()), (lambda g:g.E())], 
     'g_io_readXgraphsonX': [(lambda g:g.io('data/tinkerpop-modern.json').read()), (lambda g:g.V()), (lambda g:g.E())], 
diff --git a/gremlin-test/features/sideEffect/Inject.feature b/gremlin-test/features/sideEffect/Inject.feature
index dc5e717..49d8569 100644
--- a/gremlin-test/features/sideEffect/Inject.feature
+++ b/gremlin-test/features/sideEffect/Inject.feature
@@ -104,4 +104,77 @@ Feature: Step - inject()
     When iterated to list
     Then the result should be unordered
       | result |
-      | m[{"name":"marko", "age":null}] |
\ No newline at end of file
+      | m[{"name":"marko", "age":null}] |
+
+  Scenario: g_injectXnull_nullX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null, null)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | null |
+      | null |
+
+  Scenario: g_injectXnullX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(null)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | null |
+
+
+  Scenario: g_inject
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject()
+      """
+    When iterated to list
+    Then the result should be empty
+
+  Scenario: g_VX1X_valuesXageX_injectXnull_nullX
+    Given the modern graph
+    And using the parameter xx1 defined as "v[marko].id"
+    And the traversal of
+      """
+      g.V(xx1).values("age").inject(null, null)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[29].i |
+      | null |
+      | null |
+
+  Scenario: g_VX1X_valuesXageX_injectXnullX
+    Given the modern graph
+    And using the parameter xx1 defined as "v[marko].id"
+    And the traversal of
+      """
+      g.V(xx1).values("age").inject(null)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[29].i |
+      | null |
+
+
+  Scenario: g_VX1X_valuesXageX_inject
+    Given the modern graph
+    And using the parameter xx1 defined as "v[marko].id"
+    And the traversal of
+      """
+      g.V(xx1).values("age").inject()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[29].i |
\ No newline at end of file
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectTest.java
index fd752d2..8fb3eb4 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectTest.java
@@ -30,6 +30,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -51,6 +52,18 @@ public abstract class InjectTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Integer, Integer> get_g_injectXnull_1_3_nullX();
 
+    public abstract Traversal<Integer, Integer> get_g_injectXnull_nullX();
+
+    public abstract Traversal<Integer, Integer> get_g_injectXnullX();
+
+    public abstract Traversal<Integer, Integer> get_g_inject();
+
+    public abstract Traversal<Vertex, Object> get_g_VX1X_valuesXageX_injectXnull_nullX(final Object vid1);
+
+    public abstract Traversal<Vertex, Object> get_g_VX1X_valuesXageX_injectXnullX(final Object vid1);
+
+    public abstract Traversal<Vertex, Object> get_g_VX1X_valuesXageX_inject(final Object vid1);
+
     public abstract Traversal<Integer, Map<String, Object>> get_g_injectX10_20_null_20_10_10X_groupCountXxX_dedup_asXyX_projectXa_bX_by_byXselectXxX_selectXselectXyXXX();
 
     public abstract Traversal<Map<String,Object>, Map<String, Object>> get_g_injectXname_marko_age_nullX_selectXname_ageX();
@@ -99,6 +112,51 @@ public abstract class InjectTest extends AbstractGremlinProcessTest {
     }
 
     @Test
+    public void g_injectXnull_nullX() {
+        final Traversal<Integer, Integer> traversal = get_g_injectXnull_nullX();
+        printTraversalForm(traversal);
+        checkResults(Arrays.asList(null, null), traversal);
+    }
+
+    @Test
+    public void g_injectXnullX() {
+        final Traversal<Integer, Integer> traversal = get_g_injectXnullX();
+        printTraversalForm(traversal);
+        checkResults(Collections.singletonList(null), traversal);
+    }
+
+    @Test
+    public void g_inject() {
+        final Traversal<Integer, Integer> traversal = get_g_inject();
+        printTraversalForm(traversal);
+        assertFalse(traversal.hasNext());
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_VX1X_valuesXageX_injectXnull_nullX() {
+        final Traversal<Vertex, Object> traversal = get_g_VX1X_valuesXageX_injectXnull_nullX(convertToVertexId("marko"));
+        printTraversalForm(traversal);
+        checkResults(Arrays.asList(29, null, null), traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_VX1X_valuesXageX_injectXnullX() {
+        final Traversal<Vertex, Object> traversal = get_g_VX1X_valuesXageX_injectXnullX(convertToVertexId("marko"));
+        printTraversalForm(traversal);
+        checkResults(Arrays.asList(29, null), traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_VX1X_valuesXageX_inject() {
+        final Traversal<Vertex, Object> traversal = get_g_VX1X_valuesXageX_inject(convertToVertexId("marko"));
+        printTraversalForm(traversal);
+        checkResults(Arrays.asList(29), traversal);
+    }
+
+    @Test
     public void g_injectX10_20_null_20_10_10X_groupCountXxX_dedup_asXyX_projectXa_bX_by_byXselectXxX_selectXselectXyXXX() {
         final Traversal<Integer, Map<String, Object>> traversal = get_g_injectX10_20_null_20_10_10X_groupCountXxX_dedup_asXyX_projectXa_bX_by_byXselectXxX_selectXselectXyXXX();
         printTraversalForm(traversal);
@@ -146,6 +204,36 @@ public abstract class InjectTest extends AbstractGremlinProcessTest {
         }
 
         @Override
+        public Traversal<Integer, Integer> get_g_injectXnull_nullX() {
+            return g.inject(null, null);
+        }
+
+        @Override
+        public Traversal<Integer, Integer> get_g_injectXnullX() {
+            return g.inject(null);
+        }
+
+        @Override
+        public Traversal<Integer, Integer> get_g_inject() {
+            return g.inject();
+        }
+
+        @Override
+        public Traversal<Vertex, Object> get_g_VX1X_valuesXageX_injectXnull_nullX(final Object vid1) {
+            return g.V(vid1).values("age").inject(null, null);
+        }
+
+        @Override
+        public Traversal<Vertex, Object> get_g_VX1X_valuesXageX_injectXnullX(final Object vid1) {
+            return g.V(vid1).values("age").inject(null);
+        }
+
+        @Override
+        public Traversal<Vertex, Object> get_g_VX1X_valuesXageX_inject(final Object vid1) {
+            return g.V(vid1).values("age").inject();
+        }
+
+        @Override
         public Traversal<Integer, Map<String, Object>> get_g_injectX10_20_null_20_10_10X_groupCountXxX_dedup_asXyX_projectXa_bX_by_byXselectXxX_selectXselectXyXXX() {
             return g.inject(10,20,null,20,10,10).groupCount("x").
                      dedup().as("y").