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/10/06 17:35:40 UTC

[7/8] tinkerpop git commit: so many bug fixes in the GLV/Translator world. So many more tests added. We are now testing translators against all the strategies (save Evenstrategy cause it requires Java objects). This is really becoming clean.

so many bug fixes in the GLV/Translator world. So many more tests added. We are now testing translators against all the strategies (save Evenstrategy cause it requires Java objects). This is really becoming clean.


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

Branch: refs/heads/master
Commit: 894ff3dc0ccae16dae2fa314684aff7bbbcc139a
Parents: 3e4075b
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Oct 6 10:07:15 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Oct 6 10:07:15 2016 -0600

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              | 11 +++-
 .../upgrade/release-3.2.x-incubating.asciidoc   | 63 +++++++++++++-----
 .../gremlin/jsr223/JavaTranslator.java          | 22 ++++++-
 .../gremlin/process/computer/Computer.java      | 22 ++++++-
 .../gremlin/process/traversal/Bindings.java     |  5 ++
 .../gremlin/process/traversal/Bytecode.java     | 69 +++++++++++++-------
 .../process/traversal/TraversalStrategy.java    | 12 ++++
 .../strategy/decoration/ElementIdStrategy.java  | 27 +++++---
 .../decoration/HaltedTraverserStrategy.java     | 12 ++++
 .../strategy/decoration/PartitionStrategy.java  | 18 ++++-
 .../strategy/decoration/SubgraphStrategy.java   | 27 ++++++--
 .../finalization/MatchAlgorithmStrategy.java    | 24 +++++++
 .../StandardVerificationStrategy.java           |  2 +-
 .../gremlin/jsr223/JavaTranslatorTest.java      | 68 +++++++++++++++++++
 .../gremlin/process/traversal/BytecodeTest.java | 42 ++++++++++++
 .../dsl/graph/GraphTraversalSourceTest.java     |  2 +-
 .../gremlin/groovy/jsr223/GroovyTranslator.java | 20 ++++--
 .../python/TraversalSourceGenerator.groovy      | 17 ++++-
 .../gremlin/python/jsr223/PythonTranslator.java | 19 ++++--
 .../jython/gremlin_python/process/traversal.py  | 17 ++++-
 .../gremlin_python/structure/io/graphson.py     |  5 +-
 .../TinkerGraphGroovyTranslatorProvider.java    |  3 +
 .../TinkerGraphJavaTranslatorProvider.java      |  3 +
 23 files changed, 429 insertions(+), 81 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index f25e095..7ec7d15 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,10 +26,15 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 TinkerPop 3.2.3 (Release Date: NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-* Fixed a `String` bug in `GroovyTranslator` and `PythonTranslator` where if the string has double-quotes, use """ """.
-* Fixed a `List` and `Map` bug in `JavaTranslator` where such collections were not being internally translated.
+* Fixed a `Set`, `List`, `Map` bug in the various `Translators` where such collections were not being internally translated.
+* Fixed a `Bytecode` bug where nested structures (map, list, set) were not being analyzed for bindings and bytecode conversions.
+* Fixed a `String` bug in `GroovyTranslator` and `PythonTranslator` where if the string has double-quotes it now uses """ """.
+* Added a default `TraversalStrategy.getConfiguration()` which returns the configuration needed to construct the strategy.
+* Gremlin-Java `TraversalStrategy` and `Computer` instances are now converted to `Map`-representations in `Bytecode`.
+* `Computer` instances can be created with `Computer.create(Configuration)` and accessed via `Computer.getConf()`.
+* Every `TraversalStrategy` can be created via a `Configuration` and a static `MyStrategy.create(Configuration)`.
 * Added `TraversalSource.withComputer(Map<String,Object>)` for better language variant support.
-* Added `TraversalSource.withStrategies(Map<String,Object>)`/`withoutStrategies(String...)` for better language variant support.
+* Added `TraversalSource.withStrategies(Map<String,Object>...)`/`withoutStrategies(String...)` for better language variant support.
 * Added `PartitionStrategy.Builder.readPartitions()` and deprecated `PartitionStrategy.Builder.addPartition()`.
 * `FilterRankStrategy` now propagates labels "right" over non-`Scoping` filters.
 * Fixed a bug in `ConnectiveP` where nested equivalent connectives should be inlined.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index 983c63e..5fbf4fe 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -163,7 +163,7 @@ Configurable Strategies
 
 `TraversalSource.withStrategies()` and `TraversalSource.withoutStrategies()` use Java objects. In order to make strategy
 manipulation possible from Gremlin language variants like Gremlin-Python, it is important to support non-JVM-based versions
-of these methods. As such, `TraversalSource.withStrategy(String,Object...)` and `TraversalSource.withoutStrategy(String)`
+of these methods. As such, `TraversalSource.withStrategies(Map<String,Object>...)` and `TraversalSource.withoutStrategies(String...)`
 were added.
 
 If the provider has non-configurable `TraversalStrategy` classes, those classes should expose a static `instance()`-method.
@@ -175,31 +175,60 @@ a `SubgraphStrategy`, it does the following:
 [source,python]
 ----
 g = Graph().traversal().withRemote(connection).
-        withStrategy('org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy',
-            'vertices', __.hasLabel('person'),
-            'edges', __.has('weight',gt(0.5))
+        withStrategy({'strategy':'org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy',
+            'vertices': __.hasLabel('person'),
+            'edges': __.has('weight',gt(0.5))})
 ---
 
-`SubgraphStrategy.create(Configuration)`-method is defined as:
+The `SubgraphStrategy.create(Configuration)`-method is defined as:
 
 [source,java]
 ----
 public static SubgraphStrategy create(final Configuration configuration) {
     final Builder builder = SubgraphStrategy.build();
-    configuration.getKeys().forEachRemaining(key -> {
-        if (key.equals("vertices") || key.equals("vertexCriterion"))
-            builder.vertices((Traversal) configuration.getProperty(key));
-        else if (key.equals("edges") || key.equals("edgeCriterion"))
-            builder.edges((Traversal) configuration.getProperty(key));
-        else if (key.equals("vertexProperties"))
-            builder.vertexProperties((Traversal) configuration.getProperty(key));
-        else
-            throw new IllegalArgumentException("The following " + SubgraphStrategy.class.getSimpleName() + " configuration is unknown: " + key + ":" + configuration.getProperty(key));
-        });
-        return builder.create();
-    }
+    if (configuration.containsKey(VERTICES))
+        builder.vertices((Traversal) configuration.getProperty(VERTICES));
+    if (configuration.containsKey(EDGES))
+        builder.edges((Traversal) configuration.getProperty(EDGES));
+    if (configuration.containsKey(VERTEX_PROPERTIES))
+        builder.vertexProperties((Traversal) configuration.getProperty(VERTEX_PROPERTIES));
+    return builder.create();
+}
+----
+
+Finally, in order to make serialization possible from JVM-based Gremlin language variants, all strategies have a
+`TraverserStrategy.getConfiguration()` method which returns a `Configuration` that can be used to `create()` the
+`TraversalStrategy`.
+
+The `SubgraphStrategy.getConfiguration()`-method is defined as:
+
+[source,java]
+----
+@Override
+public Configuration getConfiguration() {
+    final Map<String, Object> map = new HashMap<>();
+    map.put(STRATEGY, SubgraphStrategy.class.getCanonicalName());
+    if (null != this.vertexCriterion)
+        map.put(VERTICES, this.vertexCriterion);
+    if (null != this.edgeCriterion)
+            map.put(EDGES, this.edgeCriterion);
+    if (null != this.vertexPropertyCriterion)
+        map.put(VERTEX_PROPERTIES, this.vertexPropertyCriterion);
+    return new MapConfiguration(map);
+}
 ----
 
+The default implementation of `TraversalStrategy.getConfiguration()` is defined as:
+
+[source,java]
+----
+public default Configuration getConfiguration() {
+    return new MapConfiguration(Collections.singletonMap(STRATEGY, this.getClass().getCanonicalName()));
+}
+----
+
+Thus, if the provider does not have any "builder"-based strategies, then no updates to their strategies are required.
+
 See: link:https://issues.apache.org/jira/browse/TINKERPOP-1455[TINKERPOP-1455]
 
 Deprecated elementNotFound

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java
index af245c5..d1e974d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 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.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
 import java.lang.reflect.Array;
@@ -31,8 +32,11 @@ import java.lang.reflect.Parameter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -40,6 +44,8 @@ import java.util.concurrent.ConcurrentHashMap;
  */
 public final class JavaTranslator<S extends TraversalSource, T extends Traversal.Admin<?, ?>> implements Translator.StepTranslator<S, T> {
 
+    private static final boolean IS_TESTING = Boolean.valueOf(System.getProperty("is.testing", "false"));
+
     private final S traversalSource;
     private final Class anonymousTraversal;
     private static final Map<Class<?>, Map<String, List<Method>>> GLOBAL_METHOD_CACHE = new ConcurrentHashMap<>();
@@ -64,6 +70,10 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
         TraversalSource dynamicSource = this.traversalSource;
         Traversal.Admin<?, ?> traversal = null;
         for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
+            if (IS_TESTING &&
+                    instruction.getOperator().equals(TraversalSource.Symbols.withStrategies) &&
+                    ((Map) instruction.getArguments()[0]).get(TraversalStrategy.STRATEGY).toString().contains("TranslationStrategy"))
+                continue;
             dynamicSource = (TraversalSource) invokeMethod(dynamicSource, TraversalSource.class, instruction.getOperator(), instruction.getArguments());
         }
         boolean spawned = false;
@@ -91,7 +101,7 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
 
     private Object translateObject(final Object object) {
         if (object instanceof Bytecode.Binding)
-            return ((Bytecode.Binding) object).value();
+            return translateObject(((Bytecode.Binding) object).value());
         else if (object instanceof Bytecode) {
             try {
                 final Traversal.Admin<?, ?> traversal = (Traversal.Admin) this.anonymousTraversal.getMethod("start").invoke(null);
@@ -103,17 +113,23 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal
                 throw new IllegalStateException(e.getMessage());
             }
         } else if (object instanceof Map) {
-            final Map<Object, Object> map = new HashMap<>(((Map) object).size());
+            final Map<Object, Object> map = new LinkedHashMap<>(((Map) object).size());
             for (final Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
                 map.put(translateObject(entry.getKey()), translateObject(entry.getValue()));
             }
             return map;
         } else if (object instanceof List) {
-            final List<Object> list = new ArrayList<>();
+            final List<Object> list = new ArrayList<>(((List) object).size());
             for (final Object o : (List) object) {
                 list.add(translateObject(o));
             }
             return list;
+        } else if (object instanceof Set) {
+            final Set<Object> set = new HashSet<>(((Set) object).size());
+            for (final Object o : (Set) object) {
+                set.add(translateObject(o));
+            }
+            return set;
         } else
             return object;
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java
index e06a62a..86e1a12 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/computer/Computer.java
@@ -20,6 +20,7 @@
 package org.apache.tinkerpop.gremlin.process.computer;
 
 import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -65,7 +66,7 @@ public final class Computer implements Function<Graph, GraphComputer>, Serializa
             final Computer computer = new Computer();
             for (final String key : (List<String>) IteratorUtils.asList(configuration.getKeys())) {
                 if (key.equals(GRAPH_COMPUTER))
-                    computer.graphComputerClass = (Class) Class.forName(configuration.getString("graphComputer"));
+                    computer.graphComputerClass = (Class) Class.forName(configuration.getString(key));
                 else if (key.equals(WORKERS))
                     computer.workers = configuration.getInt(key);
                 else if (key.equals(PERSIST))
@@ -198,4 +199,23 @@ public final class Computer implements Function<Graph, GraphComputer>, Serializa
     public int getWorkers() {
         return this.workers;
     }
+
+    public Configuration getConf() {
+        final Map<String, Object> map = new HashMap<>();
+        if (-1 != this.workers)
+            map.put(WORKERS, this.workers);
+        if (null != this.persist)
+            map.put(PERSIST, this.persist.name());
+        if (null != this.resultGraph)
+            map.put(RESULT, this.resultGraph.name());
+        if (null != this.vertices)
+            map.put(RESULT, this.vertices);
+        if (null != this.edges)
+            map.put(EDGES, this.edges);
+        map.put(GRAPH_COMPUTER, this.graphComputerClass.getCanonicalName());
+        for (final Map.Entry<String, Object> entry : this.configuration.entrySet()) {
+            map.put(entry.getKey(), entry.getValue());
+        }
+        return new MapConfiguration(map);
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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
index ca830f1..ba31e21 100644
--- 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
@@ -55,4 +55,9 @@ public final class Bindings {
     protected void clear() {
         this.map.clear();
     }
+
+    @Override
+    public String toString() {
+        return this.map.toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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 9443064..f331d50 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
@@ -19,6 +19,8 @@
 
 package org.apache.tinkerpop.gremlin.process.traversal;
 
+import org.apache.commons.configuration.ConfigurationConverter;
+import org.apache.tinkerpop.gremlin.process.computer.Computer;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
@@ -44,6 +46,8 @@ import java.util.Map;
  */
 public final class Bytecode implements Cloneable, Serializable {
 
+    private static final Object[] EMPTY_ARRAY = new Object[]{};
+
     private List<Instruction> sourceInstructions = new ArrayList<>();
     private List<Instruction> stepInstructions = new ArrayList<>();
     private transient Bindings bindings = null;
@@ -111,21 +115,32 @@ public final class Bytecode implements Cloneable, Serializable {
     public Map<String, Object> getBindings() {
         final Map<String, Object> bindingsMap = new HashMap<>();
         for (final Instruction instruction : this.sourceInstructions) {
-            addInstructionBindings(bindingsMap, instruction);
+            for (final Object argument : instruction.getArguments()) {
+                addArgumentBinding(bindingsMap, argument);
+            }
         }
         for (final Instruction instruction : this.stepInstructions) {
-            addInstructionBindings(bindingsMap, instruction);
+            for (final Object argument : instruction.getArguments()) {
+                addArgumentBinding(bindingsMap, argument);
+            }
         }
         return bindingsMap;
     }
 
-    private static final void addInstructionBindings(final Map<String, Object> bindingsMap, final Instruction instruction) {
-        for (final Object argument : instruction.getArguments()) {
-            if (argument instanceof Binding)
-                bindingsMap.put(((Binding) argument).key, ((Binding) argument).value);
-            else if (argument instanceof Bytecode)
-                bindingsMap.putAll(((Bytecode) argument).getBindings());
-        }
+    private static final void addArgumentBinding(final Map<String, Object> bindingsMap, final Object argument) {
+        if (argument instanceof Binding)
+            bindingsMap.put(((Binding) argument).key, ((Binding) argument).value);
+        else if (argument instanceof Map) {
+            for (final Map.Entry<?, ?> entry : ((Map<?, ?>) argument).entrySet()) {
+                addArgumentBinding(bindingsMap, entry.getKey());
+                addArgumentBinding(bindingsMap, entry.getValue());
+            }
+        } else if (argument instanceof List) {
+            for (final Object item : (List) argument) {
+                addArgumentBinding(bindingsMap, item);
+            }
+        } else if (argument instanceof Bytecode)
+            bindingsMap.putAll(((Bytecode) argument).getBindings());
     }
 
     @Override
@@ -234,35 +249,45 @@ public final class Bytecode implements Cloneable, Serializable {
 
     private final Object[] flattenArguments(final Object... arguments) {
         if (arguments.length == 0)
-            return new Object[]{};
+            return EMPTY_ARRAY;
         final List<Object> flatArguments = new ArrayList<>();
         for (final Object object : arguments) {
             if (object instanceof Object[]) {
                 for (final Object nestObject : (Object[]) object) {
-                    flatArguments.add(convertArgument(nestObject));
+                    flatArguments.add(convertArgument(nestObject, true));
                 }
             } else
-                flatArguments.add(convertArgument(object));
+                flatArguments.add(convertArgument(object, true));
         }
         return flatArguments.toArray();
     }
 
-    private final Object convertArgument(final Object argument) {
+    private final Object convertArgument(final Object argument, final boolean searchBindings) {
+        if (searchBindings && null != this.bindings) {
+            final String variable = this.bindings.getBoundVariable(argument);
+            if (null != variable)
+                return new Binding<>(variable, convertArgument(argument, false));
+        }
+        //
         if (argument instanceof Traversal)
             return ((Traversal) argument).asAdmin().getBytecode();
+        else if (argument instanceof TraversalStrategy)
+            return convertArgument(ConfigurationConverter.getMap(((TraversalStrategy) argument).getConfiguration()), true);
+        else if (argument instanceof Computer)
+            return convertArgument(ConfigurationConverter.getMap(((Computer) argument).getConf()), true);
         else if (argument instanceof Map) {
             final Map<Object, Object> map = new LinkedHashMap<>(((Map) argument).size());
             for (final Map.Entry<?, ?> entry : ((Map<?, ?>) argument).entrySet()) {
-                map.put(convertArgument(entry.getKey()), convertArgument(entry.getValue()));
+                map.put(convertArgument(entry.getKey(), true), convertArgument(entry.getValue(), true));
             }
             return map;
-        }
-        if (null != this.bindings) {
-            final String variable = this.bindings.getBoundVariable(argument);
-            if (null != variable)
-                return new Binding<>(variable, argument);
-        }
-
-        return argument;
+        } else if (argument instanceof List) {
+            final List<Object> list = new ArrayList<>(((List) argument).size());
+            for (final Object item : (List) argument) {
+                list.add(convertArgument(item, true));
+            }
+            return list;
+        } else
+            return argument;
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java
index a04f304..7943624 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal;
 
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.ProfileStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RangeByIsCountStrategy;
@@ -76,6 +78,16 @@ public interface TraversalStrategy<S extends TraversalStrategy> extends Serializ
         return (Class) TraversalStrategy.class;
     }
 
+    /**
+     * Get the configuration representation of this strategy.
+     * This is useful for converting a strategy into a serialized form.
+     *
+     * @return the configuration used to create this strategy
+     */
+    public default Configuration getConfiguration() {
+        return new MapConfiguration(Collections.singletonMap(STRATEGY, this.getClass().getCanonicalName()));
+    }
+
     @Override
     public default int compareTo(final Class<? extends TraversalStrategy> otherTraversalCategory) {
         return 0;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
index 396de49..32437e1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java
@@ -19,6 +19,7 @@
 package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 
 import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
@@ -40,6 +41,8 @@ import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.UUID;
 import java.util.function.Supplier;
 
@@ -152,16 +155,24 @@ public final class ElementIdStrategy extends AbstractTraversalStrategy<Traversal
         }
     }
 
+    public static final String ID_PROPERTY_KEY = "idPropertyKey";
+    public static final String ID_MAKER = "idMaker";
+
     public static ElementIdStrategy create(final Configuration configuration) {
         final ElementIdStrategy.Builder builder = ElementIdStrategy.build();
-        configuration.getKeys().forEachRemaining(key -> {
-            if (key.equals("idPropertyKey"))
-                builder.idPropertyKey((String) configuration.getProperty(key));
-            else if (key.equals("idMaker"))
-                builder.idMaker((Supplier) configuration.getProperty(key));
-            else
-                throw new IllegalArgumentException("The following " + ElementIdStrategy.class.getSimpleName() + " configuration is unknown: " + key + ":" + configuration.getProperty(key));
-        });
+        if (configuration.containsKey(ID_MAKER))
+            builder.idMaker((Supplier) configuration.getProperty(ID_MAKER));
+        if (configuration.containsKey(ID_PROPERTY_KEY))
+            builder.idPropertyKey(configuration.getString(ID_PROPERTY_KEY));
         return builder.create();
     }
+
+    @Override
+    public Configuration getConfiguration() {
+        final Map<String, Object> map = new HashMap<>();
+        map.put(STRATEGY, ElementIdStrategy.class.getCanonicalName());
+        map.put(ID_PROPERTY_KEY, this.idPropertyKey);
+        map.put(ID_MAKER, this.idMaker);
+        return new MapConfiguration(map);
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
index ee1f017..3f02c40 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
@@ -20,6 +20,7 @@
 package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 
 import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
@@ -27,6 +28,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversal
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
 import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
@@ -69,6 +73,14 @@ public final class HaltedTraverserStrategy extends AbstractTraversalStrategy<Tra
         }
     }
 
+    @Override
+    public Configuration getConfiguration() {
+        final Map<String, Object> map = new HashMap<>();
+        map.put(STRATEGY, HaltedTraverserStrategy.class.getCanonicalName());
+        map.put(HALTED_TRAVERSER_FACTORY, this.haltedTraverserFactory.getCanonicalName());
+        return new MapConfiguration(map);
+    }
+
     ////////////
 
     public static HaltedTraverserStrategy detached() {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
index 2ee4bf3..438d8b2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/PartitionStrategy.java
@@ -19,6 +19,7 @@
 package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 
 import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
@@ -55,6 +56,7 @@ import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -324,6 +326,20 @@ public final class PartitionStrategy extends AbstractTraversalStrategy<Traversal
         }
     }
 
+    @Override
+    public Configuration getConfiguration() {
+        final Map<String, Object> map = new HashMap<>();
+        map.put(STRATEGY, PartitionStrategy.class.getCanonicalName());
+        map.put(INCLUDE_META_PROPERTIES, this.includeMetaProperties);
+        if (null != this.writePartition)
+            map.put(WRITE_PARTITION, this.writePartition);
+        if (null != this.readPartitions)
+            map.put(READ_PARTITIONS, this.readPartitions);
+        if (null != this.partitionKey)
+            map.put(PARTITION_KEY, this.partitionKey);
+        return new MapConfiguration(map);
+    }
+
     public static final String INCLUDE_META_PROPERTIES = "includeMetaProperties";
     public static final String WRITE_PARTITION = "writePartition";
     public static final String PARTITION_KEY = "partitionKey";
@@ -338,7 +354,7 @@ public final class PartitionStrategy extends AbstractTraversalStrategy<Traversal
         if (configuration.containsKey(PARTITION_KEY))
             builder.partitionKey(configuration.getString(PARTITION_KEY));
         if (configuration.containsKey(READ_PARTITIONS))
-            builder.readPartitions((List) configuration.getList(READ_PARTITIONS));
+            builder.readPartitions(new ArrayList((Collection)configuration.getProperty(READ_PARTITIONS)));
         return builder.create();
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
index d7269aa..e612bee 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
@@ -19,6 +19,7 @@
 package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 
 import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
@@ -54,9 +55,10 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -78,15 +80,15 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
 
     private static final Set<Class<? extends DecorationStrategy>> POSTS = Collections.singleton(ConnectiveStrategy.class);
 
-    private final String MARKER = Graph.Hidden.hide(UUID.randomUUID().toString());
+    private final String MARKER = Graph.Hidden.hide("gremlin.subgraphStrategy");
 
     private SubgraphStrategy(final Traversal<Vertex, ?> vertexCriterion, final Traversal<Edge, ?> edgeCriterion, final Traversal<VertexProperty, ?> vertexPropertyCriterion) {
 
-        this.vertexCriterion = null == vertexCriterion ? null : vertexCriterion.asAdmin();
+        this.vertexCriterion = null == vertexCriterion ? null : vertexCriterion.asAdmin().clone();
 
         // if there is no vertex predicate there is no need to test either side of the edge
         if (null == this.vertexCriterion) {
-            this.edgeCriterion = null == edgeCriterion ? null : edgeCriterion.asAdmin();
+            this.edgeCriterion = null == edgeCriterion ? null : edgeCriterion.asAdmin().clone();
         } else {
             final Traversal.Admin<Edge, ?> vertexPredicate;
             vertexPredicate = __.<Edge>and(
@@ -97,10 +99,10 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
             // edge predicate provided by the user.
             this.edgeCriterion = null == edgeCriterion ?
                     vertexPredicate :
-                    edgeCriterion.asAdmin().addStep(new TraversalFilterStep<>(edgeCriterion.asAdmin(), vertexPredicate));
+                    edgeCriterion.asAdmin().clone().addStep(new TraversalFilterStep<>(edgeCriterion.asAdmin(), vertexPredicate));
         }
 
-        this.vertexPropertyCriterion = null == vertexPropertyCriterion ? null : vertexPropertyCriterion.asAdmin();
+        this.vertexPropertyCriterion = null == vertexPropertyCriterion ? null : vertexPropertyCriterion.asAdmin().clone();
 
         if (null != this.vertexCriterion)
             this.addLabelMarker(this.vertexCriterion);
@@ -275,6 +277,19 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
     }
 
     @Override
+    public Configuration getConfiguration() {
+        final Map<String, Object> map = new HashMap<>();
+        map.put(STRATEGY, SubgraphStrategy.class.getCanonicalName());
+        if (null != this.vertexCriterion)
+            map.put(VERTICES, this.vertexCriterion);
+        if (null != this.edgeCriterion)
+            map.put(EDGES, this.edgeCriterion);
+        if (null != this.vertexPropertyCriterion)
+            map.put(VERTEX_PROPERTIES, this.vertexPropertyCriterion);
+        return new MapConfiguration(map);
+    }
+
+    @Override
     public Set<Class<? extends DecorationStrategy>> applyPost() {
         return POSTS;
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
index be31575..7b78295 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization;
 
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
@@ -25,11 +27,15 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class MatchAlgorithmStrategy extends AbstractTraversalStrategy<TraversalStrategy.FinalizationStrategy> implements TraversalStrategy.FinalizationStrategy {
 
+    private static final String MATCH_ALGORITHM = "matchAlgorithm";
     private final Class<? extends MatchStep.MatchAlgorithm> matchAlgorithmClass;
 
     private MatchAlgorithmStrategy(final Class<? extends MatchStep.MatchAlgorithm> matchAlgorithmClass) {
@@ -45,6 +51,24 @@ public final class MatchAlgorithmStrategy extends AbstractTraversalStrategy<Trav
         }
     }
 
+    public static MatchAlgorithmStrategy create(final Configuration configuration) {
+        try {
+            return new MatchAlgorithmStrategy((Class) Class.forName(configuration.getString(MATCH_ALGORITHM)));
+        } catch (final ClassNotFoundException e) {
+            throw new IllegalArgumentException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public Configuration getConfiguration() {
+        final Map<String, Object> map = new HashMap<>();
+        map.put(STRATEGY, MatchAlgorithmStrategy.class.getCanonicalName());
+        map.put(MATCH_ALGORITHM, null != this.matchAlgorithmClass.getDeclaringClass() ?
+                this.matchAlgorithmClass.getCanonicalName().replace("." + this.matchAlgorithmClass.getSimpleName(), "$" + this.matchAlgorithmClass.getSimpleName()) :
+                this.matchAlgorithmClass.getCanonicalName());
+        return new MapConfiguration(map);
+    }
+
     public static Builder build() {
         return new Builder();
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
index 9f7f516..f72de50 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
@@ -53,7 +53,7 @@ public final class StandardVerificationStrategy extends AbstractTraversalStrateg
         }
 
         for (final Step<?, ?> step : traversal.getSteps()) {
-            for (String label : new ArrayList<>(step.getLabels())) {
+            for (String label : step.getLabels()) {
                 if (Graph.Hidden.isHidden(label))
                     step.removeLabel(label);
             }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslatorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslatorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslatorTest.java
new file mode 100644
index 0000000..ac8a645
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslatorTest.java
@@ -0,0 +1,68 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.jsr223;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Bindings;
+import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class JavaTranslatorTest {
+
+    @Test
+    public void shouldTranslateNestedBindings() {
+        final Bindings b = new Bindings();
+        final GraphTraversalSource g = EmptyGraph.instance().traversal().withBindings(b);
+
+        final Bytecode bytecode = g.withStrategies(new HashMap<String, Object>() {{
+            put(SubgraphStrategy.STRATEGY, SubgraphStrategy.class.getCanonicalName());
+            put(SubgraphStrategy.VERTICES, b.of("a", __.has("name", "marko")));
+        }}).V().out(b.of("b", "created")).asAdmin().getBytecode();
+
+        Traversal.Admin<?, ?> traversal = JavaTranslator.of(EmptyGraph.instance().traversal()).translate(bytecode);
+        assertFalse(traversal.isLocked());
+        assertEquals(2, traversal.getSteps().size());
+        // assertEquals(traversal.getBytecode(),bytecode); TODO: bindings are removed -- should translated bytecode be the same bytecode?!
+        traversal.applyStrategies();
+        assertEquals(5, TraversalHelper.getStepsOfAssignableClassRecursively(TraversalFilterStep.class, traversal).size());
+
+        // JavaTranslator should not mutate original bytecode
+        assertTrue(bytecode.getBindings().containsKey("a"));
+        assertTrue(bytecode.getBindings().containsKey("b"));
+        assertEquals(2, bytecode.getBindings().size());
+        assertEquals(__.has("name", "marko").asAdmin().getBytecode(), bytecode.getBindings().get("a"));
+        assertEquals("created", bytecode.getBindings().get("b"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java
index 0b9c65a..6093dae 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/BytecodeTest.java
@@ -19,15 +19,24 @@
 
 package org.apache.tinkerpop.gremlin.process.traversal;
 
+import org.apache.commons.configuration.ConfigurationConverter;
+import org.apache.tinkerpop.gremlin.process.computer.Computer;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
 import org.apache.tinkerpop.gremlin.structure.Column;
 import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.junit.Test;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -92,6 +101,39 @@ public class BytecodeTest {
 
         assertEquals(1, bytecode1.getBindings().size());
         assertEquals("created", bytecode1.getBindings().get("a"));
+    }
+
+    @Test
+    public void shouldSupportNestedBindings() {
+        final Bindings b = new Bindings();
+        final GraphTraversalSource g = EmptyGraph.instance().traversal().withBindings(b);
 
+        final Bytecode bytecode = g.withStrategies(new HashMap<String, Object>() {{
+            put(SubgraphStrategy.STRATEGY, SubgraphStrategy.class.getCanonicalName());
+            put(SubgraphStrategy.VERTICES, b.of("a", __.has("name", "marko")));
+        }}).V().out(b.of("b", "created")).asAdmin().getBytecode();
+
+        assertTrue(bytecode.getBindings().containsKey("a"));
+        assertTrue(bytecode.getBindings().containsKey("b"));
+        assertEquals(2, bytecode.getBindings().size());
+        assertEquals(__.has("name", "marko").asAdmin().getBytecode(), bytecode.getBindings().get("a"));
+        assertEquals("created", bytecode.getBindings().get("b"));
+    }
+
+    @Test
+    public void shouldConvertStrategies() {
+        final GraphTraversalSource g = EmptyGraph.instance().traversal();
+        Bytecode bytecode = g.withStrategies(ReadOnlyStrategy.instance()).getBytecode();
+        assertEquals(Collections.singletonMap(ReadOnlyStrategy.STRATEGY, ReadOnlyStrategy.class.getCanonicalName()), bytecode.getSourceInstructions().iterator().next().getArguments()[0]);
+        bytecode = g.withStrategies(SubgraphStrategy.build().edges(__.hasLabel("knows")).create()).getBytecode();
+        assertEquals(SubgraphStrategy.build().edges(__.hasLabel("knows")).create().getEdgeCriterion().asAdmin().getBytecode(),
+                ((Map) bytecode.getSourceInstructions().iterator().next().getArguments()[0]).get(SubgraphStrategy.EDGES));
+    }
+
+    @Test
+    public void shouldConvertComputer() {
+        final GraphTraversalSource g = EmptyGraph.instance().traversal();
+        Bytecode bytecode = g.withComputer(Computer.compute().workers(10)).getBytecode();
+        assertEquals(ConfigurationConverter.getMap(Computer.compute().workers(10).getConf()), bytecode.getSourceInstructions().iterator().next().getArguments()[0]);
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java
index 6efa4b5..457747d 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSourceTest.java
@@ -59,7 +59,7 @@ public class GraphTraversalSourceTest {
     }
 
     @Test
-    public void shouldSupportStringBasedStrategies() throws Exception {
+    public void shouldSupportMapBasedStrategies() throws Exception {
         GraphTraversalSource g = EmptyGraph.instance().traversal();
         assertFalse(g.getStrategies().getStrategy(SubgraphStrategy.class).isPresent());
         g = g.withStrategies(new HashMap<String, Object>() {{

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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
index 59a07b3..154c4a1 100644
--- 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
@@ -24,8 +24,8 @@ 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.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
 import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
 import org.apache.tinkerpop.gremlin.structure.Element;
@@ -34,8 +34,10 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -82,7 +84,9 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
         final StringBuilder traversalScript = new StringBuilder(start);
         for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
             final String methodName = instruction.getOperator();
-            if (IS_TESTING && methodName.equals(TraversalSource.Symbols.withStrategies))
+            if (IS_TESTING &&
+                    instruction.getOperator().equals(TraversalSource.Symbols.withStrategies) &&
+                    ((Map) instruction.getArguments()[0]).get(TraversalStrategy.STRATEGY).toString().contains("TranslationStrategy"))
                 continue;
             if (0 == instruction.getArguments().length)
                 traversalScript.append(".").append(methodName).append("()");
@@ -103,7 +107,13 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
             return ((Bytecode.Binding) object).variable();
         else if (object instanceof String)
             return ((String) object).contains("\"") ? "\"\"\"" + object + "\"\"\"" : "\"" + object + "\"";
-        else if (object instanceof List) {
+        else if (object instanceof Set) {
+            final Set<String> set = new HashSet<>(((Set) object).size());
+            for (final Object item : (Set) object) {
+                set.add(convertToString(item));
+            }
+            return set.toString() + " as Set";
+        } else if (object instanceof List) {
             final List<String> list = new ArrayList<>(((List) object).size());
             for (final Object item : (List) object) {
                 list.add(convertToString(item));
@@ -139,15 +149,11 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
             return ((Enum) object).getDeclaringClass().getSimpleName() + "." + object.toString();
         else if (object instanceof Element)
             return convertToString(((Element) object).id()); // hack
-        else if (object instanceof Computer)
-            return "";
         else if (object instanceof Lambda) {
             final String lambdaString = ((Lambda) object).getLambdaScript().trim();
             return lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}";
         } else if (object instanceof Bytecode)
             return this.internalTranslate("__", (Bytecode) object);
-        else if (object instanceof Traversal)
-            return this.internalTranslate("__", ((Traversal) object).asAdmin().getBytecode());
         else
             return null == object ? "null" : object.toString();
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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 e12c2cd..fe62685 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
@@ -254,9 +254,24 @@ class Bytecode(object):
         if isinstance(arg, Traversal):
             self.bindings.update(arg.bytecode.bindings)
             return arg.bytecode
+        elif isinstance(arg, dict):
+            newDict = {}
+            for key in arg:
+                newDict[self.__convertArgument(key)] = self.__convertArgument(arg[key])
+            return newDict
+        elif isinstance(arg, list):
+            newList = []
+            for item in arg:
+                newList.append(self.__convertArgument(item))
+            return newList
+        elif isinstance(arg, set):
+            newSet = set()
+            for item in arg:
+                newSet.add(self.__convertArgument(item))
+            return newSet
         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])
+            return Binding(arg[0],self.__convertArgument(arg[1]))
         else:
             return arg
     def __repr__(self):

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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 65042ab..4bfdc45 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
@@ -19,7 +19,6 @@
 
 package org.apache.tinkerpop.gremlin.python.jsr223;
 
-import org.apache.tinkerpop.gremlin.process.computer.Computer;
 import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 import org.apache.tinkerpop.gremlin.process.traversal.Operator;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
@@ -27,6 +26,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
 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.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
 import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
@@ -42,6 +42,7 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -103,7 +104,9 @@ public class PythonTranslator implements Translator.ScriptTranslator {
         for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
             final String methodName = instruction.getOperator();
             final Object[] arguments = instruction.getArguments();
-            if (IS_TESTING && methodName.equals(TraversalSource.Symbols.withStrategies) && !(instruction.getArguments()[0] instanceof Map))
+            if (IS_TESTING &&
+                    instruction.getOperator().equals(TraversalSource.Symbols.withStrategies) &&
+                    ((Map) instruction.getArguments()[0]).get(TraversalStrategy.STRATEGY).toString().contains("TranslationStrategy"))
                 continue;
             else if (0 == arguments.length)
                 traversalScript.append(".").append(SymbolHelper.toPython(methodName)).append("()");
@@ -135,7 +138,13 @@ public class PythonTranslator implements Translator.ScriptTranslator {
             return ((Bytecode.Binding) object).variable();
         else if (object instanceof String)
             return ((String) object).contains("\"") ? "\"\"\"" + object + "\"\"\"" : "\"" + object + "\"";
-        else if (object instanceof List) {
+        else if (object instanceof Set) {
+            final Set<String> set = new LinkedHashSet<>(((Set) object).size());
+            for (final Object item : (Set) object) {
+                set.add(convertToString(item));
+            }
+            return "set(" + set.toString() + ")";
+        } else if (object instanceof List) {
             final List<String> list = new ArrayList<>(((List) object).size());
             for (final Object item : (List) object) {
                 list.add(convertToString(item));
@@ -168,10 +177,6 @@ public class PythonTranslator implements Translator.ScriptTranslator {
             return convertToString(((Element) object).id()); // hack
         else if (object instanceof Bytecode)
             return this.internalTranslate("__", (Bytecode) object);
-        else if (object instanceof Traversal)
-            return this.internalTranslate("__", ((Traversal.Admin) object).asAdmin().getBytecode());
-        else if (object instanceof Computer)
-            return "";
         else if (object instanceof Lambda)
             return convertLambdaToString((Lambda) object);
         else

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/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 4c2f3b9..aa36869 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
@@ -313,9 +313,24 @@ class Bytecode(object):
         if isinstance(arg, Traversal):
             self.bindings.update(arg.bytecode.bindings)
             return arg.bytecode
+        elif isinstance(arg, dict):
+            newDict = {}
+            for key in arg:
+                newDict[self.__convertArgument(key)] = self.__convertArgument(arg[key])
+            return newDict
+        elif isinstance(arg, list):
+            newList = []
+            for item in arg:
+                newList.append(self.__convertArgument(item))
+            return newList
+        elif isinstance(arg, set):
+            newSet = set()
+            for item in arg:
+                newSet.add(self.__convertArgument(item))
+            return newSet
         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])
+            return Binding(arg[0],self.__convertArgument(arg[1]))
         else:
             return arg
     def __repr__(self):

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
index a032032..7899925 100644
--- a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
+++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
@@ -47,7 +47,7 @@ class GraphSONWriter(object):
             if isinstance(object, key):
                 return serializers[key]._dictify(object)
         # list and map are treated as normal json objects (could be isolated serializers)
-        if isinstance(object, list):
+        if isinstance(object, list) or isinstance(object, set):
             newList = []
             for item in object:
                 newList.append(GraphSONWriter._dictify(item))
@@ -181,7 +181,8 @@ class NumberSerializer(GraphSONSerializer):
     def _dictify(self, number):
         if isinstance(number, bool):  # python thinks that 0/1 integers are booleans
             return number
-        elif isinstance(number, long) or (abs(number) > 2147483647): # in python all numbers are int unless specified otherwise
+        elif isinstance(number, long) or (
+                    abs(number) > 2147483647):  # in python all numbers are int unless specified otherwise
             return _SymbolHelper.objectify("Int64", number)
         elif isinstance(number, int):
             return _SymbolHelper.objectify("Int32", number)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
index 7591bf0..c086c3a 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
@@ -27,6 +27,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategyProcessTest;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategy;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
@@ -52,6 +54,7 @@ public class TinkerGraphGroovyTranslatorProvider extends TinkerGraphProvider {
             ProgramTest.Traversals.class.getCanonicalName(),
             TraversalInterruptionTest.class.getCanonicalName(),
             TraversalInterruptionComputerTest.class.getCanonicalName(),
+            EventStrategyProcessTest.class.getCanonicalName(),
             ElementIdStrategyProcessTest.class.getCanonicalName()));
 
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/894ff3dc/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java
index 1e6645b..f40a8c7 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/jsr223/TinkerGraphJavaTranslatorProvider.java
@@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSo
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategyProcessTest;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategy;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
@@ -48,6 +49,8 @@ public class TinkerGraphJavaTranslatorProvider extends TinkerGraphProvider {
             TraversalInterruptionComputerTest.class.getCanonicalName(),
             "shouldNeverPropagateANoBulkTraverser",
             "shouldNeverPropagateANullValuedTraverser",
+            ElementIdStrategyProcessTest.class.getCanonicalName(),
+            EventStrategyProcessTest.class.getCanonicalName(),
             ProgramTest.Traversals.class.getCanonicalName()));