You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/08/08 16:09:26 UTC

tinkerpop git commit: added withBindings() which allows Java, Groovy, Python, etc. to defined bindings for Bytecode. That is, a Binding is a fundamental concept in Bytecode. A binding is a variable/value that when translated, will translate to variable n

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1278 e65ff9e7c -> e50f62c1d


added withBindings() which allows Java, Groovy, Python, etc. to defined bindings for Bytecode. That is, a Binding is a fundamental concept in Bytecode. A binding is a variable/value that when translated, will translate to variable name (e.g. with Groovy/Python) or to the value object (e.g. with Java). Created GraphSON serializer/deserislizers for it. Also, was able to simplify PythonGraphTraversal as now we don't need to check for bindings in GraphTraverasl, but at the Bytecode level. Have only done manual testing thus far.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/e50f62c1
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/e50f62c1
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/e50f62c1

Branch: refs/heads/TINKERPOP-1278
Commit: e50f62c1df7293bac2e8eb9cb2f8dd7225728e46
Parents: e65ff9e
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Mon Aug 8 10:09:12 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Mon Aug 8 10:09:12 2016 -0600

----------------------------------------------------------------------
 gremlin-console/bin/gremlin.sh                  |   4 +-
 .../gremlin/process/traversal/Bindings.java     |  44 +++
 .../gremlin/process/traversal/Bytecode.java     |  81 ++++-
 .../process/traversal/TraversalSource.java      |   7 +
 .../traversal/dsl/graph/GraphTraversal.java     |  14 +-
 .../dsl/graph/GraphTraversalSource.java         |   6 +
 .../process/traversal/util/JavaTranslator.java  |  17 +-
 .../structure/io/graphson/GraphSONModule.java   |   2 +
 .../graphson/GraphSONTraversalSerializers.java  |  37 ++
 .../gremlin/groovy/GroovyTranslatorTest.java    |   2 +-
 .../AbstractImportCustomizerProvider.java       |   2 +-
 .../jsr223/GremlinGroovyScriptEngine.java       |   1 -
 .../gremlin/groovy/jsr223/GroovyTranslator.java | 178 ++++++++++
 .../java/translator/GroovyTranslator.java       | 176 ----------
 gremlin-python/pom.xml                          |   2 +-
 .../python/GraphTraversalSourceGenerator.groovy |   9 -
 .../python/TraversalSourceGenerator.groovy      |  23 +-
 .../gremlin/python/jsr223/PythonTranslator.java |   4 +-
 .../driver/rest_remote_connection.py            |   2 +-
 .../gremlin_python/process/graph_traversal.py   | 340 +------------------
 .../jython/gremlin_python/process/traversal.py  |  23 +-
 .../RemoteGraphGroovyTranslatorProvider.java    |   1 +
 .../TinkerGraphGroovyTranslatorProvider.java    |   1 +
 23 files changed, 411 insertions(+), 565 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-console/bin/gremlin.sh
----------------------------------------------------------------------
diff --git a/gremlin-console/bin/gremlin.sh b/gremlin-console/bin/gremlin.sh
index 5fb65ac..d0d3240 100755
--- a/gremlin-console/bin/gremlin.sh
+++ b/gremlin-console/bin/gremlin.sh
@@ -20,5 +20,5 @@
 #
 
 OPTS=$@
-set JAVA_OPTIONS="-Dtinkerpop.ext=/../target/apache-gremlin-*-standalone/ext -Dlog4j.configuration=conf/log4j-console.properties -Dgremlin.log4j.level=$GREMLIN_LOG_LEVEL"
-`dirname $0`/../target/apache-gremlin-*-standalone/bin/gremlin.sh $OPTS
+set JAVA_OPTIONS="-Dtinkerpop.ext=/../target/apache-tinkerpop-gremlin-*-standalone/ext -Dlog4j.configuration=conf/log4j-console.properties -Dgremlin.log4j.level=$GREMLIN_LOG_LEVEL"
+`dirname $0`/../target/apache-tinkerpop-gremlin-*-standalone/bin/gremlin.sh $OPTS

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java
new file mode 100644
index 0000000..e641e57
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bindings.java
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.process.traversal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class Bindings {
+
+    private final Map<Object, String> map = new HashMap<>();
+
+    public <V> V of(final String variable, final V value) {
+        this.map.put(value, variable);
+        return value;
+    }
+
+    public <V> String get(final V value) {
+        return this.map.get(value);
+    }
+
+    public void clear() {
+        this.map.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
index 3fd6daf..0ace6e9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
@@ -25,7 +25,9 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * When a {@link TraversalSource} is manipulated, a {@link Traversal} is spawned and then mutated, a language
@@ -40,14 +42,22 @@ public final class Bytecode implements Cloneable, Serializable {
 
     private List<Instruction> sourceInstructions = new ArrayList<>();
     private List<Instruction> stepInstructions = new ArrayList<>();
-    // private transient List<Instruction> instructions = null;
+    private transient Bindings bindings = null;
+    private Map<String, Object> map = new HashMap<>();
 
     public void addSource(final String sourceName, final Object... arguments) {
-        this.sourceInstructions.add(new Instruction(sourceName, flattenArguments(arguments)));
+        if (sourceName.equals(TraversalSource.Symbols.withBindings)) {
+            this.bindings = (Bindings) arguments[0];
+            this.bindings.clear();
+        } else {
+            this.sourceInstructions.add(new Instruction(sourceName, flattenArguments(arguments)));
+            if (null != this.bindings) this.bindings.clear();
+        }
     }
 
     public void addStep(final String stepName, final Object... arguments) {
         this.stepInstructions.add(new Instruction(stepName, flattenArguments(arguments)));
+        if (null != this.bindings) this.bindings.clear();
     }
 
     public List<Instruction> getSourceInstructions() {
@@ -58,14 +68,9 @@ public final class Bytecode implements Cloneable, Serializable {
         return Collections.unmodifiableList(this.stepInstructions);
     }
 
-    /*public List<Instruction> getInstructions() {
-        if (null == this.instructions) {
-            this.instructions = new ArrayList<>();
-            this.instructions.addAll(this.sourceInstructions);
-            this.instructions.addAll(this.stepInstructions);
-        }
-        return this.instructions;
-    }*/
+    public Map<String, Object> getBindings() {
+        return this.map;
+    }
 
     @Override
     public String toString() {
@@ -91,7 +96,6 @@ public final class Bytecode implements Cloneable, Serializable {
             final Bytecode clone = (Bytecode) super.clone();
             clone.sourceInstructions = new ArrayList<>(this.sourceInstructions);
             clone.stepInstructions = new ArrayList<>(this.stepInstructions);
-            //clone.instructions = null;
             return clone;
         } catch (final CloneNotSupportedException e) {
             throw new IllegalStateException(e.getMessage(), e);
@@ -142,9 +146,45 @@ public final class Bytecode implements Cloneable, Serializable {
 
     }
 
+    public static class Binding<V> {
+
+        private final String variable;
+        private final V value;
+
+        public Binding(final String variable, final V value) {
+            this.variable = variable;
+            this.value = value;
+        }
+
+        public String variable() {
+            return this.variable;
+        }
+
+        public V value() {
+            return this.value;
+        }
+
+        @Override
+        public String toString() {
+            return "binding[" + this.variable + "=" + this.value + "]";
+        }
+
+        @Override
+        public boolean equals(final Object object) {
+            return object instanceof Binding &&
+                    this.variable.equals(((Binding) object).variable) &&
+                    this.value.equals(((Binding) object).value);
+        }
+
+        @Override
+        public int hashCode() {
+            return this.variable.hashCode() + this.value.hashCode();
+        }
+    }
+
     /////
 
-    private static final Object[] flattenArguments(final Object... arguments) {
+    private final Object[] flattenArguments(final Object... arguments) {
         if (arguments.length == 0)
             return new Object[]{};
         final List<Object> flatArguments = new ArrayList<>();
@@ -159,7 +199,20 @@ public final class Bytecode implements Cloneable, Serializable {
         return flatArguments.toArray();
     }
 
-    private static final Object convertArgument(final Object argument) {
-        return argument instanceof Traversal ? ((Traversal) argument).asAdmin().getBytecode() : argument;
+    private final Object convertArgument(final Object argument) {
+        if (argument instanceof Traversal) {
+            ((Traversal) argument).asAdmin().getBytecode().getBindings().forEach(this.map::put);
+            return ((Traversal) argument).asAdmin().getBytecode();
+        }
+
+        if (null != this.bindings) {
+            final String variable = this.bindings.get(argument);
+            if (null != variable) {
+                this.map.put(variable, argument);
+                return new Binding<>(variable, argument);
+            }
+        }
+
+        return argument;
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
index 5491c84..0b9a2d6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
@@ -79,6 +79,7 @@ public interface TraversalSource extends Cloneable {
             // static fields only
         }
 
+        public static final String withBindings = "withBindings";
         public static final String withSack = "withSack";
         public static final String withStrategies = "withStrategies";
         public static final String withoutStrategies = "withoutStrategies";
@@ -129,6 +130,12 @@ public interface TraversalSource extends Cloneable {
         return clone;
     }
 
+    public default TraversalSource withBindings(final Bindings bindings) {
+        final TraversalSource clone = this.clone();
+        clone.getBytecode().addSource(Symbols.withBindings, bindings);
+        return clone;
+    }
+
     /**
      * Add a {@link Function} that will generate a {@link GraphComputer} from the {@link Graph} that will be used to execute the traversal.
      * This adds a {@link VertexProgramStrategy} to the strategies.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
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 b00cfcb..4c08068 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
@@ -1270,7 +1270,10 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     public default <M, E2> GraphTraversal<S, E2> branch(final Function<Traverser<E>, M> function) {
-        return this.branch(__.map(function));
+        this.asAdmin().getBytecode().addStep(Symbols.branch, function);
+        final BranchStep<E, E2, M> branchStep = new BranchStep<>(this.asAdmin());
+        branchStep.setBranchTraversal((Traversal.Admin<E, M>) __.map(function));
+        return this.asAdmin().addStep(branchStep);
     }
 
     public default <M, E2> GraphTraversal<S, E2> choose(final Traversal<?, M> choiceTraversal) {
@@ -1285,16 +1288,19 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     public default <M, E2> GraphTraversal<S, E2> choose(final Function<E, M> choiceFunction) {
-        return this.choose(__.map(new FunctionTraverser<>(choiceFunction)));
+        this.asAdmin().getBytecode().addStep(Symbols.choose, choiceFunction);
+        return this.asAdmin().addStep(new ChooseStep<>(this.asAdmin(), (Traversal.Admin<E, M>) __.map(new FunctionTraverser<>(choiceFunction))));
     }
 
     public default <E2> GraphTraversal<S, E2> choose(final Predicate<E> choosePredicate,
                                                      final Traversal<?, E2> trueChoice, final Traversal<?, E2> falseChoice) {
-        return this.choose(__.filter(new PredicateTraverser<>(choosePredicate)), trueChoice, falseChoice);
+        this.asAdmin().getBytecode().addStep(Symbols.choose, choosePredicate, trueChoice, falseChoice);
+        return this.asAdmin().addStep(new ChooseStep<E, E2, Boolean>(this.asAdmin(), (Traversal.Admin<E, ?>) __.filter(new PredicateTraverser<>(choosePredicate)), (Traversal.Admin<E, E2>) trueChoice, (Traversal.Admin<E, E2>) falseChoice));
     }
 
     public default <E2> GraphTraversal<S, E2> optional(final Traversal<?, E2> optionalTraversal) {
-        return this.choose(optionalTraversal, optionalTraversal.asAdmin().clone(), __.identity());
+        this.asAdmin().getBytecode().addStep(Symbols.optional, optionalTraversal);
+        return this.asAdmin().addStep(new ChooseStep<>(this.asAdmin(), (Traversal.Admin<E, ?>) optionalTraversal, (Traversal.Admin<E, E2>) optionalTraversal.asAdmin().clone(), (Traversal.Admin<E, E2>) __.<E2>identity()));
     }
 
     public default <E2> GraphTraversal<S, E2> union(final Traversal<?, E2>... unionTraversals) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
----------------------------------------------------------------------
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 4197988..828f3b2 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
@@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.process.traversal.dsl.graph;
 
 import org.apache.tinkerpop.gremlin.process.computer.Computer;
 import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
+import org.apache.tinkerpop.gremlin.process.traversal.Bindings;
 import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 import org.apache.tinkerpop.gremlin.process.traversal.Translator;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
@@ -113,6 +114,11 @@ public class GraphTraversalSource implements TraversalSource {
     //// CONFIGURATIONS
 
     @Override
+    public GraphTraversalSource withBindings(final Bindings bindings) {
+        return (GraphTraversalSource) TraversalSource.super.withBindings(bindings);
+    }
+
+    @Override
     public GraphTraversalSource withTranslator(final Translator translator) {
         return (GraphTraversalSource) TraversalSource.super.withTranslator(translator);
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java
index fc271e0..891440c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java
@@ -121,6 +121,12 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
             }
         }
         ///
+        for (int i = 0; i < arguments.length; i++) {
+            if (arguments[i] instanceof Bytecode.Binding)
+                arguments[i] = ((Bytecode.Binding) arguments[i]).value();
+            else if (arguments[i] instanceof Bytecode)
+                arguments[i] = translateFromAnonymous((Bytecode) arguments[i]);
+        }
         try {
             for (final Method method : methodCache.get(methodName)) {
                 if (returnType.isAssignableFrom(method.getReturnType())) {
@@ -133,9 +139,7 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
                                 Object[] varArgs = (Object[]) Array.newInstance(parameters[i].getType().getComponentType(), arguments.length - i);
                                 int counter = 0;
                                 for (int j = i; j < arguments.length; j++) {
-                                    varArgs[counter++] = arguments[j] instanceof Bytecode ?
-                                            this.translateFromAnonymous((Bytecode) arguments[j]) :
-                                            arguments[j];
+                                    varArgs[counter++] = arguments[j];
                                 }
                                 newArguments[i] = varArgs;
                                 break;
@@ -146,11 +150,8 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
                                                         (Number.class.isAssignableFrom(arguments[i].getClass()) ||
                                                                 arguments[i].getClass().equals(Boolean.class) ||
                                                                 arguments[i].getClass().equals(Byte.class) ||
-                                                                arguments[i].getClass().equals(Character.class))) ||
-                                                (parameters[i].getType().isAssignableFrom(Traversal.class) && arguments[i] instanceof Bytecode))) {
-                                    newArguments[i] = arguments[i] instanceof Bytecode ?
-                                            this.translateFromAnonymous((Bytecode) arguments[i]) :
-                                            arguments[i];
+                                                                arguments[i].getClass().equals(Character.class))))) {
+                                    newArguments[i] = arguments[i];
                                 } else {
                                     found = false;
                                     break;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
index d625125..a4850f7 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
@@ -140,11 +140,13 @@ abstract class GraphSONModule extends SimpleModule {
             addSerializer(T.class, new GraphSONTraversalSerializers.EnumJacksonSerializer());
             addSerializer(P.class, new GraphSONTraversalSerializers.PJacksonSerializer());
             addSerializer(Lambda.class, new GraphSONTraversalSerializers.LambdaJacksonSerializer());
+            addSerializer(Bytecode.Binding.class, new GraphSONTraversalSerializers.BindingJacksonSerializer());
             // -- deserializers for traversal
             addDeserializer(Bytecode.class, new GraphSONTraversalSerializers.BytecodeJacksonDeserializer());
             addDeserializer(Enum.class, new GraphSONTraversalSerializers.EnumJacksonDeserializer());
             addDeserializer(P.class, new GraphSONTraversalSerializers.PJacksonDeserializer());
             addDeserializer(Lambda.class, new GraphSONTraversalSerializers.LambdaJacksonDeserializer());
+            addDeserializer(Bytecode.Binding.class, new GraphSONTraversalSerializers.BindingJacksonDeserializer());
 
         }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
index 78ca36e..faea5b9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
@@ -170,6 +170,24 @@ public final class GraphSONTraversalSerializers {
 
     }
 
+    final static class BindingJacksonSerializer extends StdSerializer<Bytecode.Binding> {
+
+        public BindingJacksonSerializer() {
+            super(Bytecode.Binding.class);
+        }
+
+        @Override
+        public void serialize(final Bytecode.Binding binding, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            jsonGenerator.writeStringField("@type", "Binding");
+            jsonGenerator.writeStringField("variable", binding.variable());
+            jsonGenerator.writeObjectField("value", binding.value());
+            jsonGenerator.writeEndObject();
+        }
+
+    }
+
     ///////////////////
     // DESERIALIZERS //
     //////////////////
@@ -190,6 +208,8 @@ public final class GraphSONTraversalSerializers {
                         final String type = argument.get("@type").textValue();
                         if (type.equals("Bytecode"))
                             arguments.add(oc.readValue(argument.traverse(oc), Bytecode.class));
+                        else if (type.equals("Binding"))
+                            arguments.add(oc.readValue(argument.traverse(oc), Bytecode.Binding.class));
                         else if (type.equals("P"))
                             arguments.add(oc.readValue(argument.traverse(oc), P.class));
                         else if (type.equals("Lambda"))
@@ -333,5 +353,22 @@ public final class GraphSONTraversalSerializers {
         }
     }
 
+    final static class BindingJacksonDeserializer extends StdDeserializer<Bytecode.Binding> {
+
+        public BindingJacksonDeserializer() {
+            super(Bytecode.Binding.class);
+        }
+
+        @Override
+        public Bytecode.Binding deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final ObjectCodec oc = jsonParser.getCodec();
+            final JsonNode node = oc.readTree(jsonParser);
+            assert node.get("@type").textValue().equals("Binding");
+            final String variable = node.get("variable").textValue();
+            final Object value = oc.readValue(node.get("value").traverse(oc), Object.class);
+            return new Bytecode.Binding<>(variable, value);
+        }
+    }
+
 
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyTranslatorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyTranslatorTest.java b/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyTranslatorTest.java
index 9a936c1..f76fa7a 100644
--- a/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyTranslatorTest.java
+++ b/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyTranslatorTest.java
@@ -21,7 +21,7 @@ package org.apache.tinkerpop.gremlin.groovy;
 
 import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
 import org.apache.tinkerpop.gremlin.LoadGraphWith;
-import org.apache.tinkerpop.gremlin.java.translator.GroovyTranslator;
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java
index 3f7eec2..27939b1 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/AbstractImportCustomizerProvider.java
@@ -23,7 +23,7 @@ import groovy.json.JsonBuilder;
 import org.apache.commons.configuration.Configuration;
 import org.apache.tinkerpop.gremlin.groovy.function.GFunction;
 import org.apache.tinkerpop.gremlin.groovy.loaders.GremlinLoader;
-import org.apache.tinkerpop.gremlin.java.translator.GroovyTranslator;
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator;
 import org.apache.tinkerpop.gremlin.process.computer.Computer;
 import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
 import org.apache.tinkerpop.gremlin.process.computer.bulkdumping.BulkDumperVertexProgram;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java
index 1a0ae41..e5f4bca 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.java
@@ -38,7 +38,6 @@ import groovy.lang.MissingMethodException;
 import groovy.lang.MissingPropertyException;
 import groovy.lang.Script;
 import groovy.lang.Tuple;
-import org.apache.tinkerpop.gremlin.java.translator.GroovyTranslator;
 import org.apache.tinkerpop.gremlin.jsr223.Customizer;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngine;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngineFactory;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
new file mode 100644
index 0000000..ee233c4
--- /dev/null
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
@@ -0,0 +1,178 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.groovy.jsr223;
+
+import org.apache.tinkerpop.gremlin.process.computer.Computer;
+import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
+import org.apache.tinkerpop.gremlin.process.traversal.Translator;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException;
+import org.apache.tinkerpop.gremlin.process.traversal.util.BytecodeHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
+import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.Lambda;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroovyTranslator implements Translator.ScriptTranslator {
+
+    private final String traversalSource;
+    private final String anonymousTraversal;
+
+    private GroovyTranslator(final String traversalSource, final String anonymousTraversal) {
+        this.traversalSource = traversalSource;
+        this.anonymousTraversal = anonymousTraversal;
+    }
+
+    public static final GroovyTranslator of(final String traversalSource, final String anonymousTraversal) {
+        return new GroovyTranslator(traversalSource, anonymousTraversal);
+    }
+
+    public static final GroovyTranslator of(final String traversalSource) {
+        return new GroovyTranslator(traversalSource, "__");
+    }
+
+    ///////
+
+    @Override
+    public String translate(final Bytecode bytecode) {
+        return this.internalTranslate(this.traversalSource, bytecode);
+    }
+
+    @Override
+    public String getTargetLanguage() {
+        return "gremlin-groovy";
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.translatorString(this);
+    }
+
+    @Override
+    public String getTraversalSource() {
+        return this.traversalSource;
+    }
+
+    @Override
+    public String getAnonymousTraversal() {
+        return this.anonymousTraversal;
+    }
+
+    ///////
+
+    private String internalTranslate(final String start, final Bytecode bytecode) {
+        final StringBuilder traversalScript = new StringBuilder(start);
+        final Bytecode clone = BytecodeHelper.filterInstructions(bytecode,
+                instruction -> !Arrays.asList("withTranslator", "withStrategies").contains(instruction.getOperator()));
+        for (final Bytecode.Instruction instruction : clone.getSourceInstructions()) {
+            processInstruction(traversalScript, instruction);
+        }
+        for (final Bytecode.Instruction instruction : clone.getStepInstructions()) {
+            processInstruction(traversalScript, instruction);
+        }
+        final String script = traversalScript.toString();
+        if (script.contains("$"))
+            throw new VerificationException("Lambdas are currently not supported: " + script, EmptyTraversal.instance());
+        return script;
+    }
+
+    private void processInstruction(final StringBuilder traversalScript, final Bytecode.Instruction instruction) {
+        final String methodName = instruction.getOperator();
+        final Object[] arguments = instruction.getArguments();
+        final List<Object> objects = Arrays.asList(arguments);
+        if (objects.isEmpty())
+            traversalScript.append(".").append(methodName).append("()");
+        else {
+            traversalScript.append(".");
+            String temp = methodName + "(";
+            for (final Object object : objects) {
+                temp = temp + convertToString(object) + ",";
+            }
+            traversalScript.append(temp.substring(0, temp.length() - 1) + ")");
+        }
+    }
+
+    private String convertToString(final Object object) {
+        if (object instanceof Bytecode.Binding)
+            return ((Bytecode.Binding) object).variable();
+        else if (object instanceof String)
+            return "\"" + object + "\"";
+        else if (object instanceof List) {
+            final List<String> list = new ArrayList<>(((List) object).size());
+            for (final Object item : (List) object) {
+                list.add(convertToString(item));
+            }
+            return list.toString();
+        } else if (object instanceof Long)
+            return object + "L";
+        else if (object instanceof Double)
+            return object + "d";
+        else if (object instanceof Float)
+            return object + "f";
+        else if (object instanceof Integer)
+            return "(int) " + object;
+        else if (object instanceof Class)
+            return ((Class) object).getCanonicalName();
+        else if (object instanceof P)
+            return convertPToString((P) object, new StringBuilder()).toString();
+        else if (object instanceof SackFunctions.Barrier)
+            return "SackFunctions.Barrier." + object.toString();
+        else if (object instanceof VertexProperty.Cardinality)
+            return "VertexProperty.Cardinality." + object.toString();
+        else if (object instanceof Enum)
+            return ((Enum) object).getDeclaringClass().getSimpleName() + "." + object.toString();
+        else if (object instanceof Element)
+            return convertToString(((Element) object).id()); // hack
+        else if (object instanceof Computer) { // TODO: blow out
+            return "";
+        } else if (object instanceof Lambda) {
+            final String lambdaString = ((Lambda) object).getLambdaScript();
+            return lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}";
+        } else if (object instanceof Bytecode)
+            return this.internalTranslate(this.anonymousTraversal, (Bytecode) object);
+        else
+            return null == object ? "null" : object.toString();
+    }
+
+    private StringBuilder convertPToString(final P p, final StringBuilder current) {
+        if (p instanceof ConnectiveP) {
+            final List<P<?>> list = ((ConnectiveP) p).getPredicates();
+            for (int i = 0; i < list.size(); i++) {
+                convertPToString(list.get(i), current);
+                if (i < list.size() - 1)
+                    current.append(p instanceof OrP ? ".or(" : ".and(");
+            }
+            current.append(")");
+        } else
+            current.append("P.").append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
+        return current;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/java/translator/GroovyTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/java/translator/GroovyTranslator.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/java/translator/GroovyTranslator.java
deleted file mode 100644
index 39c60df..0000000
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/java/translator/GroovyTranslator.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.tinkerpop.gremlin.java.translator;
-
-import org.apache.tinkerpop.gremlin.process.computer.Computer;
-import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
-import org.apache.tinkerpop.gremlin.process.traversal.P;
-import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
-import org.apache.tinkerpop.gremlin.process.traversal.Translator;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException;
-import org.apache.tinkerpop.gremlin.process.traversal.util.BytecodeHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
-import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
-import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
-import org.apache.tinkerpop.gremlin.structure.Element;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.Lambda;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class GroovyTranslator implements Translator.ScriptTranslator {
-
-    private final String traversalSource;
-    private final String anonymousTraversal;
-
-    private GroovyTranslator(final String traversalSource, final String anonymousTraversal) {
-        this.traversalSource = traversalSource;
-        this.anonymousTraversal = anonymousTraversal;
-    }
-
-    public static final GroovyTranslator of(final String traversalSource, final String anonymousTraversal) {
-        return new GroovyTranslator(traversalSource, anonymousTraversal);
-    }
-
-    public static final GroovyTranslator of(final String traversalSource) {
-        return new GroovyTranslator(traversalSource, "__");
-    }
-
-    ///////
-
-    @Override
-    public String translate(final Bytecode bytecode) {
-        return this.internalTranslate(this.traversalSource, bytecode);
-    }
-
-    @Override
-    public String getTargetLanguage() {
-        return "gremlin-groovy";
-    }
-
-    @Override
-    public String toString() {
-        return StringFactory.translatorString(this);
-    }
-
-    @Override
-    public String getTraversalSource() {
-        return this.traversalSource;
-    }
-
-    @Override
-    public String getAnonymousTraversal() {
-        return this.anonymousTraversal;
-    }
-
-    ///////
-
-    private String internalTranslate(final String start, final Bytecode bytecode) {
-        final StringBuilder traversalScript = new StringBuilder(start);
-        final Bytecode clone = BytecodeHelper.filterInstructions(bytecode,
-                instruction -> !Arrays.asList("withTranslator", "withStrategies").contains(instruction.getOperator()));
-        for (final Bytecode.Instruction instruction : clone.getSourceInstructions()) {
-            processInstruction(traversalScript, instruction);
-        }
-        for (final Bytecode.Instruction instruction : clone.getStepInstructions()) {
-            processInstruction(traversalScript, instruction);
-        }
-        final String script = traversalScript.toString();
-        if (script.contains("$"))
-            throw new VerificationException("Lambdas are currently not supported: " + script, EmptyTraversal.instance());
-        return script;
-    }
-
-    private void processInstruction(final StringBuilder traversalScript, final Bytecode.Instruction instruction) {
-        final String methodName = instruction.getOperator();
-        final Object[] arguments = instruction.getArguments();
-        final List<Object> objects = Arrays.asList(arguments);
-        if (objects.isEmpty())
-            traversalScript.append(".").append(methodName).append("()");
-        else {
-            traversalScript.append(".");
-            String temp = methodName + "(";
-            for (final Object object : objects) {
-                temp = temp + convertToString(object) + ",";
-            }
-            traversalScript.append(temp.substring(0, temp.length() - 1) + ")");
-        }
-    }
-
-    private String convertToString(final Object object) {
-        if (object instanceof String)
-            return "\"" + object + "\"";
-        else if (object instanceof List) {
-            final List<String> list = new ArrayList<>(((List) object).size());
-            for (final Object item : (List) object) {
-                list.add(convertToString(item));
-            }
-            return list.toString();
-        } else if (object instanceof Long)
-            return object + "L";
-        else if (object instanceof Double)
-            return object + "d";
-        else if (object instanceof Float)
-            return object + "f";
-        else if (object instanceof Integer)
-            return "(int) " + object;
-        else if (object instanceof Class)
-            return ((Class) object).getCanonicalName();
-        else if (object instanceof P)
-            return convertPToString((P) object, new StringBuilder()).toString();
-        else if (object instanceof SackFunctions.Barrier)
-            return "SackFunctions.Barrier." + object.toString();
-        else if (object instanceof VertexProperty.Cardinality)
-            return "VertexProperty.Cardinality." + object.toString();
-        else if (object instanceof Enum)
-            return ((Enum) object).getDeclaringClass().getSimpleName() + "." + object.toString();
-        else if (object instanceof Element)
-            return convertToString(((Element) object).id()); // hack
-        else if (object instanceof Computer) { // TODO: blow out
-            return "";
-        } else if (object instanceof Lambda) {
-            final String lambdaString = ((Lambda) object).getLambdaScript();
-            return lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}";
-        } else if (object instanceof Bytecode)
-            return this.internalTranslate(this.anonymousTraversal, (Bytecode) object);
-        else
-            return null == object ? "null" : object.toString();
-    }
-
-    private StringBuilder convertPToString(final P p, final StringBuilder current) {
-        if (p instanceof ConnectiveP) {
-            final List<P<?>> list = ((ConnectiveP) p).getPredicates();
-            for (int i = 0; i < list.size(); i++) {
-                convertPToString(list.get(i), current);
-                if (i < list.size() - 1)
-                    current.append(p instanceof OrP ? ".or(" : ".and(");
-            }
-            current.append(")");
-        } else
-            current.append("P.").append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
-        return current;
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-python/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml
index 92f1c2f..7e6030c 100644
--- a/gremlin-python/pom.xml
+++ b/gremlin-python/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.apache.tinkerpop</groupId>
         <artifactId>tinkerpop</artifactId>
-        <version>3.2.1-SNAPSHOT</version>
+        <version>3.2.2-SNAPSHOT</version>
     </parent>
     <artifactId>gremlin-python</artifactId>
     <name>Apache TinkerPop :: Gremlin Python</name>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
index 0992beb..f507171 100644
--- a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
+++ b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
@@ -91,9 +91,6 @@ under the License.
                             """  def ${method}(self, *args):
     traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     traversal.bytecode.add_step("${method}", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return traversal
 """)
                 } else if (TraversalSource.isAssignableFrom(returnType)) {
@@ -101,9 +98,6 @@ under the License.
                             """  def ${method}(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("${method}", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
 """)
                 }
@@ -132,9 +126,6 @@ under the License.
                 pythonClass.append(
                         """  def ${method}(self, *args):
     self.bytecode.add_step("${method}", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
 """)
             }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
index f2a95bf..59d09a4 100644
--- a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
+++ b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
@@ -66,7 +66,6 @@ class Traversal(object):
         self.side_effects = {}
         self.traversers = None
         self.last_traverser = None
-        self.bindings = {}
 
     def __repr__(self):
         return str(self.bytecode)
@@ -217,6 +216,7 @@ class Bytecode(object):
     def __init__(self, bytecode=None):
         self.source_instructions = []
         self.step_instructions = []
+        self.bindings = {}
         if bytecode is not None:
             self.source_instructions = list(bytecode.source_instructions)
             self.step_instructions = list(bytecode.step_instructions)
@@ -224,23 +224,36 @@ class Bytecode(object):
     def add_source(self, source_name, *args):
         newArgs = ()
         for arg in args:
-            newArgs = newArgs + (Bytecode.__convertArgument(arg),)
+            newArgs = newArgs + (self.__convertArgument(arg),)
         self.source_instructions.append((source_name, newArgs))
         return
 
     def add_step(self, step_name, *args):
         newArgs = ()
         for arg in args:
-            newArgs = newArgs + (Bytecode.__convertArgument(arg),)
+            newArgs = newArgs + (self.__convertArgument(arg),)
         self.step_instructions.append((step_name, newArgs))
         return
 
-    @staticmethod
-    def __convertArgument(arg):
+    def __convertArgument(self,arg):
         if isinstance(arg, Traversal):
+            self.bindings.update(arg.bytecode.bindings)
             return arg.bytecode
+        elif isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
+            self.bindings[arg[0]] = arg[1]
+            return Binding(arg[0],arg[1])
         else:
             return arg
+
+'''
+BINDING
+'''
+
+class Binding(object):
+    def __init__(self,variable,value):
+        self.variable = variable
+        self.value = value
+
 """)
         //////////////
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
index efe1768..b2d1cb1 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
@@ -160,7 +160,9 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
     }
 
     private String convertToString(final Object object) {
-        if (object instanceof String)
+        if (object instanceof Bytecode.Binding)
+            return ((Bytecode.Binding) object).variable();
+        else if (object instanceof String)
             return "\"" + object + "\"";
         else if (object instanceof List) {
             final List<String> list = new ArrayList<>(((List) object).size());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-python/src/main/jython/gremlin_python/driver/rest_remote_connection.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/driver/rest_remote_connection.py b/gremlin-python/src/main/jython/gremlin_python/driver/rest_remote_connection.py
index f204d15..3346b74 100644
--- a/gremlin-python/src/main/jython/gremlin_python/driver/rest_remote_connection.py
+++ b/gremlin-python/src/main/jython/gremlin_python/driver/rest_remote_connection.py
@@ -35,7 +35,7 @@ class RESTRemoteConnection(RemoteConnection):
 
     def submit(self, target_language, bytecode):
         response = requests.post(self.url, data=json.dumps(
-            {"gremlin": bytecode, "source": self.traversal_source, "language": target_language, "bindings": None}))
+            {"gremlin": bytecode, "source": self.traversal_source, "language": target_language, "bindings": bytecode.bindings}))
         if response.status_code != requests.codes.ok:
             raise BaseException(response.text)
         traversers = []

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
index 5c6be95..be05299 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
@@ -32,86 +32,54 @@ class GraphTraversalSource(object):
   def E(self, *args):
     traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     traversal.bytecode.add_step("E", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return traversal
   def V(self, *args):
     traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     traversal.bytecode.add_step("V", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return traversal
   def addV(self, *args):
     traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     traversal.bytecode.add_step("addV", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return traversal
   def inject(self, *args):
     traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     traversal.bytecode.add_step("inject", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return traversal
+  def withBindings(self, *args):
+    source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
+    source.bytecode.add_source("withBindings", *args)
+    return source
   def withBulk(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("withBulk", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
   def withComputer(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("withComputer", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
   def withPath(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("withPath", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
   def withSack(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("withSack", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
   def withSideEffect(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("withSideEffect", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
   def withStrategies(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("withStrategies", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
   def withTranslator(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("withTranslator", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
   def withoutStrategies(self, *args):
     source = GraphTraversalSource(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
     source.bytecode.add_source("withoutStrategies", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return source
 
 
@@ -120,603 +88,303 @@ class GraphTraversal(Traversal):
     Traversal.__init__(self, graph, traversal_strategies, bytecode)
   def V(self, *args):
     self.bytecode.add_step("V", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def _and(self, *args):
     self.bytecode.add_step("_and", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def _as(self, *args):
     self.bytecode.add_step("_as", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def _from(self, *args):
     self.bytecode.add_step("_from", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def _in(self, *args):
     self.bytecode.add_step("_in", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def _is(self, *args):
     self.bytecode.add_step("_is", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def _not(self, *args):
     self.bytecode.add_step("_not", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def _or(self, *args):
     self.bytecode.add_step("_or", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def addE(self, *args):
     self.bytecode.add_step("addE", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def addInE(self, *args):
     self.bytecode.add_step("addInE", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def addOutE(self, *args):
     self.bytecode.add_step("addOutE", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def addV(self, *args):
     self.bytecode.add_step("addV", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def aggregate(self, *args):
     self.bytecode.add_step("aggregate", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def asAdmin(self, *args):
     self.bytecode.add_step("asAdmin", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def barrier(self, *args):
     self.bytecode.add_step("barrier", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def both(self, *args):
     self.bytecode.add_step("both", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def bothE(self, *args):
     self.bytecode.add_step("bothE", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def bothV(self, *args):
     self.bytecode.add_step("bothV", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def branch(self, *args):
     self.bytecode.add_step("branch", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def by(self, *args):
     self.bytecode.add_step("by", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def cap(self, *args):
     self.bytecode.add_step("cap", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def choose(self, *args):
     self.bytecode.add_step("choose", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def coalesce(self, *args):
     self.bytecode.add_step("coalesce", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def coin(self, *args):
     self.bytecode.add_step("coin", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def constant(self, *args):
     self.bytecode.add_step("constant", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def count(self, *args):
     self.bytecode.add_step("count", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def cyclicPath(self, *args):
     self.bytecode.add_step("cyclicPath", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def dedup(self, *args):
     self.bytecode.add_step("dedup", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def drop(self, *args):
     self.bytecode.add_step("drop", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def emit(self, *args):
     self.bytecode.add_step("emit", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def filter(self, *args):
     self.bytecode.add_step("filter", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def flatMap(self, *args):
     self.bytecode.add_step("flatMap", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def fold(self, *args):
     self.bytecode.add_step("fold", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def group(self, *args):
     self.bytecode.add_step("group", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def groupCount(self, *args):
     self.bytecode.add_step("groupCount", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def groupV3d0(self, *args):
     self.bytecode.add_step("groupV3d0", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def has(self, *args):
     self.bytecode.add_step("has", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def hasId(self, *args):
     self.bytecode.add_step("hasId", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def hasKey(self, *args):
     self.bytecode.add_step("hasKey", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def hasLabel(self, *args):
     self.bytecode.add_step("hasLabel", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def hasNot(self, *args):
     self.bytecode.add_step("hasNot", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def hasValue(self, *args):
     self.bytecode.add_step("hasValue", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def id(self, *args):
     self.bytecode.add_step("id", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def identity(self, *args):
     self.bytecode.add_step("identity", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def inE(self, *args):
     self.bytecode.add_step("inE", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def inV(self, *args):
     self.bytecode.add_step("inV", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def inject(self, *args):
     self.bytecode.add_step("inject", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def iterate(self, *args):
     self.bytecode.add_step("iterate", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def key(self, *args):
     self.bytecode.add_step("key", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def label(self, *args):
     self.bytecode.add_step("label", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def limit(self, *args):
     self.bytecode.add_step("limit", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def local(self, *args):
     self.bytecode.add_step("local", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def loops(self, *args):
     self.bytecode.add_step("loops", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def map(self, *args):
     self.bytecode.add_step("map", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def mapKeys(self, *args):
     self.bytecode.add_step("mapKeys", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def mapValues(self, *args):
     self.bytecode.add_step("mapValues", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def match(self, *args):
     self.bytecode.add_step("match", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def max(self, *args):
     self.bytecode.add_step("max", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def mean(self, *args):
     self.bytecode.add_step("mean", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def min(self, *args):
     self.bytecode.add_step("min", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def option(self, *args):
     self.bytecode.add_step("option", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def optional(self, *args):
     self.bytecode.add_step("optional", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def order(self, *args):
     self.bytecode.add_step("order", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def otherV(self, *args):
     self.bytecode.add_step("otherV", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def out(self, *args):
     self.bytecode.add_step("out", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def outE(self, *args):
     self.bytecode.add_step("outE", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def outV(self, *args):
     self.bytecode.add_step("outV", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def pageRank(self, *args):
     self.bytecode.add_step("pageRank", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def path(self, *args):
     self.bytecode.add_step("path", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def peerPressure(self, *args):
     self.bytecode.add_step("peerPressure", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def profile(self, *args):
     self.bytecode.add_step("profile", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def program(self, *args):
     self.bytecode.add_step("program", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def project(self, *args):
     self.bytecode.add_step("project", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def properties(self, *args):
     self.bytecode.add_step("properties", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def property(self, *args):
     self.bytecode.add_step("property", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def propertyMap(self, *args):
     self.bytecode.add_step("propertyMap", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def range(self, *args):
     self.bytecode.add_step("range", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def repeat(self, *args):
     self.bytecode.add_step("repeat", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def sack(self, *args):
     self.bytecode.add_step("sack", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def sample(self, *args):
     self.bytecode.add_step("sample", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def select(self, *args):
     self.bytecode.add_step("select", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def sideEffect(self, *args):
     self.bytecode.add_step("sideEffect", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def simplePath(self, *args):
     self.bytecode.add_step("simplePath", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def store(self, *args):
     self.bytecode.add_step("store", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def subgraph(self, *args):
     self.bytecode.add_step("subgraph", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def sum(self, *args):
     self.bytecode.add_step("sum", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def tail(self, *args):
     self.bytecode.add_step("tail", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def timeLimit(self, *args):
     self.bytecode.add_step("timeLimit", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def times(self, *args):
     self.bytecode.add_step("times", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def to(self, *args):
     self.bytecode.add_step("to", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def toE(self, *args):
     self.bytecode.add_step("toE", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def toV(self, *args):
     self.bytecode.add_step("toV", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def tree(self, *args):
     self.bytecode.add_step("tree", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def unfold(self, *args):
     self.bytecode.add_step("unfold", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def union(self, *args):
     self.bytecode.add_step("union", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def until(self, *args):
     self.bytecode.add_step("until", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def value(self, *args):
     self.bytecode.add_step("value", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def valueMap(self, *args):
     self.bytecode.add_step("valueMap", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def values(self, *args):
     self.bytecode.add_step("values", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
   def where(self, *args):
     self.bytecode.add_step("where", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
     return self
 
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
index 1d9aa18..3703e5d 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
@@ -28,7 +28,6 @@ class Traversal(object):
         self.side_effects = {}
         self.traversers = None
         self.last_traverser = None
-        self.bindings = {}
 
     def __repr__(self):
         return str(self.bytecode)
@@ -297,6 +296,7 @@ class Bytecode(object):
     def __init__(self, bytecode=None):
         self.source_instructions = []
         self.step_instructions = []
+        self.bindings = {}
         if bytecode is not None:
             self.source_instructions = list(bytecode.source_instructions)
             self.step_instructions = list(bytecode.step_instructions)
@@ -304,20 +304,33 @@ class Bytecode(object):
     def add_source(self, source_name, *args):
         newArgs = ()
         for arg in args:
-            newArgs = newArgs + (Bytecode.__convertArgument(arg),)
+            newArgs = newArgs + (self.__convertArgument(arg),)
         self.source_instructions.append((source_name, newArgs))
         return
 
     def add_step(self, step_name, *args):
         newArgs = ()
         for arg in args:
-            newArgs = newArgs + (Bytecode.__convertArgument(arg),)
+            newArgs = newArgs + (self.__convertArgument(arg),)
         self.step_instructions.append((step_name, newArgs))
         return
 
-    @staticmethod
-    def __convertArgument(arg):
+    def __convertArgument(self,arg):
         if isinstance(arg, Traversal):
+            self.bindings.update(arg.bytecode.bindings)
             return arg.bytecode
+        elif isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
+            self.bindings[arg[0]] = arg[1]
+            return Binding(arg[0],arg[1])
         else:
             return arg
+
+'''
+BINDING
+'''
+
+class Binding(object):
+    def __init__(self,variable,value):
+        self.variable = variable
+        self.value = value
+

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/java/translator/RemoteGraphGroovyTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/java/translator/RemoteGraphGroovyTranslatorProvider.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/java/translator/RemoteGraphGroovyTranslatorProvider.java
index d7c2399..074e220 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/java/translator/RemoteGraphGroovyTranslatorProvider.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/java/translator/RemoteGraphGroovyTranslatorProvider.java
@@ -20,6 +20,7 @@
 package org.apache.tinkerpop.gremlin.java.translator;
 
 import org.apache.tinkerpop.gremlin.driver.remote.RemoteGraphProvider;
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e50f62c1/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphGroovyTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphGroovyTranslatorProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphGroovyTranslatorProvider.java
index aa84ff0..b5f6b1d 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphGroovyTranslatorProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphGroovyTranslatorProvider.java
@@ -20,6 +20,7 @@
 package org.apache.tinkerpop.gremlin.java.translator;
 
 import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionComputerTest;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;