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 16:07:24 UTC

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.

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1455 3e4075bd0 -> 894ff3dc0


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/TINKERPOP-1455
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()));