TINKERPOP-1565 Stub out GraphSON 3.0

Set up the new testing model and generated test files. Reverted changes on 
property serialization that went in as breaking changes on GraphSON 2.0 and 
moved them forward to GraphSON 3.0.


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

Branch: refs/heads/master
Commit: 7db10c40cc143473eff78866d989a90df8da7206
Parents: a004162
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jan 12 14:58:50 2017 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jan 19 15:15:33 2017 -0500

----------------------------------------------------------------------
 .../structure/io/graphson/GraphSONMapper.java   |  71 +-
 .../structure/io/graphson/GraphSONModule.java   | 206 ++++++
 .../io/graphson/GraphSONSerializersV2d0.java    | 162 ++---
 .../io/graphson/GraphSONSerializersV3d0.java    | 632 +++++++++++++++++
 .../structure/io/graphson/GraphSONTokens.java   |   1 +
 .../structure/io/graphson/GraphSONUtil.java     |   7 +
 .../structure/io/graphson/GraphSONVersion.java  |   3 +-
 .../ser/GraphSONMessageSerializerV3d0.java      | 124 ++++
 .../ser/GraphSONMessageSerializerV3d0Test.java  | 342 ++++++++++
 .../driver/gremlin-server-modern-secure-py.yaml |   2 +-
 gremlin-server/conf/gremlin-server-classic.yaml |   2 +-
 .../conf/gremlin-server-modern-py.yaml          |   2 +-
 gremlin-server/conf/gremlin-server-modern.yaml  |   2 +-
 gremlin-server/conf/gremlin-server.yaml         |   2 +-
 gremlin-tools/gremlin-io-test/pom.xml           |  20 +-
 .../io/graphson/GraphSONCompatibility.java      |   3 +-
 .../GraphSONTypedCompatibilityTest.java         |   9 +-
 .../_3_3_0/authenticationchallenge-v3d0.json    |  12 +
 .../authenticationresponse-v2d0-partial.json    |   5 +-
 .../_3_3_0/authenticationresponse-v3d0.json     |   9 +
 .../io/graphson/_3_3_0/barrier-v3d0.json        |   4 +
 .../io/graphson/_3_3_0/bigdecimal-v3d0.json     |   4 +
 .../io/graphson/_3_3_0/biginteger-v3d0.json     |   4 +
 .../io/graphson/_3_3_0/binding-v3d0.json        |  10 +
 .../structure/io/graphson/_3_3_0/byte-v3d0.json |   4 +
 .../io/graphson/_3_3_0/bytebuffer-v3d0.json     |   4 +
 .../io/graphson/_3_3_0/bytecode-v3d0.json       |   6 +
 .../io/graphson/_3_3_0/cardinality-v3d0.json    |   4 +
 .../structure/io/graphson/_3_3_0/char-v3d0.json |   4 +
 .../io/graphson/_3_3_0/class-v3d0.json          |   4 +
 .../io/graphson/_3_3_0/column-v3d0.json         |   4 +
 .../structure/io/graphson/_3_3_0/date-v3d0.json |   4 +
 .../io/graphson/_3_3_0/direction-v3d0.json      |   4 +
 .../io/graphson/_3_3_0/double-v3d0.json         |   4 +
 .../io/graphson/_3_3_0/duration-v3d0.json       |   4 +
 .../io/graphson/_3_3_0/edge-v2d0-no-types.json  |   5 +-
 .../io/graphson/_3_3_0/edge-v2d0-partial.json   |  10 +-
 .../structure/io/graphson/_3_3_0/edge-v3d0.json |  26 +
 .../io/graphson/_3_3_0/float-v3d0.json          |   4 +
 .../io/graphson/_3_3_0/inetaddress-v3d0.json    |   4 +
 .../io/graphson/_3_3_0/instant-v3d0.json        |   4 +
 .../io/graphson/_3_3_0/integer-v3d0.json        |   4 +
 .../io/graphson/_3_3_0/lambda-v3d0.json         |   8 +
 .../io/graphson/_3_3_0/localdate-v3d0.json      |   4 +
 .../io/graphson/_3_3_0/localdatetime-v3d0.json  |   4 +
 .../io/graphson/_3_3_0/localtime-v3d0.json      |   4 +
 .../structure/io/graphson/_3_3_0/long-v3d0.json |   4 +
 .../io/graphson/_3_3_0/metrics-v3d0.json        |  54 ++
 .../io/graphson/_3_3_0/monthday-v3d0.json       |   4 +
 .../io/graphson/_3_3_0/offsetdatetime-v3d0.json |   4 +
 .../io/graphson/_3_3_0/offsettime-v3d0.json     |   4 +
 .../io/graphson/_3_3_0/operator-v3d0.json       |   4 +
 .../io/graphson/_3_3_0/order-v3d0.json          |   4 +
 .../structure/io/graphson/_3_3_0/p-v3d0.json    |  10 +
 .../structure/io/graphson/_3_3_0/pand-v3d0.json |  25 +
 .../io/graphson/_3_3_0/path-v2d0-no-types.json  |   7 -
 .../io/graphson/_3_3_0/path-v2d0-partial.json   |  28 -
 .../structure/io/graphson/_3_3_0/path-v3d0.json | 122 ++++
 .../io/graphson/_3_3_0/period-v3d0.json         |   4 +
 .../structure/io/graphson/_3_3_0/pick-v3d0.json |   4 +
 .../structure/io/graphson/_3_3_0/pop-v3d0.json  |   4 +
 .../structure/io/graphson/_3_3_0/por-v3d0.json  |  31 +
 .../graphson/_3_3_0/property-v2d0-no-types.json |  11 +-
 .../graphson/_3_3_0/property-v2d0-partial.json  |  18 -
 .../io/graphson/_3_3_0/property-v3d0.json       |  25 +
 .../io/graphson/_3_3_0/scope-v3d0.json          |   4 +
 .../_3_3_0/sessionclose-v2d0-partial.json       |   5 +-
 .../io/graphson/_3_3_0/sessionclose-v3d0.json   |  11 +
 .../_3_3_0/sessioneval-v2d0-partial.json        |   5 +-
 .../io/graphson/_3_3_0/sessioneval-v3d0.json    |  19 +
 .../_3_3_0/sessionevalaliased-v2d0-partial.json |   5 +-
 .../_3_3_0/sessionevalaliased-v3d0.json         |  22 +
 .../_3_3_0/sessionlesseval-v2d0-partial.json    |   5 +-
 .../graphson/_3_3_0/sessionlesseval-v3d0.json   |  15 +
 .../sessionlessevalaliased-v2d0-partial.json    |   5 +-
 .../_3_3_0/sessionlessevalaliased-v3d0.json     |  18 +
 .../io/graphson/_3_3_0/short-v3d0.json          |   4 +
 .../_3_3_0/standardresult-v2d0-no-types.json    |   5 -
 .../_3_3_0/standardresult-v2d0-partial.json     |  20 -
 .../io/graphson/_3_3_0/standardresult-v3d0.json |  91 +++
 .../_3_3_0/stargraph-v2d0-no-types.json         |   5 -
 .../graphson/_3_3_0/stargraph-v2d0-partial.json |  20 -
 .../io/graphson/_3_3_0/stargraph-v3d0.json      |  82 +++
 .../structure/io/graphson/_3_3_0/t-v3d0.json    |   4 +
 .../io/graphson/_3_3_0/timestamp-v3d0.json      |   4 +
 .../_3_3_0/tinkergraph-v2d0-no-types.json       |  85 ++-
 .../_3_3_0/tinkergraph-v2d0-partial.json        | 210 +++---
 .../io/graphson/_3_3_0/tinkergraph-v3d0.json    | 671 +++++++++++++++++++
 .../graphson/_3_3_0/traversalmetrics-v3d0.json  | 114 ++++
 .../_3_3_0/traverser-v2d0-no-types.json         |   5 -
 .../graphson/_3_3_0/traverser-v2d0-partial.json |  20 -
 .../io/graphson/_3_3_0/traverser-v3d0.json      |  89 +++
 .../io/graphson/_3_3_0/tree-v2d0-no-types.json  |   7 -
 .../io/graphson/_3_3_0/tree-v2d0-partial.json   |  28 -
 .../structure/io/graphson/_3_3_0/tree-v3d0.json | 137 ++++
 .../structure/io/graphson/_3_3_0/uuid-v3d0.json |   4 +
 .../graphson/_3_3_0/vertex-v2d0-no-types.json   |   5 -
 .../io/graphson/_3_3_0/vertex-v2d0-partial.json |  20 -
 .../io/graphson/_3_3_0/vertex-v3d0.json         |  80 +++
 .../_3_3_0/vertexproperty-v2d0-no-types.json    |   1 -
 .../_3_3_0/vertexproperty-v2d0-partial.json     |   4 -
 .../io/graphson/_3_3_0/vertexproperty-v3d0.json |  15 +
 .../structure/io/graphson/_3_3_0/year-v3d0.json |   4 +
 .../io/graphson/_3_3_0/yearmonth-v3d0.json      |   4 +
 .../io/graphson/_3_3_0/zoneddatetime-v3d0.json  |   4 +
 .../io/graphson/_3_3_0/zoneoffset-v3d0.json     |   4 +
 106 files changed, 3465 insertions(+), 523 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7db10c40/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
index f82ebb7..d442dbc 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
@@ -87,13 +87,44 @@ public class GraphSONMapper implements Mapper<ObjectMapper> 
{
         om.registerModule(graphSONModule);
         customModules.forEach(om::registerModule);
 
-
         // plugin external serialization modules
         if (loadCustomSerializers)
             om.findAndRegisterModules();
 
-
-        if (version == GraphSONVersion.V1_0) {
+        // graphson 3.0 only allows type - there is no option to remove 
embedded types
+        if (version == GraphSONVersion.V3_0 || (version == 
GraphSONVersion.V2_0 && typeInfo != TypeInfo.NO_TYPES)) {
+            final GraphSONTypeIdResolver graphSONTypeIdResolver = new 
GraphSONTypeIdResolver();
+            final TypeResolverBuilder typer = new GraphSONTypeResolverBuilder()
+                    .typesEmbedding(getTypeInfo())
+                    .valuePropertyName(GraphSONTokens.VALUEPROP)
+                    .init(JsonTypeInfo.Id.CUSTOM, graphSONTypeIdResolver)
+                    .typeProperty(GraphSONTokens.VALUETYPE);
+
+            // Registers native Java types that are supported by Jackson
+            registerJavaBaseTypes(graphSONTypeIdResolver);
+
+            // Registers the GraphSON Module's types
+            graphSONModule.getTypeDefinitions().forEach(
+                    (targetClass, typeId) -> 
graphSONTypeIdResolver.addCustomType(
+                            String.format("%s:%s", 
graphSONModule.getTypeNamespace(), typeId), targetClass));
+
+            // Register types to typeResolver for the Custom modules
+            customModules.forEach(e -> {
+                if (e instanceof TinkerPopJacksonModule) {
+                    final TinkerPopJacksonModule mod = 
(TinkerPopJacksonModule) e;
+                    final Map<Class, String> moduleTypeDefinitions = 
mod.getTypeDefinitions();
+                    if (moduleTypeDefinitions != null) {
+                        if (mod.getTypeNamespace() == null || 
mod.getTypeNamespace().isEmpty())
+                            throw new IllegalStateException("Cannot specify a 
module for GraphSON 2.0 with type definitions but without a type Domain. " +
+                                    "If no specific type domain is required, 
use Gremlin's default domain, \"gremlin\" but there may be collisions.");
+
+                        moduleTypeDefinitions.forEach((targetClass, typeId) -> 
graphSONTypeIdResolver.addCustomType(
+                                        String.format("%s:%s", 
mod.getTypeNamespace(), typeId), targetClass));
+                    }
+                }
+            });
+            om.setDefaultTyping(typer);
+        } else if (version == GraphSONVersion.V1_0 || version == 
GraphSONVersion.V2_0) {
             if (embedTypes) {
                 final TypeResolverBuilder<?> typer = new 
StdTypeResolverBuilder()
                         .init(JsonTypeInfo.Id.CLASS, null)
@@ -101,40 +132,6 @@ public class GraphSONMapper implements 
Mapper<ObjectMapper> {
                         .typeProperty(GraphSONTokens.CLASS);
                 om.setDefaultTyping(typer);
             }
-        } else if (version == GraphSONVersion.V2_0) {
-            if (typeInfo != TypeInfo.NO_TYPES) {
-                final GraphSONTypeIdResolver graphSONTypeIdResolver = new 
GraphSONTypeIdResolver();
-                final TypeResolverBuilder typer = new 
GraphSONTypeResolverBuilder()
-                        .typesEmbedding(getTypeInfo())
-                        .valuePropertyName(GraphSONTokens.VALUEPROP)
-                        .init(JsonTypeInfo.Id.CUSTOM, graphSONTypeIdResolver)
-                        .typeProperty(GraphSONTokens.VALUETYPE);
-
-                // Registers native Java types that are supported by Jackson
-                registerJavaBaseTypes(graphSONTypeIdResolver);
-
-                // Registers the GraphSON Module's types
-                graphSONModule.getTypeDefinitions().forEach(
-                        (targetClass, typeId) -> 
graphSONTypeIdResolver.addCustomType(
-                                String.format("%s:%s", 
graphSONModule.getTypeNamespace(), typeId), targetClass));
-
-                // Register types to typeResolver for the Custom modules
-                customModules.forEach(e -> {
-                    if (e instanceof TinkerPopJacksonModule) {
-                        final TinkerPopJacksonModule mod = 
(TinkerPopJacksonModule) e;
-                        final Map<Class, String> moduleTypeDefinitions = 
mod.getTypeDefinitions();
-                        if (moduleTypeDefinitions != null) {
-                            if (mod.getTypeNamespace() == null || 
mod.getTypeNamespace().isEmpty())
-                                throw new IllegalStateException("Cannot 
specify a module for GraphSON 2.0 with type definitions but without a type 
Domain. " +
-                                        "If no specific type domain is 
required, use Gremlin's default domain, \"gremlin\" but there may be 
collisions.");
-
-                            moduleTypeDefinitions.forEach((targetClass, 
typeId) -> graphSONTypeIdResolver.addCustomType(
-                                            String.format("%s:%s", 
mod.getTypeNamespace(), typeId), targetClass));
-                        }
-                    }
-                });
-                om.setDefaultTyping(typer);
-            }
         } else {
             throw new IllegalStateException("Unknown GraphSONVersion : " + 
version);
         }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7db10c40/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
index a061d1c..dceae6b 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
@@ -109,6 +109,212 @@ abstract class GraphSONModule extends 
TinkerPopJacksonModule {
     }
 
     /**
+     * Version 3.0 of GraphSON.
+     */
+    static final class GraphSONModuleV3d0 extends GraphSONModule {
+
+        private static final Map<Class, String> TYPE_DEFINITIONS = 
Collections.unmodifiableMap(
+                new LinkedHashMap<Class, String>() {{
+                    // Those don't have deserializers because handled by 
Jackson,
+                    // but we still want to rename them in GraphSON
+                    put(Integer.class, "Int32");
+                    put(Long.class, "Int64");
+                    put(Double.class, "Double");
+                    put(Float.class, "Float");
+
+                    // Tinkerpop Graph objects
+                    put(Lambda.class, "Lambda");
+                    put(Vertex.class, "Vertex");
+                    put(Edge.class, "Edge");
+                    put(Property.class, "Property");
+                    put(Path.class, "Path");
+                    put(VertexProperty.class, "VertexProperty");
+                    put(Metrics.class, "Metrics");
+                    put(TraversalMetrics.class, "TraversalMetrics");
+                    put(Traverser.class, "Traverser");
+                    put(Tree.class, "Tree");
+                    put(Bytecode.class, "Bytecode");
+                    put(Bytecode.Binding.class, "Binding");
+                    put(AndP.class, "P");
+                    put(OrP.class, "P");
+                    put(P.class, "P");
+                    Stream.of(
+                            VertexProperty.Cardinality.class,
+                            Column.class,
+                            Direction.class,
+                            Operator.class,
+                            Order.class,
+                            Pop.class,
+                            SackFunctions.Barrier.class,
+                            TraversalOptionParent.Pick.class,
+                            Scope.class,
+                            T.class).forEach(e -> put(e, e.getSimpleName()));
+                    Arrays.asList(
+                            ConnectiveStrategy.class,
+                            ElementIdStrategy.class,
+                            EventStrategy.class,
+                            HaltedTraverserStrategy.class,
+                            PartitionStrategy.class,
+                            SubgraphStrategy.class,
+                            LazyBarrierStrategy.class,
+                            MatchAlgorithmStrategy.class,
+                            AdjacentToIncidentStrategy.class,
+                            FilterRankingStrategy.class,
+                            IdentityRemovalStrategy.class,
+                            IncidentToAdjacentStrategy.class,
+                            InlineFilterStrategy.class,
+                            MatchPredicateStrategy.class,
+                            OrderLimitStrategy.class,
+                            PathProcessorStrategy.class,
+                            PathRetractionStrategy.class,
+                            RangeByIsCountStrategy.class,
+                            RepeatUnrollStrategy.class,
+                            ComputerVerificationStrategy.class,
+                            LambdaRestrictionStrategy.class,
+                            ReadOnlyStrategy.class,
+                            StandardVerificationStrategy.class,
+                            //
+                            GraphFilterStrategy.class,
+                            VertexProgramStrategy.class
+                    ).forEach(strategy -> put(strategy, 
strategy.getSimpleName()));
+                }});
+
+        /**
+         * Constructs a new object.
+         */
+        protected GraphSONModuleV3d0(final boolean normalize) {
+            super("graphson-3.0");
+
+            /////////////////////// SERIALIZERS ////////////////////////////
+
+            // graph
+            addSerializer(Edge.class, new 
GraphSONSerializersV3d0.EdgeJacksonSerializer(normalize));
+            addSerializer(Vertex.class, new 
GraphSONSerializersV3d0.VertexJacksonSerializer(normalize));
+            addSerializer(VertexProperty.class, new 
GraphSONSerializersV3d0.VertexPropertyJacksonSerializer(normalize, true));
+            addSerializer(Property.class, new 
GraphSONSerializersV3d0.PropertyJacksonSerializer());
+            addSerializer(Metrics.class, new 
GraphSONSerializersV3d0.MetricsJacksonSerializer());
+            addSerializer(TraversalMetrics.class, new 
GraphSONSerializersV3d0.TraversalMetricsJacksonSerializer());
+            addSerializer(TraversalExplanation.class, new 
GraphSONSerializersV3d0.TraversalExplanationJacksonSerializer());
+            addSerializer(Path.class, new 
GraphSONSerializersV3d0.PathJacksonSerializer());
+            addSerializer(DirectionalStarGraph.class, new 
StarGraphGraphSONSerializerV2d0(normalize));
+            addSerializer(Tree.class, new 
GraphSONSerializersV3d0.TreeJacksonSerializer());
+
+            // java.util
+            addSerializer(Map.Entry.class, new 
JavaUtilSerializersV2d0.MapEntryJacksonSerializer());
+
+            // need to explicitly add serializers for those types because 
Jackson doesn't do it at all.
+            addSerializer(Integer.class, new 
GraphSONSerializersV3d0.IntegerGraphSONSerializer());
+            addSerializer(Double.class, new 
GraphSONSerializersV3d0.DoubleGraphSONSerializer());
+
+            // traversal
+            addSerializer(Traversal.class, new 
GraphSONTraversalSerializersV2d0.TraversalJacksonSerializer());
+            addSerializer(Bytecode.class, new 
GraphSONTraversalSerializersV2d0.BytecodeJacksonSerializer());
+            Stream.of(VertexProperty.Cardinality.class,
+                    Column.class,
+                    Direction.class,
+                    Operator.class,
+                    Order.class,
+                    Pop.class,
+                    SackFunctions.Barrier.class,
+                    Scope.class,
+                    TraversalOptionParent.Pick.class,
+                    T.class).forEach(e -> addSerializer(e, new 
GraphSONTraversalSerializersV2d0.EnumJacksonSerializer()));
+            addSerializer(P.class, new 
GraphSONTraversalSerializersV2d0.PJacksonSerializer());
+            addSerializer(Lambda.class, new 
GraphSONTraversalSerializersV2d0.LambdaJacksonSerializer());
+            addSerializer(Bytecode.Binding.class, new 
GraphSONTraversalSerializersV2d0.BindingJacksonSerializer());
+            addSerializer(Traverser.class, new 
GraphSONTraversalSerializersV2d0.TraverserJacksonSerializer());
+            addSerializer(TraversalStrategy.class, new 
GraphSONTraversalSerializersV2d0.TraversalStrategyJacksonSerializer());
+
+            /////////////////////// DESERIALIZERS ////////////////////////////
+
+            // Tinkerpop Graph
+            addDeserializer(Vertex.class, new 
GraphSONSerializersV3d0.VertexJacksonDeserializer());
+            addDeserializer(Edge.class, new 
GraphSONSerializersV3d0.EdgeJacksonDeserializer());
+            addDeserializer(Property.class, new 
GraphSONSerializersV3d0.PropertyJacksonDeserializer());
+            addDeserializer(Path.class, new 
GraphSONSerializersV3d0.PathJacksonDeserializer());
+            addDeserializer(VertexProperty.class, new 
GraphSONSerializersV3d0.VertexPropertyJacksonDeserializer());
+            addDeserializer(Metrics.class, new 
GraphSONSerializersV3d0.MetricsJacksonDeserializer());
+            addDeserializer(TraversalMetrics.class, new 
GraphSONSerializersV3d0.TraversalMetricsJacksonDeserializer());
+            addDeserializer(Tree.class, new 
GraphSONSerializersV3d0.TreeJacksonDeserializer());
+
+            // numbers
+            addDeserializer(Integer.class, new 
GraphSONSerializersV2d0.IntegerJackonsDeserializer());
+            addDeserializer(Double.class, new 
GraphSONSerializersV2d0.DoubleJackonsDeserializer());
+
+            // traversal
+            addDeserializer(Bytecode.class, new 
GraphSONTraversalSerializersV2d0.BytecodeJacksonDeserializer());
+            addDeserializer(Bytecode.Binding.class, new 
GraphSONTraversalSerializersV2d0.BindingJacksonDeserializer());
+            Stream.of(VertexProperty.Cardinality.values(),
+                    Column.values(),
+                    Direction.values(),
+                    Operator.values(),
+                    Order.values(),
+                    Pop.values(),
+                    SackFunctions.Barrier.values(),
+                    Scope.values(),
+                    TraversalOptionParent.Pick.values(),
+                    T.values()).flatMap(Stream::of).forEach(e -> 
addDeserializer(e.getClass(), new 
GraphSONTraversalSerializersV2d0.EnumJacksonDeserializer(e.getDeclaringClass())));
+            addDeserializer(P.class, new 
GraphSONTraversalSerializersV2d0.PJacksonDeserializer());
+            addDeserializer(Lambda.class, new 
GraphSONTraversalSerializersV2d0.LambdaJacksonDeserializer());
+            addDeserializer(Traverser.class, new 
GraphSONTraversalSerializersV2d0.TraverserJacksonDeserializer());
+            Arrays.asList(
+                    ConnectiveStrategy.class,
+                    ElementIdStrategy.class,
+                    EventStrategy.class,
+                    HaltedTraverserStrategy.class,
+                    PartitionStrategy.class,
+                    SubgraphStrategy.class,
+                    LazyBarrierStrategy.class,
+                    MatchAlgorithmStrategy.class,
+                    AdjacentToIncidentStrategy.class,
+                    FilterRankingStrategy.class,
+                    IdentityRemovalStrategy.class,
+                    IncidentToAdjacentStrategy.class,
+                    InlineFilterStrategy.class,
+                    MatchPredicateStrategy.class,
+                    OrderLimitStrategy.class,
+                    PathProcessorStrategy.class,
+                    PathRetractionStrategy.class,
+                    RangeByIsCountStrategy.class,
+                    RepeatUnrollStrategy.class,
+                    ComputerVerificationStrategy.class,
+                    LambdaRestrictionStrategy.class,
+                    ReadOnlyStrategy.class,
+                    StandardVerificationStrategy.class,
+                    //
+                    GraphFilterStrategy.class,
+                    VertexProgramStrategy.class
+            ).forEach(strategy -> addDeserializer(strategy, new 
GraphSONTraversalSerializersV2d0.TraversalStrategyProxyJacksonDeserializer(strategy)));
+        }
+
+        public static Builder build() {
+            return new Builder();
+        }
+
+        @Override
+        public Map<Class, String> getTypeDefinitions() {
+            return TYPE_DEFINITIONS;
+        }
+
+        @Override
+        public String getTypeNamespace() {
+            return GraphSONTokens.GREMLIN_TYPE_NAMESPACE;
+        }
+
+        static final class Builder implements GraphSONModuleBuilder {
+
+            private Builder() {
+            }
+
+            @Override
+            public GraphSONModule create(final boolean normalize) {
+                return new GraphSONModuleV3d0(normalize);
+            }
+
+        }
+    }
+
+    /**
      * Version 2.0 of GraphSON.
      */
     static final class GraphSONModuleV2d0 extends GraphSONModule {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7db10c40/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
index 824fc7f..f8f4cd1 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -54,7 +54,6 @@ import org.javatuples.Pair;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -64,6 +63,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
+import static 
org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil.safeWriteObjectField;
+
 /**
  * GraphSON serializers for graph-based objects such as vertices, edges, 
properties, and paths. These serializers
  * present a generalized way to serialize the implementations of core 
interfaces.
@@ -100,34 +101,22 @@ class GraphSONSerializersV2d0 {
         }
 
         private void writeProperties(final Vertex vertex, final JsonGenerator 
jsonGenerator) throws IOException {
-            if (vertex.keys().isEmpty())
+            if (vertex.keys().size() == 0)
                 return;
             jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
             jsonGenerator.writeStartObject();
 
             final List<String> keys = normalize ?
                     IteratorUtils.list(vertex.keys().iterator(), 
Comparator.naturalOrder()) : new ArrayList<>(vertex.keys());
-            for (final String key : keys) {
+            for (String key : keys) {
                 final Iterator<VertexProperty<Object>> vertexProperties = 
normalize ?
                         IteratorUtils.list(vertex.properties(key), 
Comparators.PROPERTY_COMPARATOR).iterator() : vertex.properties(key);
                 if (vertexProperties.hasNext()) {
                     jsonGenerator.writeFieldName(key);
+
                     jsonGenerator.writeStartArray();
                     while (vertexProperties.hasNext()) {
-                        final VertexProperty<?> vertexProperty = 
vertexProperties.next();
-                        jsonGenerator.writeStartObject();
-                        jsonGenerator.writeObjectField(GraphSONTokens.ID, 
vertexProperty.id());
-                        jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
vertexProperty.value());
-                        if (!vertexProperty.keys().isEmpty()) {
-                            
jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
-                            final Iterator<Property<?>> properties = 
(Iterator) vertexProperty.properties();
-                            while (properties.hasNext()) {
-                                final Property<?> property = properties.next();
-                                jsonGenerator.writeObjectField(property.key(), 
property.value());
-                            }
-                            jsonGenerator.writeEndObject();
-                        }
-                        jsonGenerator.writeEndObject();
+                        jsonGenerator.writeObject(vertexProperties.next());
                     }
                     jsonGenerator.writeEndArray();
                 }
@@ -164,15 +153,13 @@ class GraphSONSerializersV2d0 {
         }
 
         private void writeProperties(final Edge edge, final JsonGenerator 
jsonGenerator) throws IOException {
-            final Iterator<Property<Object>> edgeProperties = normalize ?
+            final Iterator<Property<Object>> elementProperties = normalize ?
                     IteratorUtils.list(edge.properties(), 
Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
-            if (edgeProperties.hasNext()) {
+            if (elementProperties.hasNext()) {
                 jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+
                 jsonGenerator.writeStartObject();
-                while (edgeProperties.hasNext()) {
-                    final Property<?> property = edgeProperties.next();
-                    jsonGenerator.writeObjectField(property.key(), 
property.value());
-                }
+                elementProperties.forEachRemaining(prop -> 
safeWriteObjectField(jsonGenerator, prop.key(), prop));
                 jsonGenerator.writeEndObject();
             }
         }
@@ -188,25 +175,8 @@ class GraphSONSerializersV2d0 {
         public void serialize(final Property property, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
                 throws IOException {
             jsonGenerator.writeStartObject();
-            jsonGenerator.writeStringField(GraphSONTokens.KEY, property.key());
+            jsonGenerator.writeObjectField(GraphSONTokens.KEY, property.key());
             jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
property.value());
-            if (property.element() instanceof VertexProperty) {
-                VertexProperty vertexProperty = (VertexProperty) 
property.element();
-                
jsonGenerator.writeObjectFieldStart(GraphSONTokens.VERTEX_PROPERTY);
-                jsonGenerator.writeObjectField(GraphSONTokens.ID, 
vertexProperty.id());
-                jsonGenerator.writeStringField(GraphSONTokens.LABEL, 
vertexProperty.label());
-                jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
vertexProperty.value());
-                jsonGenerator.writeObjectField(GraphSONTokens.VERTEX, 
vertexProperty.element().id());
-                jsonGenerator.writeEndObject();
-            } else if (property.element() instanceof Edge) {
-                Edge edge = (Edge) property.element();
-                jsonGenerator.writeObjectFieldStart(GraphSONTokens.EDGE);
-                jsonGenerator.writeObjectField(GraphSONTokens.ID, edge.id());
-                jsonGenerator.writeStringField(GraphSONTokens.LABEL, 
edge.label());
-                jsonGenerator.writeObjectField(GraphSONTokens.IN, 
edge.inVertex().id());
-                jsonGenerator.writeObjectField(GraphSONTokens.OUT, 
edge.outVertex().id());
-                jsonGenerator.writeEndObject();
-            }
             jsonGenerator.writeEndObject();
         }
     }
@@ -223,46 +193,44 @@ class GraphSONSerializersV2d0 {
         }
 
         @Override
-        public void serialize(final VertexProperty vertexProperty, final 
JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+        public void serialize(final VertexProperty property, final 
JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
                 throws IOException {
             jsonGenerator.writeStartObject();
 
-            jsonGenerator.writeObjectField(GraphSONTokens.ID, 
vertexProperty.id());
-            jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
vertexProperty.value());
-            if (null != vertexProperty.element())
-                jsonGenerator.writeObjectField(GraphSONTokens.VERTEX, 
vertexProperty.element().id());
-            if (this.includeLabel)
-                jsonGenerator.writeStringField(GraphSONTokens.LABEL, 
vertexProperty.label());
-            tryWriteMetaProperties(vertexProperty, jsonGenerator, normalize);
+            jsonGenerator.writeObjectField(GraphSONTokens.ID, property.id());
+            jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
property.value());
+            if (includeLabel)
+                jsonGenerator.writeStringField(GraphSONTokens.LABEL, 
property.label());
+            tryWriteMetaProperties(property, jsonGenerator, normalize);
 
             jsonGenerator.writeEndObject();
         }
 
-        private static void tryWriteMetaProperties(final VertexProperty 
vertexProperty, final JsonGenerator jsonGenerator,
+        private static void tryWriteMetaProperties(final VertexProperty 
property, final JsonGenerator jsonGenerator,
                                                    final boolean normalize) 
throws IOException {
             // when "detached" you can't check features of the graph it 
detached from so it has to be
             // treated differently from a regular VertexProperty 
implementation.
-            if (vertexProperty instanceof DetachedVertexProperty) {
+            if (property instanceof DetachedVertexProperty) {
                 // only write meta properties key if they exist
-                if (vertexProperty.properties().hasNext()) {
-                    writeMetaProperties(vertexProperty, jsonGenerator, 
normalize);
+                if (property.properties().hasNext()) {
+                    writeMetaProperties(property, jsonGenerator, normalize);
                 }
             } else {
                 // still attached - so we can check the features to see if 
it's worth even trying to write the
                 // meta properties key
-                if 
(vertexProperty.graph().features().vertex().supportsMetaProperties() && 
vertexProperty.properties().hasNext()) {
-                    writeMetaProperties(vertexProperty, jsonGenerator, 
normalize);
+                if 
(property.graph().features().vertex().supportsMetaProperties() && 
property.properties().hasNext()) {
+                    writeMetaProperties(property, jsonGenerator, normalize);
                 }
             }
         }
 
-        private static void writeMetaProperties(final VertexProperty 
vertexProperty, final JsonGenerator jsonGenerator,
+        private static void writeMetaProperties(final VertexProperty property, 
final JsonGenerator jsonGenerator,
                                                 final boolean normalize) 
throws IOException {
             jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
             jsonGenerator.writeStartObject();
 
             final Iterator<Property<Object>> metaProperties = normalize ?
-                    IteratorUtils.list((Iterator<Property<Object>>) 
vertexProperty.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : 
vertexProperty.properties();
+                    IteratorUtils.list((Iterator<Property<Object>>) 
property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : 
property.properties();
             while (metaProperties.hasNext()) {
                 final Property<Object> metaProperty = metaProperties.next();
                 jsonGenerator.writeObjectField(metaProperty.key(), 
metaProperty.value());
@@ -358,7 +326,7 @@ class GraphSONSerializersV2d0 {
         @Override
         public void serialize(final Integer integer, final JsonGenerator 
jsonGenerator,
                               final SerializerProvider serializerProvider) 
throws IOException {
-            jsonGenerator.writeNumber(integer.intValue());
+            jsonGenerator.writeNumber(((Integer) integer).intValue());
         }
     }
 
@@ -459,7 +427,7 @@ class GraphSONSerializersV2d0 {
         public Vertex createObject(final Map<String, Object> vertexData) {
             return new DetachedVertex(
                     vertexData.get(GraphSONTokens.ID),
-                    (String) vertexData.getOrDefault(GraphSONTokens.LABEL, 
Vertex.DEFAULT_LABEL),
+                    vertexData.get(GraphSONTokens.LABEL).toString(),
                     (Map<String, Object>) 
vertexData.get(GraphSONTokens.PROPERTIES)
             );
         }
@@ -475,10 +443,10 @@ class GraphSONSerializersV2d0 {
         public Edge createObject(final Map<String, Object> edgeData) {
             return new DetachedEdge(
                     edgeData.get(GraphSONTokens.ID),
-                    (String) edgeData.getOrDefault(GraphSONTokens.LABEL, 
Edge.DEFAULT_LABEL),
-                    (Map<String, Object>) 
edgeData.get(GraphSONTokens.PROPERTIES),
-                    Pair.with(edgeData.get(GraphSONTokens.OUT), (String) 
edgeData.getOrDefault(GraphSONTokens.OUT_LABEL, Vertex.DEFAULT_LABEL)),
-                    Pair.with(edgeData.get(GraphSONTokens.IN), (String) 
edgeData.getOrDefault(GraphSONTokens.IN_LABEL, Vertex.DEFAULT_LABEL))
+                    edgeData.get(GraphSONTokens.LABEL).toString(),
+                    (Map) edgeData.get(GraphSONTokens.PROPERTIES),
+                    Pair.with(edgeData.get(GraphSONTokens.OUT), 
edgeData.get(GraphSONTokens.OUT_LABEL).toString()),
+                    Pair.with(edgeData.get(GraphSONTokens.IN), 
edgeData.get(GraphSONTokens.IN_LABEL).toString())
             );
         }
     }
@@ -491,41 +459,9 @@ class GraphSONSerializersV2d0 {
 
         @Override
         public Property createObject(final Map<String, Object> propData) {
-            Element element = null;
-            if (propData.containsKey(GraphSONTokens.VERTEX_PROPERTY)) {
-                final Map<String, Object> elementData = (Map<String, Object>) 
propData.get(GraphSONTokens.VERTEX_PROPERTY);
-                element = new 
VertexPropertyJacksonDeserializer().createObject(elementData);
-            } else if (propData.containsKey(GraphSONTokens.EDGE)) {
-                final Map<String, Object> elementData = (Map<String, Object>) 
propData.get(GraphSONTokens.EDGE);
-                element = new 
EdgeJacksonDeserializer().createObject(elementData);
-            }
-            return null != element ? // graphson-non-embedded is treated 
differently, but since this is a hard coded embedding...
-                    new DetachedProperty<>((String) 
propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE), element) :
-                    new DetachedProperty<>((String) 
propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE));
-        }
-    }
-
-    static class VertexPropertyJacksonDeserializer extends 
AbstractObjectDeserializer<VertexProperty> {
-
-        protected VertexPropertyJacksonDeserializer() {
-            super(VertexProperty.class);
-        }
-
-        @Override
-        public VertexProperty createObject(final Map<String, Object> propData) 
{
-            return propData.containsKey(GraphSONTokens.VERTEX) ?
-                    new DetachedVertexProperty<>(
-                            propData.get(GraphSONTokens.ID),
-                            (String) propData.get(GraphSONTokens.LABEL),
-                            propData.get(GraphSONTokens.VALUE),
-                            (Map<String, Object>) 
propData.get(GraphSONTokens.PROPERTIES),
-                            new 
DetachedVertex(propData.get(GraphSONTokens.VERTEX), Vertex.DEFAULT_LABEL, 
null)) :
-                    new DetachedVertexProperty<>(
-                            propData.get(GraphSONTokens.ID),
-                            (String) propData.get(GraphSONTokens.LABEL),
-                            propData.get(GraphSONTokens.VALUE),
-                            (Map<String, Object>) 
propData.get(GraphSONTokens.PROPERTIES));
-
+            return new DetachedProperty(
+                    (String) propData.get(GraphSONTokens.KEY),
+                    propData.get(GraphSONTokens.VALUE));
         }
     }
 
@@ -549,6 +485,23 @@ class GraphSONSerializersV2d0 {
         }
     }
 
+    static class VertexPropertyJacksonDeserializer extends 
AbstractObjectDeserializer<VertexProperty> {
+
+        protected VertexPropertyJacksonDeserializer() {
+            super(VertexProperty.class);
+        }
+
+        @Override
+        public VertexProperty createObject(final Map<String, Object> propData) 
{
+            return new DetachedVertexProperty(
+                    propData.get(GraphSONTokens.ID),
+                    (String) propData.get(GraphSONTokens.LABEL),
+                    propData.get(GraphSONTokens.VALUE),
+                    (Map) propData.get(GraphSONTokens.PROPERTIES)
+            );
+        }
+    }
+
     static class MetricsJacksonDeserializer extends 
AbstractObjectDeserializer<Metrics> {
         public MetricsJacksonDeserializer() {
             super(Metrics.class);
@@ -556,16 +509,16 @@ class GraphSONSerializersV2d0 {
 
         @Override
         public Metrics createObject(final Map<String, Object> metricsData) {
-            final MutableMetrics m = new MutableMetrics((String) 
metricsData.get(GraphSONTokens.ID), (String) 
metricsData.get(GraphSONTokens.NAME));
+            final MutableMetrics m = new 
MutableMetrics((String)metricsData.get(GraphSONTokens.ID), 
(String)metricsData.get(GraphSONTokens.NAME));
 
             m.setDuration(Math.round((Double) 
metricsData.get(GraphSONTokens.DURATION) * 1000000), TimeUnit.NANOSECONDS);
-            for (Map.Entry<String, Long> count : ((Map<String, Long>) 
metricsData.getOrDefault(GraphSONTokens.COUNTS, 
Collections.emptyMap())).entrySet()) {
+            for (Map.Entry<String, Long> count : ((Map<String, 
Long>)metricsData.getOrDefault(GraphSONTokens.COUNTS, new 
HashMap<>(0))).entrySet()) {
                 m.setCount(count.getKey(), count.getValue());
             }
-            for (Map.Entry<String, Long> count : ((Map<String, Long>) 
metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, 
Collections.emptyMap())).entrySet()) {
+            for (Map.Entry<String, Long> count : ((Map<String, Long>) 
metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, new 
HashMap<>(0))).entrySet()) {
                 m.setAnnotation(count.getKey(), count.getValue());
             }
-            for (MutableMetrics nested : (List<MutableMetrics>) 
metricsData.getOrDefault(GraphSONTokens.METRICS, Collections.emptyList())) {
+            for (MutableMetrics nested : 
(List<MutableMetrics>)metricsData.getOrDefault(GraphSONTokens.METRICS, new 
ArrayList<>(0))) {
                 m.addNested(nested);
             }
             return m;
@@ -627,7 +580,4 @@ class GraphSONSerializersV2d0 {
             return jsonParser.getDoubleValue();
         }
     }
-}
-
-
-
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7db10c40/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java
new file mode 100644
index 0000000..165e7e1
--- /dev/null
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java
@@ -0,0 +1,632 @@
+/*
+ * 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.structure.io.graphson;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MutablePath;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
+import 
org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalMetrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics;
+import 
org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
+import 
org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdKeySerializer;
+import 
org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdScalarSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.javatuples.Pair;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * GraphSON serializers for graph-based objects such as vertices, edges, 
properties, and paths. These serializers
+ * present a generalized way to serialize the implementations of core 
interfaces.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+class GraphSONSerializersV3d0 {
+
+    private GraphSONSerializersV3d0() {
+    }
+
+    ////////////////////////////// SERIALIZERS 
/////////////////////////////////
+
+    final static class VertexJacksonSerializer extends 
StdScalarSerializer<Vertex> {
+
+        private final boolean normalize;
+
+        public VertexJacksonSerializer(final boolean normalize) {
+            super(Vertex.class);
+            this.normalize = normalize;
+        }
+
+        @Override
+        public void serialize(final Vertex vertex, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+
+            jsonGenerator.writeObjectField(GraphSONTokens.ID, vertex.id());
+            jsonGenerator.writeStringField(GraphSONTokens.LABEL, 
vertex.label());
+            writeProperties(vertex, jsonGenerator);
+
+            jsonGenerator.writeEndObject();
+
+        }
+
+        private void writeProperties(final Vertex vertex, final JsonGenerator 
jsonGenerator) throws IOException {
+            if (vertex.keys().isEmpty())
+                return;
+            jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+            jsonGenerator.writeStartObject();
+
+            final List<String> keys = normalize ?
+                    IteratorUtils.list(vertex.keys().iterator(), 
Comparator.naturalOrder()) : new ArrayList<>(vertex.keys());
+            for (final String key : keys) {
+                final Iterator<VertexProperty<Object>> vertexProperties = 
normalize ?
+                        IteratorUtils.list(vertex.properties(key), 
Comparators.PROPERTY_COMPARATOR).iterator() : vertex.properties(key);
+                if (vertexProperties.hasNext()) {
+                    jsonGenerator.writeFieldName(key);
+                    jsonGenerator.writeStartArray();
+                    while (vertexProperties.hasNext()) {
+                        final VertexProperty<?> vertexProperty = 
vertexProperties.next();
+                        jsonGenerator.writeStartObject();
+                        jsonGenerator.writeObjectField(GraphSONTokens.ID, 
vertexProperty.id());
+                        jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
vertexProperty.value());
+                        if (!vertexProperty.keys().isEmpty()) {
+                            
jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+                            final Iterator<Property<?>> properties = 
(Iterator) vertexProperty.properties();
+                            while (properties.hasNext()) {
+                                final Property<?> property = properties.next();
+                                jsonGenerator.writeObjectField(property.key(), 
property.value());
+                            }
+                            jsonGenerator.writeEndObject();
+                        }
+                        jsonGenerator.writeEndObject();
+                    }
+                    jsonGenerator.writeEndArray();
+                }
+            }
+
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    final static class EdgeJacksonSerializer extends StdScalarSerializer<Edge> 
{
+
+        private final boolean normalize;
+
+        public EdgeJacksonSerializer(final boolean normalize) {
+            super(Edge.class);
+            this.normalize = normalize;
+        }
+
+
+        @Override
+        public void serialize(final Edge edge, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+
+            jsonGenerator.writeObjectField(GraphSONTokens.ID, edge.id());
+            jsonGenerator.writeStringField(GraphSONTokens.LABEL, edge.label());
+            jsonGenerator.writeStringField(GraphSONTokens.IN_LABEL, 
edge.inVertex().label());
+            jsonGenerator.writeStringField(GraphSONTokens.OUT_LABEL, 
edge.outVertex().label());
+            jsonGenerator.writeObjectField(GraphSONTokens.IN, 
edge.inVertex().id());
+            jsonGenerator.writeObjectField(GraphSONTokens.OUT, 
edge.outVertex().id());
+            writeProperties(edge, jsonGenerator);
+
+            jsonGenerator.writeEndObject();
+        }
+
+        private void writeProperties(final Edge edge, final JsonGenerator 
jsonGenerator) throws IOException {
+            final Iterator<Property<Object>> edgeProperties = normalize ?
+                    IteratorUtils.list(edge.properties(), 
Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+            if (edgeProperties.hasNext()) {
+                jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+                jsonGenerator.writeStartObject();
+                while (edgeProperties.hasNext()) {
+                    final Property<?> property = edgeProperties.next();
+                    jsonGenerator.writeObjectField(property.key(), 
property.value());
+                }
+                jsonGenerator.writeEndObject();
+            }
+        }
+    }
+
+    final static class PropertyJacksonSerializer extends 
StdScalarSerializer<Property> {
+
+        public PropertyJacksonSerializer() {
+            super(Property.class);
+        }
+
+        @Override
+        public void serialize(final Property property, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            jsonGenerator.writeStringField(GraphSONTokens.KEY, property.key());
+            jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
property.value());
+            if (property.element() instanceof VertexProperty) {
+                VertexProperty vertexProperty = (VertexProperty) 
property.element();
+                
jsonGenerator.writeObjectFieldStart(GraphSONTokens.VERTEX_PROPERTY);
+                jsonGenerator.writeObjectField(GraphSONTokens.ID, 
vertexProperty.id());
+                jsonGenerator.writeStringField(GraphSONTokens.LABEL, 
vertexProperty.label());
+                jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
vertexProperty.value());
+                jsonGenerator.writeObjectField(GraphSONTokens.VERTEX, 
vertexProperty.element().id());
+                jsonGenerator.writeEndObject();
+            } else if (property.element() instanceof Edge) {
+                Edge edge = (Edge) property.element();
+                jsonGenerator.writeObjectFieldStart(GraphSONTokens.EDGE);
+                jsonGenerator.writeObjectField(GraphSONTokens.ID, edge.id());
+                jsonGenerator.writeStringField(GraphSONTokens.LABEL, 
edge.label());
+                jsonGenerator.writeObjectField(GraphSONTokens.IN, 
edge.inVertex().id());
+                jsonGenerator.writeObjectField(GraphSONTokens.OUT, 
edge.outVertex().id());
+                jsonGenerator.writeEndObject();
+            }
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    final static class VertexPropertyJacksonSerializer extends 
StdScalarSerializer<VertexProperty> {
+
+        private final boolean normalize;
+        private final boolean includeLabel;
+
+        public VertexPropertyJacksonSerializer(final boolean normalize, final 
boolean includeLabel) {
+            super(VertexProperty.class);
+            this.normalize = normalize;
+            this.includeLabel = includeLabel;
+        }
+
+        @Override
+        public void serialize(final VertexProperty vertexProperty, final 
JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+
+            jsonGenerator.writeObjectField(GraphSONTokens.ID, 
vertexProperty.id());
+            jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
vertexProperty.value());
+            if (null != vertexProperty.element())
+                jsonGenerator.writeObjectField(GraphSONTokens.VERTEX, 
vertexProperty.element().id());
+            if (this.includeLabel)
+                jsonGenerator.writeStringField(GraphSONTokens.LABEL, 
vertexProperty.label());
+            tryWriteMetaProperties(vertexProperty, jsonGenerator, normalize);
+
+            jsonGenerator.writeEndObject();
+        }
+
+        private static void tryWriteMetaProperties(final VertexProperty 
vertexProperty, final JsonGenerator jsonGenerator,
+                                                   final boolean normalize) 
throws IOException {
+            // when "detached" you can't check features of the graph it 
detached from so it has to be
+            // treated differently from a regular VertexProperty 
implementation.
+            if (vertexProperty instanceof DetachedVertexProperty) {
+                // only write meta properties key if they exist
+                if (vertexProperty.properties().hasNext()) {
+                    writeMetaProperties(vertexProperty, jsonGenerator, 
normalize);
+                }
+            } else {
+                // still attached - so we can check the features to see if 
it's worth even trying to write the
+                // meta properties key
+                if 
(vertexProperty.graph().features().vertex().supportsMetaProperties() && 
vertexProperty.properties().hasNext()) {
+                    writeMetaProperties(vertexProperty, jsonGenerator, 
normalize);
+                }
+            }
+        }
+
+        private static void writeMetaProperties(final VertexProperty 
vertexProperty, final JsonGenerator jsonGenerator,
+                                                final boolean normalize) 
throws IOException {
+            jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+            jsonGenerator.writeStartObject();
+
+            final Iterator<Property<Object>> metaProperties = normalize ?
+                    IteratorUtils.list((Iterator<Property<Object>>) 
vertexProperty.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : 
vertexProperty.properties();
+            while (metaProperties.hasNext()) {
+                final Property<Object> metaProperty = metaProperties.next();
+                jsonGenerator.writeObjectField(metaProperty.key(), 
metaProperty.value());
+            }
+
+            jsonGenerator.writeEndObject();
+        }
+
+
+    }
+
+    final static class PathJacksonSerializer extends StdScalarSerializer<Path> 
{
+
+        public PathJacksonSerializer() {
+            super(Path.class);
+        }
+
+        @Override
+        public void serialize(final Path path, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException, JsonGenerationException {
+            jsonGenerator.writeStartObject();
+
+            jsonGenerator.writeObjectField(GraphSONTokens.LABELS, 
path.labels());
+            jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, 
path.objects());
+
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    final static class TreeJacksonSerializer extends StdScalarSerializer<Tree> 
{
+
+        public TreeJacksonSerializer() {
+            super(Tree.class);
+        }
+
+        @Override
+        public void serialize(final Tree tree, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider) throws IOException, 
JsonGenerationException {
+            jsonGenerator.writeStartArray();
+            final Set<Map.Entry<Element, Tree>> set = tree.entrySet();
+            for (Map.Entry<Element, Tree> entry : set) {
+                jsonGenerator.writeStartObject();
+                jsonGenerator.writeObjectField(GraphSONTokens.KEY, 
entry.getKey());
+                jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
entry.getValue());
+                jsonGenerator.writeEndObject();
+            }
+            jsonGenerator.writeEndArray();
+        }
+    }
+
+    final static class TraversalExplanationJacksonSerializer extends 
StdSerializer<TraversalExplanation> {
+        public TraversalExplanationJacksonSerializer() {
+            super(TraversalExplanation.class);
+        }
+
+        @Override
+        public void serialize(final TraversalExplanation traversalExplanation, 
final JsonGenerator jsonGenerator,
+                              final SerializerProvider serializerProvider) 
throws IOException {
+            final Map<String, Object> m = new HashMap<>();
+            m.put(GraphSONTokens.ORIGINAL, 
getStepsAsList(traversalExplanation.getOriginalTraversal()));
+
+            final List<Pair<TraversalStrategy, Traversal.Admin<?, ?>>> 
strategyTraversals = traversalExplanation.getStrategyTraversals();
+
+            final List<Map<String, Object>> intermediates = new ArrayList<>();
+            for (final Pair<TraversalStrategy, Traversal.Admin<?, ?>> pair : 
strategyTraversals) {
+                final Map<String, Object> intermediate = new HashMap<>();
+                intermediate.put(GraphSONTokens.STRATEGY, 
pair.getValue0().toString());
+                intermediate.put(GraphSONTokens.CATEGORY, 
pair.getValue0().getTraversalCategory().getSimpleName());
+                intermediate.put(GraphSONTokens.TRAVERSAL, 
getStepsAsList(pair.getValue1()));
+                intermediates.add(intermediate);
+            }
+            m.put(GraphSONTokens.INTERMEDIATE, intermediates);
+
+            if (strategyTraversals.isEmpty())
+                m.put(GraphSONTokens.FINAL, 
getStepsAsList(traversalExplanation.getOriginalTraversal()));
+            else
+                m.put(GraphSONTokens.FINAL, 
getStepsAsList(strategyTraversals.get(strategyTraversals.size() - 
1).getValue1()));
+
+            jsonGenerator.writeObject(m);
+        }
+
+        private List<String> getStepsAsList(final Traversal.Admin<?, ?> t) {
+            final List<String> steps = new ArrayList<>();
+            t.getSteps().iterator().forEachRemaining(s -> 
steps.add(s.toString()));
+            return steps;
+        }
+    }
+
+    final static class IntegerGraphSONSerializer extends 
StdScalarSerializer<Integer> {
+        public IntegerGraphSONSerializer() {
+            super(Integer.class);
+        }
+
+        @Override
+        public void serialize(final Integer integer, final JsonGenerator 
jsonGenerator,
+                              final SerializerProvider serializerProvider) 
throws IOException {
+            jsonGenerator.writeNumber(integer.intValue());
+        }
+    }
+
+    final static class DoubleGraphSONSerializer extends 
StdScalarSerializer<Double> {
+        public DoubleGraphSONSerializer() {
+            super(Double.class);
+        }
+
+        @Override
+        public void serialize(final Double doubleValue, final JsonGenerator 
jsonGenerator,
+                              final SerializerProvider serializerProvider) 
throws IOException {
+            jsonGenerator.writeNumber(doubleValue);
+        }
+    }
+
+    final static class TraversalMetricsJacksonSerializer extends 
StdScalarSerializer<TraversalMetrics> {
+        public TraversalMetricsJacksonSerializer() {
+            super(TraversalMetrics.class);
+        }
+
+        @Override
+        public void serialize(final TraversalMetrics traversalMetrics, final 
JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            // creation of the map enables all the fields to be properly 
written with their type if required
+            final Map<String, Object> m = new HashMap<>();
+            m.put(GraphSONTokens.DURATION, 
traversalMetrics.getDuration(TimeUnit.NANOSECONDS) / 1000000d);
+            final List<Metrics> metrics = new ArrayList<>();
+            metrics.addAll(traversalMetrics.getMetrics());
+            m.put(GraphSONTokens.METRICS, metrics);
+
+            jsonGenerator.writeObject(m);
+        }
+    }
+
+    final static class MetricsJacksonSerializer extends 
StdScalarSerializer<Metrics> {
+        public MetricsJacksonSerializer() {
+            super(Metrics.class);
+        }
+
+        @Override
+        public void serialize(final Metrics metrics, final JsonGenerator 
jsonGenerator,
+                              final SerializerProvider serializerProvider) 
throws IOException {
+            final Map<String, Object> m = new HashMap<>();
+            m.put(GraphSONTokens.ID, metrics.getId());
+            m.put(GraphSONTokens.NAME, metrics.getName());
+            m.put(GraphSONTokens.COUNTS, metrics.getCounts());
+            m.put(GraphSONTokens.DURATION, 
metrics.getDuration(TimeUnit.NANOSECONDS) / 1000000d);
+
+            if (!metrics.getAnnotations().isEmpty()) {
+                m.put(GraphSONTokens.ANNOTATIONS, metrics.getAnnotations());
+            }
+            if (!metrics.getNested().isEmpty()) {
+                final List<Metrics> nested = new ArrayList<>();
+                metrics.getNested().forEach(it -> nested.add(it));
+                m.put(GraphSONTokens.METRICS, nested);
+            }
+            jsonGenerator.writeObject(m);
+        }
+    }
+
+
+    /**
+     * Maps in the JVM can have {@link Object} as a key, but in JSON they must 
be a {@link String}.
+     */
+    final static class GraphSONKeySerializer extends StdKeySerializer {
+
+        @Override
+        public void serialize(final Object o, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider) throws IOException {
+            ser(o, jsonGenerator, serializerProvider);
+        }
+
+        @Override
+        public void serializeWithType(final Object o, final JsonGenerator 
jsonGenerator,
+                                      final SerializerProvider 
serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            ser(o, jsonGenerator, serializerProvider);
+        }
+
+        private void ser(final Object o, final JsonGenerator jsonGenerator,
+                         final SerializerProvider serializerProvider) throws 
IOException {
+            if (Element.class.isAssignableFrom(o.getClass()))
+                jsonGenerator.writeFieldName((((Element) o).id()).toString());
+            else
+                super.serialize(o, jsonGenerator, serializerProvider);
+        }
+    }
+
+
+    //////////////////////////// DESERIALIZERS ///////////////////////////
+
+
+    static class VertexJacksonDeserializer extends 
AbstractObjectDeserializer<Vertex> {
+
+        public VertexJacksonDeserializer() {
+            super(Vertex.class);
+        }
+
+        @Override
+        public Vertex createObject(final Map<String, Object> vertexData) {
+            return new DetachedVertex(
+                    vertexData.get(GraphSONTokens.ID),
+                    (String) vertexData.getOrDefault(GraphSONTokens.LABEL, 
Vertex.DEFAULT_LABEL),
+                    (Map<String, Object>) 
vertexData.get(GraphSONTokens.PROPERTIES)
+            );
+        }
+    }
+
+    static class EdgeJacksonDeserializer extends 
AbstractObjectDeserializer<Edge> {
+
+        public EdgeJacksonDeserializer() {
+            super(Edge.class);
+        }
+
+        @Override
+        public Edge createObject(final Map<String, Object> edgeData) {
+            return new DetachedEdge(
+                    edgeData.get(GraphSONTokens.ID),
+                    (String) edgeData.getOrDefault(GraphSONTokens.LABEL, 
Edge.DEFAULT_LABEL),
+                    (Map<String, Object>) 
edgeData.get(GraphSONTokens.PROPERTIES),
+                    Pair.with(edgeData.get(GraphSONTokens.OUT), (String) 
edgeData.getOrDefault(GraphSONTokens.OUT_LABEL, Vertex.DEFAULT_LABEL)),
+                    Pair.with(edgeData.get(GraphSONTokens.IN), (String) 
edgeData.getOrDefault(GraphSONTokens.IN_LABEL, Vertex.DEFAULT_LABEL))
+            );
+        }
+    }
+
+    static class PropertyJacksonDeserializer extends 
AbstractObjectDeserializer<Property> {
+
+        public PropertyJacksonDeserializer() {
+            super(Property.class);
+        }
+
+        @Override
+        public Property createObject(final Map<String, Object> propData) {
+            Element element = null;
+            if (propData.containsKey(GraphSONTokens.VERTEX_PROPERTY)) {
+                final Map<String, Object> elementData = (Map<String, Object>) 
propData.get(GraphSONTokens.VERTEX_PROPERTY);
+                element = new 
VertexPropertyJacksonDeserializer().createObject(elementData);
+            } else if (propData.containsKey(GraphSONTokens.EDGE)) {
+                final Map<String, Object> elementData = (Map<String, Object>) 
propData.get(GraphSONTokens.EDGE);
+                element = new 
EdgeJacksonDeserializer().createObject(elementData);
+            }
+            return null != element ? // graphson-non-embedded is treated 
differently, but since this is a hard coded embedding...
+                    new DetachedProperty<>((String) 
propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE), element) :
+                    new DetachedProperty<>((String) 
propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE));
+        }
+    }
+
+    static class VertexPropertyJacksonDeserializer extends 
AbstractObjectDeserializer<VertexProperty> {
+
+        protected VertexPropertyJacksonDeserializer() {
+            super(VertexProperty.class);
+        }
+
+        @Override
+        public VertexProperty createObject(final Map<String, Object> propData) 
{
+            return propData.containsKey(GraphSONTokens.VERTEX) ?
+                    new DetachedVertexProperty<>(
+                            propData.get(GraphSONTokens.ID),
+                            (String) propData.get(GraphSONTokens.LABEL),
+                            propData.get(GraphSONTokens.VALUE),
+                            (Map<String, Object>) 
propData.get(GraphSONTokens.PROPERTIES),
+                            new 
DetachedVertex(propData.get(GraphSONTokens.VERTEX), Vertex.DEFAULT_LABEL, 
null)) :
+                    new DetachedVertexProperty<>(
+                            propData.get(GraphSONTokens.ID),
+                            (String) propData.get(GraphSONTokens.LABEL),
+                            propData.get(GraphSONTokens.VALUE),
+                            (Map<String, Object>) 
propData.get(GraphSONTokens.PROPERTIES));
+
+        }
+    }
+
+    static class PathJacksonDeserializer extends 
AbstractObjectDeserializer<Path> {
+
+        public PathJacksonDeserializer() {
+            super(Path.class);
+        }
+
+        @Override
+        public Path createObject(final Map<String, Object> pathData) {
+            final Path p = MutablePath.make();
+
+            final List labels = (List) pathData.get(GraphSONTokens.LABELS);
+            final List objects = (List) pathData.get(GraphSONTokens.OBJECTS);
+
+            for (int i = 0; i < objects.size(); i++) {
+                p.extend(objects.get(i), new HashSet((List) labels.get(i)));
+            }
+            return p;
+        }
+    }
+
+    static class MetricsJacksonDeserializer extends 
AbstractObjectDeserializer<Metrics> {
+        public MetricsJacksonDeserializer() {
+            super(Metrics.class);
+        }
+
+        @Override
+        public Metrics createObject(final Map<String, Object> metricsData) {
+            final MutableMetrics m = new MutableMetrics((String) 
metricsData.get(GraphSONTokens.ID), (String) 
metricsData.get(GraphSONTokens.NAME));
+
+            m.setDuration(Math.round((Double) 
metricsData.get(GraphSONTokens.DURATION) * 1000000), TimeUnit.NANOSECONDS);
+            for (Map.Entry<String, Long> count : ((Map<String, Long>) 
metricsData.getOrDefault(GraphSONTokens.COUNTS, 
Collections.emptyMap())).entrySet()) {
+                m.setCount(count.getKey(), count.getValue());
+            }
+            for (Map.Entry<String, Long> count : ((Map<String, Long>) 
metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, 
Collections.emptyMap())).entrySet()) {
+                m.setAnnotation(count.getKey(), count.getValue());
+            }
+            for (MutableMetrics nested : (List<MutableMetrics>) 
metricsData.getOrDefault(GraphSONTokens.METRICS, Collections.emptyList())) {
+                m.addNested(nested);
+            }
+            return m;
+        }
+    }
+
+    static class TraversalMetricsJacksonDeserializer extends 
AbstractObjectDeserializer<TraversalMetrics> {
+
+        public TraversalMetricsJacksonDeserializer() {
+            super(TraversalMetrics.class);
+        }
+
+        @Override
+        public TraversalMetrics createObject(final Map<String, Object> 
traversalMetricsData) {
+            return new DefaultTraversalMetrics(
+                    Math.round((Double) 
traversalMetricsData.get(GraphSONTokens.DURATION) * 1000000),
+                    (List<MutableMetrics>) 
traversalMetricsData.get(GraphSONTokens.METRICS)
+            );
+        }
+    }
+
+    static class TreeJacksonDeserializer extends StdDeserializer<Tree> {
+
+        public TreeJacksonDeserializer() {
+            super(Tree.class);
+        }
+
+        @Override
+        public Tree deserialize(final JsonParser jsonParser, final 
DeserializationContext deserializationContext) throws IOException, 
JsonProcessingException {
+            final List<Map> data = 
deserializationContext.readValue(jsonParser, List.class);
+            final Tree t = new Tree();
+            for (Map<String, Object> entry : data) {
+                t.put(entry.get(GraphSONTokens.KEY), 
entry.get(GraphSONTokens.VALUE));
+            }
+            return t;
+        }
+    }
+
+    static class IntegerJackonsDeserializer extends StdDeserializer<Integer> {
+
+        protected IntegerJackonsDeserializer() {
+            super(Integer.class);
+        }
+
+        @Override
+        public Integer deserialize(JsonParser jsonParser, 
DeserializationContext deserializationContext) throws IOException, 
JsonProcessingException {
+            return jsonParser.getIntValue();
+        }
+    }
+
+    static class DoubleJackonsDeserializer extends StdDeserializer<Double> {
+
+        protected DoubleJackonsDeserializer() {
+            super(Double.class);
+        }
+
+        @Override
+        public Double deserialize(JsonParser jsonParser, 
DeserializationContext deserializationContext) throws IOException, 
JsonProcessingException {
+            return jsonParser.getDoubleValue();
+        }
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7db10c40/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
index d804f0b..10e36e0 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
@@ -36,6 +36,7 @@ public final class GraphSONTokens {
     public static final String KEY = "key";
     public static final String EDGE = "edge";
     public static final String EDGES = "edges";
+    public static final String ELEMENT = "ELEMENT";
     public static final String VERTEX = "vertex";
     public static final String VERTEX_PROPERTY = "vertexProperty";
     public static final String VERTICES = "vertices";

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7db10c40/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
index 97292af..710c2bc 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
@@ -86,4 +86,11 @@ public final class GraphSONUtil {
             jsonGenerator.writeEndArray();
     }
 
+    static void safeWriteObjectField(final JsonGenerator jsonGenerator, final 
String key, final Object value) {
+        try {
+            jsonGenerator.writeObjectField(key, value);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7db10c40/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
index 7740b06..cb163e7 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
@@ -25,7 +25,8 @@ package org.apache.tinkerpop.gremlin.structure.io.graphson;
  */
 public enum GraphSONVersion {
     V1_0(GraphSONModule.GraphSONModuleV1d0.build(), "1.0"),
-    V2_0(GraphSONModule.GraphSONModuleV2d0.build(), "2.0");
+    V2_0(GraphSONModule.GraphSONModuleV2d0.build(), "2.0"),
+    V3_0(GraphSONModule.GraphSONModuleV3d0.build(), "3.0");
 
     private final GraphSONModule.GraphSONModuleBuilder builder;
     private final String versionNumber;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7db10c40/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0.java
----------------------------------------------------------------------
diff --git 
a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0.java
 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0.java
new file mode 100644
index 0000000..f6f2fc8
--- /dev/null
+++ 
b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0.java
@@ -0,0 +1,124 @@
+/*
+ * 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.driver.ser;
+
+import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
+import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.TypeInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Serialize results to JSON with version 3.0.x schema and the extended module.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public final class GraphSONMessageSerializerV3d0 extends 
AbstractGraphSONMessageSerializerV2d0 implements MessageTextSerializer {
+    private static final Logger logger = 
LoggerFactory.getLogger(GraphSONMessageSerializerV3d0.class);
+    private static final String MIME_TYPE = SerTokens.MIME_JSON;
+
+    private static byte[] header;
+
+    static {
+        final ByteBuffer buffer = ByteBuffer.allocate(MIME_TYPE.length() + 1);
+        buffer.put((byte) MIME_TYPE.length());
+        buffer.put(MIME_TYPE.getBytes());
+        header = buffer.array();
+    }
+
+    public GraphSONMessageSerializerV3d0() {
+        super();
+    }
+
+    public GraphSONMessageSerializerV3d0(final GraphSONMapper mapper) {
+        super(mapper);
+    }
+
+    @Override
+    public String[] mimeTypesSupported() {
+        return new String[]{MIME_TYPE, "application/json"};
+    }
+
+    @Override
+    GraphSONMapper.Builder configureBuilder(final GraphSONMapper.Builder 
builder) {
+        // override the 2.0 in AbstractGraphSONMessageSerializerV2d0
+        return 
builder.typeInfo(TypeInfo.PARTIAL_TYPES).version(GraphSONVersion.V3_0);
+    }
+
+    @Override
+    byte[] obtainHeader() {
+        return header;
+    }
+
+    @Override
+    public ResponseMessage deserializeResponse(final String msg) throws 
SerializationException {
+        try {
+            final Map<String, Object> responseData = mapper.readValue(msg, 
mapTypeReference);
+            final Map<String, Object> status = (Map<String, Object>) 
responseData.get(SerTokens.TOKEN_STATUS);
+            final Map<String, Object> result = (Map<String, Object>) 
responseData.get(SerTokens.TOKEN_RESULT);
+            return 
ResponseMessage.build(UUID.fromString(responseData.get(SerTokens.TOKEN_REQUEST).toString()))
+                    .code(ResponseStatusCode.getFromValue((Integer) 
status.get(SerTokens.TOKEN_CODE)))
+                    
.statusMessage(status.get(SerTokens.TOKEN_MESSAGE).toString())
+                    .statusAttributes((Map<String, Object>) 
status.get(SerTokens.TOKEN_ATTRIBUTES))
+                    .result(result.get(SerTokens.TOKEN_DATA))
+                    .responseMetaData((Map<String, Object>) 
result.get(SerTokens.TOKEN_META))
+                    .create();
+        } catch (Exception ex) {
+            logger.warn("Response [{}] could not be deserialized by {}.", msg, 
AbstractGraphSONMessageSerializerV2d0.class.getName());
+            throw new SerializationException(ex);
+        }
+    }
+
+    @Override
+    public String serializeResponseAsString(final ResponseMessage 
responseMessage) throws SerializationException {
+        try {
+            return mapper.writeValueAsString(responseMessage);
+        } catch (Exception ex) {
+            logger.warn("Response [{}] could not be serialized by {}.", 
responseMessage.toString(), 
AbstractGraphSONMessageSerializerV2d0.class.getName());
+            throw new SerializationException(ex);
+        }
+    }
+
+    @Override
+    public RequestMessage deserializeRequest(final String msg) throws 
SerializationException {
+        try {
+            return mapper.readValue(msg, RequestMessage.class);
+        } catch (Exception ex) {
+            logger.warn("Request [{}] could not be deserialized by {}.", msg, 
AbstractGraphSONMessageSerializerV2d0.class.getName());
+            throw new SerializationException(ex);
+        }
+    }
+
+    @Override
+    public String serializeRequestAsString(final RequestMessage 
requestMessage) throws SerializationException {
+        try {
+            return mapper.writeValueAsString(requestMessage);
+        } catch (Exception ex) {
+            logger.warn("Request [{}] could not be serialized by {}.", 
requestMessage.toString(), 
AbstractGraphSONMessageSerializerV2d0.class.getName());
+            throw new SerializationException(ex);
+        }
+    }
+}

Reply via email to