You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2017/07/01 18:17:38 UTC

[1/4] tinkerpop git commit: TINKERPOP-1427 Make GraphSON 3.0 serializers equivalent to 2.0

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1427 [created] 90f5ee331


TINKERPOP-1427 Make GraphSON 3.0 serializers equivalent to 2.0

There were some internal changes to GraphSON 2.0 deserializers that improved performance. Migrated all that to 3.0.


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

Branch: refs/heads/TINKERPOP-1427
Commit: 72ebd7e7de9bc6f0f183246b047e39e3142772b4
Parents: e5022c3
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 30 12:34:52 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jun 30 12:34:52 2017 -0400

----------------------------------------------------------------------
 .../io/graphson/GraphSONSerializersV3d0.java    | 204 +++++++++++++++----
 1 file changed, 163 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72ebd7e7/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
index b62094e..6f6e011 100644
--- 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
@@ -35,6 +35,7 @@ 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.DetachedFactory;
 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;
@@ -43,18 +44,22 @@ 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.core.JsonToken;
 import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 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.node.ArrayNode;
 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.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
 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;
@@ -239,8 +244,6 @@ class GraphSONSerializersV3d0 {
 
             jsonGenerator.writeEndObject();
         }
-
-
     }
 
     final static class PathJacksonSerializer extends StdScalarSerializer<Path> {
@@ -254,8 +257,10 @@ class GraphSONSerializersV3d0 {
                 throws IOException, JsonGenerationException {
             jsonGenerator.writeStartObject();
 
-            jsonGenerator.writeObjectField(GraphSONTokens.LABELS, path.labels());
-            jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, path.objects());
+            // paths shouldn't serialize with properties if the path contains graph elements
+            final Path p = DetachedFactory.detach(path, false);
+            jsonGenerator.writeObjectField(GraphSONTokens.LABELS, p.labels());
+            jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, p.objects());
 
             jsonGenerator.writeEndObject();
         }
@@ -417,89 +422,191 @@ class GraphSONSerializersV3d0 {
 
     //////////////////////////// DESERIALIZERS ///////////////////////////
 
-
-    static class VertexJacksonDeserializer extends AbstractObjectDeserializer<Vertex> {
+    static class VertexJacksonDeserializer extends StdDeserializer<Vertex> {
 
         public VertexJacksonDeserializer() {
             super(Vertex.class);
         }
 
+        public Vertex deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final DetachedVertex.Builder v = DetachedVertex.build();
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
+                    jsonParser.nextToken();
+                    v.setId(deserializationContext.readValue(jsonParser, Object.class));
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
+                    jsonParser.nextToken();
+                    v.setLabel(jsonParser.getText());
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
+                    jsonParser.nextToken();
+                    while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                        jsonParser.nextToken();
+                        while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
+                            v.addProperty((DetachedVertexProperty) deserializationContext.readValue(jsonParser, VertexProperty.class));
+                        }
+                    }
+                }
+            }
+
+            return v.create();
+        }
+
         @Override
-        public Vertex createObject(final Map<String, Object> vertexData) {
-            return new DetachedVertex(
-                    vertexData.get(GraphSONTokens.ID),
-                    vertexData.get(GraphSONTokens.LABEL).toString(),
-                    (Map<String, Object>) vertexData.get(GraphSONTokens.PROPERTIES)
-            );
+        public boolean isCachable() {
+            return true;
         }
     }
 
-    static class EdgeJacksonDeserializer extends AbstractObjectDeserializer<Edge> {
+    static class EdgeJacksonDeserializer extends StdDeserializer<Edge> {
 
         public EdgeJacksonDeserializer() {
             super(Edge.class);
         }
 
         @Override
-        public Edge createObject(final Map<String, Object> edgeData) {
-            return new DetachedEdge(
-                    edgeData.get(GraphSONTokens.ID),
-                    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())
-            );
+        public Edge deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final DetachedEdge.Builder e = DetachedEdge.build();
+            final DetachedVertex.Builder inV = DetachedVertex.build();
+            final DetachedVertex.Builder outV = DetachedVertex.build();
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
+                    jsonParser.nextToken();
+                    e.setId(deserializationContext.readValue(jsonParser, Object.class));
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
+                    jsonParser.nextToken();
+                    e.setLabel(jsonParser.getText());
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.OUT)) {
+                    jsonParser.nextToken();
+                    outV.setId(deserializationContext.readValue(jsonParser, Object.class));
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.OUT_LABEL)) {
+                    jsonParser.nextToken();
+                    outV.setLabel(jsonParser.getText());
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.IN)) {
+                    jsonParser.nextToken();
+                    inV.setId(deserializationContext.readValue(jsonParser, Object.class));
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.IN_LABEL)) {
+                    jsonParser.nextToken();
+                    inV.setLabel(jsonParser.getText());
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
+                    jsonParser.nextToken();
+                    while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                        jsonParser.nextToken();
+                        e.addProperty(deserializationContext.readValue(jsonParser, Property.class));
+                    }
+                }
+            }
+
+            e.setInV(inV.create());
+            e.setOutV(outV.create());
+
+            return e.create();
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 
-    static class PropertyJacksonDeserializer extends AbstractObjectDeserializer<Property> {
+    static class PropertyJacksonDeserializer extends StdDeserializer<Property> {
 
         public PropertyJacksonDeserializer() {
             super(Property.class);
         }
 
         @Override
-        public Property createObject(final Map<String, Object> propData) {
-            return new DetachedProperty(
-                    (String) propData.get(GraphSONTokens.KEY),
-                    propData.get(GraphSONTokens.VALUE));
+        public Property deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            String key = null;
+            Object value = null;
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.KEY)) {
+                    jsonParser.nextToken();
+                    key = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    value = deserializationContext.readValue(jsonParser, Object.class);
+                }
+            }
+
+            return new DetachedProperty<>(key, value);
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 
-    static class PathJacksonDeserializer extends AbstractObjectDeserializer<Path> {
+    static class PathJacksonDeserializer extends StdDeserializer<Path> {
+        private static final JavaType setType = TypeFactory.defaultInstance().constructCollectionType(HashSet.class, String.class);
 
         public PathJacksonDeserializer() {
             super(Path.class);
         }
 
         @Override
-        public Path createObject(final Map<String, Object> pathData) {
+        public Path deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final JsonNode n = jsonParser.readValueAsTree();
             final Path p = MutablePath.make();
 
-            final List labels = (List) pathData.get(GraphSONTokens.LABELS);
-            final List objects = (List) pathData.get(GraphSONTokens.OBJECTS);
+            final ArrayNode labels = (ArrayNode) n.get(GraphSONTokens.LABELS);
+            final ArrayNode objects = (ArrayNode) n.get(GraphSONTokens.OBJECTS);
 
             for (int i = 0; i < objects.size(); i++) {
-                p.extend(objects.get(i), new HashSet((List) labels.get(i)));
+                final JsonParser po = objects.get(i).traverse();
+                po.nextToken();
+                final JsonParser pl = labels.get(i).traverse();
+                pl.nextToken();
+                p.extend(deserializationContext.readValue(po, Object.class), deserializationContext.readValue(pl, setType));
             }
+
             return p;
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
-    static class VertexPropertyJacksonDeserializer extends AbstractObjectDeserializer<VertexProperty> {
+    static class VertexPropertyJacksonDeserializer extends StdDeserializer<VertexProperty> {
+        private static final JavaType propertiesType = TypeFactory.defaultInstance().constructMapType(HashMap.class, String.class, Object.class);
 
         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)
-            );
+        public VertexProperty deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final DetachedVertexProperty.Builder vp = DetachedVertexProperty.build();
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
+                    jsonParser.nextToken();
+                    vp.setId(deserializationContext.readValue(jsonParser, Object.class));
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
+                    jsonParser.nextToken();
+                    vp.setLabel(jsonParser.getText());
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    vp.setValue(deserializationContext.readValue(jsonParser, Object.class));
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
+                    jsonParser.nextToken();
+                    while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                        final String key = jsonParser.getCurrentName();
+                        jsonParser.nextToken();
+                        final Object val = deserializationContext.readValue(jsonParser, Object.class);
+                        vp.addProperty(new DetachedProperty(key, val));
+                    }
+                }
+            }
+
+            return vp.create();
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 
@@ -556,6 +663,11 @@ class GraphSONSerializersV3d0 {
             }
             return t;
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     static class IntegerJackonsDeserializer extends StdDeserializer<Integer> {
@@ -568,6 +680,11 @@ class GraphSONSerializersV3d0 {
         public Integer deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             return jsonParser.getIntValue();
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     static class DoubleJackonsDeserializer extends StdDeserializer<Double> {
@@ -580,5 +697,10 @@ class GraphSONSerializersV3d0 {
         public Double deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             return jsonParser.getDoubleValue();
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
-}
\ No newline at end of file
+}


[3/4] tinkerpop git commit: TINKERPOP-1427 Added g:Map for GraphSON 3.0

Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
index 9079c8a..eaf12cf 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
@@ -43,7 +43,12 @@ import java.time.YearMonth;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
+import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.Matchers.either;
 import static org.hamcrest.core.StringStartsWith.startsWith;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assume.assumeThat;
@@ -61,6 +66,9 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
                 {"v2", GraphSONMapper.build().version(GraphSONVersion.V2_0)
                         .addCustomModule(GraphSONXModuleV2d0.build().create(false))
                         .typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()},
+                {"v3", GraphSONMapper.build().version(GraphSONVersion.V3_0)
+                        .addCustomModule(GraphSONXModuleV3d0.build().create(false))
+                        .typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()}
         });
     }
 
@@ -72,8 +80,23 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
     public String version;
 
     @Test
+    public void shouldHandleMap() throws Exception {
+        assumeThat(version, startsWith("v3"));
+
+        final Map<Object,Object> o = new HashMap<>();
+        o.put("string key", "string value");
+        o.put(1, 1);
+        o.put(1L, 1L);
+
+        final List<Object> l = Arrays.asList("test", 1, 5L);
+        o.put(l, "crazy");
+
+        assertEquals(o, serializeDeserialize(mapper, o, Map.class));
+    }
+
+    @Test
     public void shouldHandleBiFunctionLambda() throws Exception {
-        assumeThat(version, startsWith("v2"));
+        assumeThat(version, either(startsWith("v2")).or(startsWith("v3")));
 
         final Lambda o = (Lambda) Lambda.biFunction("x,y -> 'test'");
         assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
@@ -81,7 +104,7 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
 
     @Test
     public void shouldHandleComparatorLambda() throws Exception {
-        assumeThat(version, startsWith("v2"));
+        assumeThat(version, either(startsWith("v2")).or(startsWith("v3")));
 
         final Lambda o = (Lambda) Lambda.comparator("x,y -> x <=> y");
         assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
@@ -89,7 +112,7 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
 
     @Test
     public void shouldHandleConsumerLambda() throws Exception {
-        assumeThat(version, startsWith("v2"));
+        assumeThat(version, either(startsWith("v2")).or(startsWith("v3")));
 
         final Lambda o = (Lambda) Lambda.consumer("x -> x");
         assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
@@ -97,7 +120,7 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
 
     @Test
     public void shouldHandleFunctionLambda() throws Exception {
-        assumeThat(version, startsWith("v2"));
+        assumeThat(version, either(startsWith("v2")).or(startsWith("v3")));
 
         final Lambda o = (Lambda) Lambda.function("x -> x");
         assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
@@ -105,7 +128,7 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
 
     @Test
     public void shouldHandlePredicateLambda() throws Exception {
-        assumeThat(version, startsWith("v2"));
+        assumeThat(version, either(startsWith("v2")).or(startsWith("v3")));
 
         final Lambda o = (Lambda) Lambda.predicate("x -> true");
         assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
@@ -113,7 +136,7 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
 
     @Test
     public void shouldHandleSupplierLambda() throws Exception {
-        assumeThat(version, startsWith("v2"));
+        assumeThat(version, either(startsWith("v2")).or(startsWith("v3")));
 
         final Lambda o = (Lambda) Lambda.supplier("'test'");
         assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
@@ -121,7 +144,7 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
 
     @Test
     public void shouldHandleBytecodeBinding() throws Exception {
-        assumeThat(version, startsWith("v2"));
+        assumeThat(version, either(startsWith("v2")).or(startsWith("v3")));
 
         final Bytecode.Binding<String> o = new Bytecode.Binding<>("test", "testing");
         assertEquals(o, serializeDeserialize(mapper, o, Bytecode.Binding.class));
@@ -129,7 +152,7 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
 
     @Test
     public void shouldHandleTraverser() throws Exception {
-        assumeThat(version, startsWith("v2"));
+        assumeThat(version, either(startsWith("v2")).or(startsWith("v3")));
 
         final Traverser<String> o = new DefaultRemoteTraverser<>("test", 100);
         assertEquals(o, serializeDeserialize(mapper, o, Traverser.class));

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
new file mode 100644
index 0000000..14fdf7a
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
@@ -0,0 +1,297 @@
+/*
+ * 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.remote.traversal.DefaultRemoteTraverser;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests automatic typed serialization/deserialization for GraphSON 2.0+.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class GraphSONMapperPartialEmbeddedTypeTest extends AbstractGraphSONTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"v2", GraphSONMapper.build().version(GraphSONVersion.V2_0)
+                        .addCustomModule(GraphSONXModuleV2d0.build().create(false))
+                        .typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()},
+                {"v3", GraphSONMapper.build().version(GraphSONVersion.V3_0)
+                        .addCustomModule(GraphSONXModuleV3d0.build().create(false))
+                        .typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()}
+        });
+    }
+
+    @Parameterized.Parameter(1)
+    public ObjectMapper mapper;
+
+
+    @Parameterized.Parameter(0)
+    public String version;
+
+    @Test
+    public void shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly() throws Exception {
+        // Trying to fail the TypeDeserializer type detection
+        final UUID uuid = UUID.randomUUID();
+        final List<Object> myList = new ArrayList<>();
+
+        final List<Object> myList2 = new ArrayList<>();
+        myList2.add(UUID.randomUUID());
+        myList2.add(33L);
+        myList2.add(84);
+        final Map<String,Object> map2 = new HashMap<>();
+        map2.put("eheh", UUID.randomUUID());
+        map2.put("normal", "normal");
+        myList2.add(map2);
+
+        final Map<String, Object> map1 = new HashMap<>();
+        map1.put("hello", "world");
+        map1.put("test", uuid);
+        map1.put("hehe", myList2);
+        myList.add(map1);
+
+        myList.add("kjkj");
+        myList.add(UUID.randomUUID());
+        assertEquals(myList, serializeDeserializeAuto(mapper, myList));
+
+        // no "@value" property
+        String s = "{\""+GraphSONTokens.VALUETYPE+"\":\"" + GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":UUID\", \"test\":2}";
+        Map<String,Object> map = new LinkedHashMap<>();
+        map.put(GraphSONTokens.VALUETYPE, GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":UUID");
+        map.put("test", 2);
+        Object res = mapper.readValue(s, Object.class);
+        assertEquals(map, res);
+
+        // "@value" and "@type" property reversed
+        s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \"" + GraphSONTokens.VALUETYPE + "\":\"" + GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":Int64\"}";
+        res = mapper.readValue(s, Object.class);
+        assertEquals(res, 2L);
+        assertEquals(res.getClass(), Long.class);
+
+        // no "@type" property.
+        s = "{\""+GraphSONTokens.VALUEPROP + "\":2, \"id\":2}";
+        map = new LinkedHashMap<>();
+        map.put(GraphSONTokens.VALUEPROP, 2);
+        map.put("id", 2);
+        res = mapper.readValue(s, Object.class);
+        assertEquals(res, map);
+    }
+
+    @Test
+    public void shouldFailIfMoreThanTwoPropertiesInATypePattern() {
+        String s = "{\"" + GraphSONTokens.VALUEPROP + "\":2, \"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":Int64\", \"hello\": \"world\"}";
+        try {
+            mapper.readValue(s, Object.class);
+            fail("Should have failed deserializing because there's more than properties in the type.");
+        } catch (IOException e) {
+            assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
+        }
+        s = "{\"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":Int64\",\"" + GraphSONTokens.VALUEPROP + "\":2, \"hello\": \"world\"}";
+        try {
+            mapper.readValue(s, Object.class);
+            fail("Should have failed deserializing because there's more than properties in the type.");
+        } catch (IOException e) {
+            assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
+        }
+    }
+
+    @Test
+    public void shouldFailIfTypeSpecifiedIsNotSameTypeInPayload() {
+        final ZoneOffset o = ZonedDateTime.now().getOffset();
+        final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+        try {
+            mapper.writeValue(stream, o);
+            final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray());
+            // What has been serialized is a ZoneOffset with the type, but the user explicitly requires another type.
+            mapper.readValue(inputStream, Instant.class);
+            fail("Should have failed decoding the value");
+        } catch (Exception e) {
+            assertThat(e.getMessage(), containsString("Could not deserialize the JSON value as required. Nested exception: java.lang.InstantiationException: Cannot deserialize the value with the detected type contained in the JSON ('" + GraphSONTokens.GREMLINX_TYPE_NAMESPACE + ":ZoneOffset') to the type specified in parameter to the object mapper (class java.time.Instant). Those types are incompatible."));
+        }
+    }
+
+    @Test
+    public void shouldHandleRawPOJOs() throws Exception {
+        final FunObject funObject = new FunObject();
+        funObject.setVal("test");
+        assertEquals(funObject.toString(), serializeDeserialize(mapper, funObject, FunObject.class).toString());
+        assertEquals(funObject.getClass(), serializeDeserialize(mapper, funObject, FunObject.class).getClass());
+    }
+
+    @Test
+    public void shouldHandleMapWithTypesUsingEmbedTypeSettingV2d0() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V2_0)
+                .embedTypes(true)
+                .create()
+                .createMapper();
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("test", 100L);
+
+        final String json = mapper.writeValueAsString(m);
+        final Map read = mapper.readValue(json, HashMap.class);
+
+        assertEquals(100L, read.get("test"));
+    }
+
+    @Test
+    public void shouldNotHandleMapWithTypesUsingEmbedTypeSettingV2d0() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V2_0)
+                .embedTypes(false)
+                .create()
+                .createMapper();
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("test", 100L);
+
+        final String json = mapper.writeValueAsString(m);
+        final Map read = mapper.readValue(json, HashMap.class);
+
+        assertEquals(100, read.get("test"));
+    }
+
+    @Test
+    public void shouldHandleMapWithTypesUsingEmbedTypeSettingV1d0() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V1_0)
+                .typeInfo(TypeInfo.PARTIAL_TYPES)
+                .create()
+                .createMapper();
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("test", 100L);
+
+        final String json = mapper.writeValueAsString(m);
+        final Map read = mapper.readValue(json, HashMap.class);
+
+        assertEquals(100L, read.get("test"));
+    }
+
+    @Test
+    public void shouldNotHandleMapWithTypesUsingEmbedTypeSettingV1d0() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V1_0)
+                .typeInfo(TypeInfo.NO_TYPES)
+                .create()
+                .createMapper();
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("test", 100L);
+
+        final String json = mapper.writeValueAsString(m);
+        final Map read = mapper.readValue(json, HashMap.class);
+
+        assertEquals(100, read.get("test"));
+    }
+
+    @Test
+    public void shouldLooseTypesInfoWithGraphSONNoType() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V2_0)
+                .typeInfo(TypeInfo.NO_TYPES)
+                .create()
+                .createMapper();
+
+        final UUID uuid = UUID.randomUUID();
+        final List<Object> myList = new ArrayList<>();
+
+        final List<Object> myList2 = new ArrayList<>();
+        myList2.add(UUID.randomUUID());
+        myList2.add(33L);
+        myList2.add(84);
+        final Map<String,Object> map2 = new HashMap<>();
+        map2.put("eheh", UUID.randomUUID());
+        map2.put("normal", "normal");
+        myList2.add(map2);
+
+        final Map<String, Object> map1 = new HashMap<>();
+        map1.put("hello", "world");
+        map1.put("test", uuid);
+        map1.put("hehe", myList2);
+        myList.add(map1);
+
+        myList.add("kjkj");
+        myList.add(UUID.randomUUID());
+
+        final String json = mapper.writeValueAsString(myList);
+        final Object read = mapper.readValue(json, Object.class);
+
+        // Not equals because of type loss
+        assertNotEquals(myList, read);
+    }
+
+    @Test
+    public void shouldHandleDefaultRemoteTraverser() throws Exception {
+        final DefaultRemoteTraverser<String> o = new DefaultRemoteTraverser<>("test", 100);
+        assertEquals(o, serializeDeserialize(mapper, o, Traverser.class));
+    }
+
+    // Class needs to be defined as statics as it's a nested class.
+    public static class FunObject {
+        private String val;
+
+        public FunObject() {
+        }
+
+        public String getVal() {
+            return this.val;
+        }
+
+        public void setVal(String s) {
+            this.val = s;
+        }
+
+        public String toString() {
+            return this.val;
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
index 217cc6f..aa2a467 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
@@ -48,6 +48,9 @@ import static org.junit.Assert.assertEquals;
 @RunWith(Parameterized.class)
 public class GraphSONMapperTest {
 
+    /**
+     * No need to test V3 as it does not have an option to be constructed without types
+     */
     @Parameterized.Parameters(name = "{0}")
     public static Iterable<Object[]> data() {
         return Arrays.asList(new Object[][]{

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
deleted file mode 100644
index 28107d0..0000000
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tinkerpop.gremlin.structure.io.graphson;
-
-import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
-import org.junit.Test;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.time.Instant;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.StringContains.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.fail;
-
-/**
- * Tests automatic typed serialization/deserialization for GraphSON 2.0.
- */
-public class GraphSONMapperV2d0PartialEmbeddedTypeTest extends AbstractGraphSONTest {
-
-    private final ObjectMapper mapper = GraphSONMapper.build()
-            .version(GraphSONVersion.V2_0)
-            .addCustomModule(GraphSONXModuleV2d0.build().create(false))
-            .typeInfo(TypeInfo.PARTIAL_TYPES)
-            .create()
-            .createMapper();
-
-    @Test
-    public void shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly() throws Exception {
-        // Trying to fail the TypeDeserializer type detection
-        final UUID uuid = UUID.randomUUID();
-        final List<Object> myList = new ArrayList<>();
-
-        final List<Object> myList2 = new ArrayList<>();
-        myList2.add(UUID.randomUUID());
-        myList2.add(33L);
-        myList2.add(84);
-        final Map<String,Object> map2 = new HashMap<>();
-        map2.put("eheh", UUID.randomUUID());
-        map2.put("normal", "normal");
-        myList2.add(map2);
-
-        final Map<String, Object> map1 = new HashMap<>();
-        map1.put("hello", "world");
-        map1.put("test", uuid);
-        map1.put("hehe", myList2);
-        myList.add(map1);
-
-        myList.add("kjkj");
-        myList.add(UUID.randomUUID());
-        assertEquals(myList, serializeDeserializeAuto(mapper, myList));
-
-        // no "@value" property
-        String s = "{\""+GraphSONTokens.VALUETYPE+"\":\"" + GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":UUID\", \"test\":2}";
-        Map<String,Object> map = new LinkedHashMap<>();
-        map.put(GraphSONTokens.VALUETYPE, GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":UUID");
-        map.put("test", 2);
-        Object res = mapper.readValue(s, Object.class);
-        assertEquals(map, res);
-
-        // "@value" and "@type" property reversed
-        s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \"" + GraphSONTokens.VALUETYPE + "\":\"" + GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":Int64\"}";
-        res = mapper.readValue(s, Object.class);
-        assertEquals(res, 2L);
-        assertEquals(res.getClass(), Long.class);
-
-        // no "@type" property.
-        s = "{\""+GraphSONTokens.VALUEPROP + "\":2, \"id\":2}";
-        map = new LinkedHashMap<>();
-        map.put(GraphSONTokens.VALUEPROP, 2);
-        map.put("id", 2);
-        res = mapper.readValue(s, Object.class);
-        assertEquals(res, map);
-    }
-
-    @Test
-    public void shouldFailIfMoreThanTwoPropertiesInATypePattern() {
-        String s = "{\"" + GraphSONTokens.VALUEPROP + "\":2, \"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":Int64\", \"hello\": \"world\"}";
-        try {
-            mapper.readValue(s, Object.class);
-            fail("Should have failed deserializing because there's more than properties in the type.");
-        } catch (IOException e) {
-            assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
-        }
-        s = "{\"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":Int64\",\"" + GraphSONTokens.VALUEPROP + "\":2, \"hello\": \"world\"}";
-        try {
-            mapper.readValue(s, Object.class);
-            fail("Should have failed deserializing because there's more than properties in the type.");
-        } catch (IOException e) {
-            assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
-        }
-    }
-
-    @Test
-    public void shouldFailIfTypeSpecifiedIsNotSameTypeInPayload() {
-        final ZoneOffset o = ZonedDateTime.now().getOffset();
-        final ByteArrayOutputStream stream = new ByteArrayOutputStream();
-        try {
-            mapper.writeValue(stream, o);
-            final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray());
-            // What has been serialized is a ZoneOffset with the type, but the user explicitly requires another type.
-            mapper.readValue(inputStream, Instant.class);
-            fail("Should have failed decoding the value");
-        } catch (Exception e) {
-            assertThat(e.getMessage(), containsString("Could not deserialize the JSON value as required. Nested exception: java.lang.InstantiationException: Cannot deserialize the value with the detected type contained in the JSON ('" + GraphSONTokens.GREMLINX_TYPE_NAMESPACE + ":ZoneOffset') to the type specified in parameter to the object mapper (class java.time.Instant). Those types are incompatible."));
-        }
-    }
-
-    @Test
-    public void shouldHandleRawPOJOs() throws Exception {
-        final FunObject funObject = new FunObject();
-        funObject.setVal("test");
-        assertEquals(funObject.toString(), serializeDeserialize(mapper, funObject, FunObject.class).toString());
-        assertEquals(funObject.getClass(), serializeDeserialize(mapper, funObject, FunObject.class).getClass());
-    }
-
-    @Test
-    public void shouldHandleMapWithTypesUsingEmbedTypeSettingV2d0() throws Exception {
-        final ObjectMapper mapper = GraphSONMapper.build()
-                .version(GraphSONVersion.V2_0)
-                .embedTypes(true)
-                .create()
-                .createMapper();
-
-        final Map<String,Object> m = new HashMap<>();
-        m.put("test", 100L);
-
-        final String json = mapper.writeValueAsString(m);
-        final Map read = mapper.readValue(json, HashMap.class);
-
-        assertEquals(100L, read.get("test"));
-    }
-
-    @Test
-    public void shouldNotHandleMapWithTypesUsingEmbedTypeSettingV2d0() throws Exception {
-        final ObjectMapper mapper = GraphSONMapper.build()
-                .version(GraphSONVersion.V2_0)
-                .embedTypes(false)
-                .create()
-                .createMapper();
-
-        final Map<String,Object> m = new HashMap<>();
-        m.put("test", 100L);
-
-        final String json = mapper.writeValueAsString(m);
-        final Map read = mapper.readValue(json, HashMap.class);
-
-        assertEquals(100, read.get("test"));
-    }
-
-    @Test
-    public void shouldHandleMapWithTypesUsingEmbedTypeSettingV1d0() throws Exception {
-        final ObjectMapper mapper = GraphSONMapper.build()
-                .version(GraphSONVersion.V1_0)
-                .typeInfo(TypeInfo.PARTIAL_TYPES)
-                .create()
-                .createMapper();
-
-        final Map<String,Object> m = new HashMap<>();
-        m.put("test", 100L);
-
-        final String json = mapper.writeValueAsString(m);
-        final Map read = mapper.readValue(json, HashMap.class);
-
-        assertEquals(100L, read.get("test"));
-    }
-
-    @Test
-    public void shouldNotHandleMapWithTypesUsingEmbedTypeSettingV1d0() throws Exception {
-        final ObjectMapper mapper = GraphSONMapper.build()
-                .version(GraphSONVersion.V1_0)
-                .typeInfo(TypeInfo.NO_TYPES)
-                .create()
-                .createMapper();
-
-        final Map<String,Object> m = new HashMap<>();
-        m.put("test", 100L);
-
-        final String json = mapper.writeValueAsString(m);
-        final Map read = mapper.readValue(json, HashMap.class);
-
-        assertEquals(100, read.get("test"));
-    }
-
-    @Test
-    public void shouldLooseTypesInfoWithGraphSONNoType() throws Exception {
-        final ObjectMapper mapper = GraphSONMapper.build()
-                .version(GraphSONVersion.V2_0)
-                .typeInfo(TypeInfo.NO_TYPES)
-                .create()
-                .createMapper();
-
-        final UUID uuid = UUID.randomUUID();
-        final List<Object> myList = new ArrayList<>();
-
-        final List<Object> myList2 = new ArrayList<>();
-        myList2.add(UUID.randomUUID());
-        myList2.add(33L);
-        myList2.add(84);
-        final Map<String,Object> map2 = new HashMap<>();
-        map2.put("eheh", UUID.randomUUID());
-        map2.put("normal", "normal");
-        myList2.add(map2);
-
-        final Map<String, Object> map1 = new HashMap<>();
-        map1.put("hello", "world");
-        map1.put("test", uuid);
-        map1.put("hehe", myList2);
-        myList.add(map1);
-
-        myList.add("kjkj");
-        myList.add(UUID.randomUUID());
-
-        final String json = mapper.writeValueAsString(myList);
-        final Object read = mapper.readValue(json, Object.class);
-
-        // Not equals because of type loss
-        assertNotEquals(myList, read);
-    }
-
-    @Test
-    public void shouldHandleDefaultRemoteTraverser() throws Exception {
-        final DefaultRemoteTraverser<String> o = new DefaultRemoteTraverser<>("test", 100);
-        assertEquals(o, serializeDeserialize(mapper, o, Traverser.class));
-    }
-
-    // Class needs to be defined as statics as it's a nested class.
-    public static class FunObject {
-        private String val;
-
-        public FunObject() {
-        }
-
-        public String getVal() {
-            return this.val;
-        }
-
-        public void setVal(String s) {
-            this.val = s;
-        }
-
-        public String toString() {
-            return this.val;
-        }
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0Test.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0Test.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0Test.java
index c1e43b5..b4f49d7 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0Test.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV3d0Test.java
@@ -34,7 +34,6 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.apache.tinkerpop.shaded.jackson.databind.util.StdDateFormat;
 import org.junit.Test;
 
 import java.util.ArrayList;
@@ -132,15 +131,15 @@ public class GraphSONMessageSerializerV3d0Test {
         final ResponseMessage response = convert(IteratorUtils.asList(map.entrySet()));
         assertCommon(response);
 
-        final List<Map<String, Object>> deserializedEntries = (List<Map<String, Object>>) response.getResult().getData();
+        final List<Map.Entry<Object, Object>> deserializedEntries = (List<Map.Entry<Object, Object>>) response.getResult().getData();
         assertEquals(3, deserializedEntries.size());
         deserializedEntries.forEach(e -> {
-            if (e.containsKey("x"))
-                assertEquals(1, e.get("x"));
-            else if (e.containsKey(v1.id().toString()))
-                assertEquals(100, e.get(v1.id().toString()));
-            else if (e.containsKey(StdDateFormat.instance.format(d)))
-                assertEquals("test", e.get(StdDateFormat.instance.format(d)));
+            if (e.getKey().equals("x"))
+                assertEquals(1, e.getValue());
+            else if (e.getKey() instanceof Vertex && e.getKey().equals(v1))
+                assertEquals(100, e.getValue());
+            else if (e.getKey() instanceof Date)
+                assertEquals("test", e.getValue());
             else
                 fail("Map entries contains a key that is not part of what was serialized");
         });
@@ -246,17 +245,15 @@ public class GraphSONMessageSerializerV3d0Test {
         final TinkerGraph graph = TinkerFactory.createClassic();
         final GraphTraversalSource g = graph.traversal();
         final Map<Vertex, Integer> map = new HashMap<>();
-        map.put(g.V().has("name", "marko").next(), 1000);
+        final Vertex v1 = g.V().has("name", "marko").next();
+        map.put(v1, 1000);
 
         final ResponseMessage response = convert(map);
         assertCommon(response);
 
-        final Map<String, Integer> deserializedMap = (Map<String, Integer>) response.getResult().getData();
+        final Map<Vertex, Integer> deserializedMap = (Map<Vertex, Integer>) response.getResult().getData();
         assertEquals(1, deserializedMap.size());
-
-        // with no embedded types the key (which is a vertex) simply serializes out to an id
-        // {"result":{"1":1000},"code":200,"requestId":"2d62161b-9544-4f39-af44-62ec49f9a595","type":0}
-        assertEquals(new Integer(1000), deserializedMap.get("1"));
+        assertEquals(new Integer(1000), deserializedMap.get(v1));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
index df3bb9d..9f6dfbd 100644
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
@@ -31,6 +31,7 @@ import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONWriter;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONXModuleV2d0;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONXModuleV3d0;
 import org.apache.tinkerpop.shaded.jackson.core.JsonFactory;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 
@@ -53,10 +54,10 @@ final class PythonGraphSONJavaTranslator<S extends TraversalSource, T extends Tr
     private final JavaTranslator<S, T> javaTranslator;
     private final GraphSONReader reader = GraphSONReader.build().mapper(
             GraphSONMapper.build().addCustomModule(GraphSONXModuleV2d0.build().create(false))
-                    .version(GraphSONVersion.V3_0).create()).create();
+                    .version(GraphSONVersion.V2_0).create()).create();
     private final GraphSONWriter writer = GraphSONWriter.build().mapper(
             GraphSONMapper.build().addCustomModule(GraphSONXModuleV2d0.build().create(false))
-                    .version(GraphSONVersion.V3_0).create()).create();
+                    .version(GraphSONVersion.V2_0).create()).create();
 
     public PythonGraphSONJavaTranslator(final PythonTranslator pythonTranslator, final JavaTranslator<S, T> javaTranslator) {
         this.pythonTranslator = pythonTranslator;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
index 41daf5b..41fb79a 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
@@ -767,6 +767,40 @@ public class GremlinDriverIntegrateTest extends AbstractGremlinServerIntegration
     }
 
     @Test
+    public void shouldWorkWithGraphSONV3Serialization() throws Exception {
+        final Cluster cluster = TestClientFactory.build().serializer(Serializers.GRAPHSON_V3D0).create();
+        final Client client = cluster.connect();
+
+        final List<Result> r = client.submit("TinkerFactory.createModern().traversal().V(1)").all().join();
+        assertEquals(1, r.size());
+
+        final Vertex v = r.get(0).get(DetachedVertex.class);
+        assertEquals(1, v.id());
+        assertEquals("person", v.label());
+
+        assertEquals(2, IteratorUtils.count(v.properties()));
+        assertEquals("marko", v.value("name"));
+        assertEquals(29, Integer.parseInt(v.value("age").toString()));
+
+        cluster.close();
+    }
+
+    @Test
+    public void shouldWorkWithGraphSONExtendedV3Serialization() throws Exception {
+        final Cluster cluster = TestClientFactory.build().serializer(Serializers.GRAPHSON_V3D0).create();
+        final Client client = cluster.connect();
+
+        final Instant now = Instant.now();
+        final List<Result> r = client.submit("java.time.Instant.ofEpochMilli(" + now.toEpochMilli() + ")").all().join();
+        assertEquals(1, r.size());
+
+        final Instant then = r.get(0).get(Instant.class);
+        assertEquals(now, then);
+
+        cluster.close();
+    }
+
+    @Test
     @org.junit.Ignore("Can't seem to make this test pass consistently")
     public void shouldHandleRequestSentThatNeverReturns() throws Exception {
         final Cluster cluster = TestClientFactory.open();

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java
index 5d90f9c..bcce801 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerAuditLogIntegrateTest.java
@@ -23,6 +23,8 @@ import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
+import org.apache.log4j.Appender;
+import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
 import org.apache.log4j.spi.LoggingEvent;
 import static org.apache.log4j.Level.INFO;
@@ -336,6 +338,11 @@ public class GremlinServerAuditLogIntegrateTest extends AbstractGremlinServerInt
             cluster.close();
             cluster2.close();
         }
+
+        // for some reason a pause here helps the server "catch-up" logging messages.  hopefully this reduces the
+        // number of failed tests here
+        Thread.sleep(3000);
+
         final List<LoggingEvent> log = recordingAppender.getEvents();
         final Stream<LoggingEvent> auditEvents = log.stream().filter(event -> event.getLoggerName().equals(AUDIT_LOGGER_NAME));
         final Iterator<LoggingEvent> authEvents = auditEvents

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
index ec878de..643657f 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
@@ -749,7 +749,7 @@ public class GremlinServerHttpIntegrateTest extends AbstractGremlinServerIntegra
             final String json = EntityUtils.toString(response.getEntity());
             final JsonNode node = mapper.readTree(json);
             assertEquals(true, node.get("result").get("data").get(0).isObject());
-            assertEquals(1, node.get("result").get("data").get(0).get("y").get("@value").asInt());
+            assertEquals(1, node.get("result").get("data").get(0).get("@value").get(1).get("@value").asInt());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 90076d5..105e19d 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -809,7 +809,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
 
     @Test
     public void shouldReceiveFailureOnBadGraphSONSerialization() throws Exception {
-        final Cluster cluster = TestClientFactory.build().serializer(Serializers.GRAPHSON_V2D0).create();
+        final Cluster cluster = TestClientFactory.build().serializer(Serializers.GRAPHSON_V3D0).create();
         final Client client = cluster.connect();
 
         try {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java
index f7340f8..35c1add 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java
@@ -58,7 +58,8 @@ public class IoCustomTest extends AbstractGremlinTest {
         final SimpleModule moduleV1d0 = new SimpleModule();
         moduleV1d0.addSerializer(CustomId.class, new CustomId.CustomIdJacksonSerializerV1d0());
 
-        final SimpleModule moduleV2d0 = new CustomId.CustomIdTinkerPopJacksonModule();
+        final SimpleModule moduleV2d0 = new CustomId.CustomIdTinkerPopJacksonModuleV2d0();
+        final SimpleModule modulev3d0 = new CustomId.CustomIdTinkerPopJacksonModuleV3d0();
 
         return Arrays.asList(new Object[][]{
                 {"graphson-v1-embedded", true,
@@ -68,8 +69,8 @@ public class IoCustomTest extends AbstractGremlinTest {
                         (Function<Graph, GraphReader>) g -> g.io(IoCore.graphson()).reader().mapper(g.io(GraphSONIo.build(GraphSONVersion.V2_0)).mapper().addCustomModule(moduleV2d0).typeInfo(TypeInfo.PARTIAL_TYPES).create()).create(),
                         (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().mapper(g.io(GraphSONIo.build(GraphSONVersion.V2_0)).mapper().addCustomModule(moduleV2d0).typeInfo(TypeInfo.PARTIAL_TYPES).create()).create()},
                 {"graphson-v3", true,
-                        (Function<Graph, GraphReader>) g -> g.io(IoCore.graphson()).reader().mapper(g.io(GraphSONIo.build(GraphSONVersion.V3_0)).mapper().addCustomModule(moduleV2d0).create()).create(),
-                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().mapper(g.io(GraphSONIo.build(GraphSONVersion.V3_0)).mapper().addCustomModule(moduleV2d0).create()).create()},
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.graphson()).reader().mapper(g.io(GraphSONIo.build(GraphSONVersion.V3_0)).mapper().addCustomModule(modulev3d0).create()).create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().mapper(g.io(GraphSONIo.build(GraphSONVersion.V3_0)).mapper().addCustomModule(modulev3d0).create()).create()},
                 {"gryo", true,
                         (Function<Graph, GraphReader>) g -> g.io(IoCore.gryo()).reader().mapper(g.io(IoCore.gryo()).mapper().addCustom(CustomId.class).create()).create(),
                         (Function<Graph, GraphWriter>) g -> g.io(IoCore.gryo()).writer().mapper(g.io(IoCore.gryo()).mapper().addCustom(CustomId.class).create()).create()}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java
index 1605708..ec39a8f 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java
@@ -597,7 +597,7 @@ public class IoTest {
             final UUID id = UUID.fromString("AF4B5965-B176-4552-B3C1-FBBE2F52C305");
             graph.addVertex(T.id, new CustomId("vertex", id));
 
-            final SimpleModule module = new CustomId.CustomIdTinkerPopJacksonModule();
+            final SimpleModule module = new CustomId.CustomIdTinkerPopJacksonModuleV2d0();
             final GraphWriter writer = graph.io(graphson).writer().mapper(
                     graph.io(graphson).mapper().version(GraphSONVersion.V2_0).addCustomModule(module).create()).create();
 
@@ -720,7 +720,7 @@ public class IoTest {
             final UUID id = UUID.fromString("AF4B5965-B176-4552-B3C1-FBBE2F52C305");
             graph.addVertex(T.id, new CustomId("vertex", id));
 
-            final SimpleModule module = new CustomId.CustomIdTinkerPopJacksonModule();
+            final SimpleModule module = new CustomId.CustomIdTinkerPopJacksonModuleV3d0();
             final GraphWriter writer = graph.io(graphson).writer().mapper(
                     graph.io(graphson).mapper().version(GraphSONVersion.V3_0).addCustomModule(module).create()).create();
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java
index 2277247..d503ae8 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java
@@ -23,9 +23,13 @@ import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.TinkerPopJacksonModule;
 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.StdScalarSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
 
 import java.io.IOException;
@@ -136,14 +140,14 @@ public class CustomId {
         }
     }
 
-    public static class CustomIdTinkerPopJacksonModule extends TinkerPopJacksonModule {
+    public static class CustomIdTinkerPopJacksonModuleV2d0 extends TinkerPopJacksonModule {
 
         private static final Map<Class, String> TYPE_DEFINITIONS = Collections.unmodifiableMap(
                 new LinkedHashMap<Class, String>() {{
                     put(CustomId.class, "id");
                 }});
 
-        public CustomIdTinkerPopJacksonModule() {
+        public CustomIdTinkerPopJacksonModuleV2d0() {
             super("custom");
             addSerializer(CustomId.class, new CustomIdJacksonSerializerV2d0());
             addDeserializer(CustomId.class, new CustomIdJacksonDeserializerV2d0());
@@ -159,4 +163,60 @@ public class CustomId {
             return "simple";
         }
     }
+
+    public static class CustomIdJacksonSerializerV3d0 extends StdScalarSerializer<CustomId> {
+        public CustomIdJacksonSerializerV3d0() {
+            super(CustomId.class);
+        }
+
+        @Override
+        public void serialize(final CustomId customId, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException, JsonGenerationException {
+            final Map<String, Object> m = new HashMap<>();
+            m.put("cluster", customId.getCluster());
+            m.put("elementId", customId.getElementId());
+            jsonGenerator.writeObject(m);
+        }
+    }
+
+    public static class CustomIdJacksonDeserializerV3d0 extends StdDeserializer<CustomId> {
+        public CustomIdJacksonDeserializerV3d0() {
+            super(CustomId.class);
+        }
+
+        @Override
+        public CustomId deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final Map<String, Object> data = deserializationContext.readValue(jsonParser, Map.class);
+            return new CustomId((String) data.get("cluster"), (UUID) data.get("elementId"));
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
+    }
+
+    public static class CustomIdTinkerPopJacksonModuleV3d0 extends TinkerPopJacksonModule {
+
+        private static final Map<Class, String> TYPE_DEFINITIONS = Collections.unmodifiableMap(
+                new LinkedHashMap<Class, String>() {{
+                    put(CustomId.class, "id");
+                }});
+
+        public CustomIdTinkerPopJacksonModuleV3d0() {
+            super("custom");
+            addSerializer(CustomId.class, new CustomIdJacksonSerializerV3d0());
+            addDeserializer(CustomId.class, new CustomIdJacksonDeserializerV3d0());
+        }
+
+        @Override
+        public Map<Class, String> getTypeDefinitions() {
+            return TYPE_DEFINITIONS;
+        }
+
+        @Override
+        public String getTypeNamespace() {
+            return "simple";
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/pom.xml b/gremlin-tools/gremlin-io-test/pom.xml
index 60a56dc..afdc79b 100644
--- a/gremlin-tools/gremlin-io-test/pom.xml
+++ b/gremlin-tools/gremlin-io-test/pom.xml
@@ -168,7 +168,7 @@ writeSupportedV1Objects = { writer, mapper ->
 }
 
 mapper = GraphSONMapper.build().
-                        addRegistry(TinkerIoRegistry.instance()).
+                        addRegistry(TinkerIoRegistryV1d0.instance()).
                         addCustomModule(new AbstractGraphSONMessageSerializerV1d0.GremlinServerModule()).
                         version(GraphSONVersion.V1_0).create().createMapper()
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypedCompatibilityTest.java
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypedCompatibilityTest.java b/gremlin-tools/gremlin-io-test/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypedCompatibilityTest.java
index bf87d89..b2c63da 100644
--- a/gremlin-tools/gremlin-io-test/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypedCompatibilityTest.java
+++ b/gremlin-tools/gremlin-io-test/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypedCompatibilityTest.java
@@ -21,6 +21,7 @@ package org.apache.tinkerpop.gremlin.structure.io.graphson;
 import org.apache.tinkerpop.gremlin.structure.io.AbstractTypedCompatibilityTest;
 import org.apache.tinkerpop.gremlin.structure.io.Compatibility;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2d0;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -41,9 +42,9 @@ public class GraphSONTypedCompatibilityTest extends AbstractTypedCompatibilityTe
             version(GraphSONVersion.V2_0).create().createMapper();
 
     private static ObjectMapper mapperV3 = GraphSONMapper.build().
-            addRegistry(TinkerIoRegistryV2d0.instance()).
-            addCustomModule(GraphSONXModuleV2d0.build().create(false)).
-            addCustomModule(new org.apache.tinkerpop.gremlin.driver.ser.AbstractGraphSONMessageSerializerV2d0.GremlinServerModule()).
+            addRegistry(TinkerIoRegistryV3d0.instance()).
+            addCustomModule(GraphSONXModuleV3d0.build().create(false)).
+            addCustomModule(new org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0.GremlinServerModule()).
             version(GraphSONVersion.V3_0).create().createMapper();
 
     @Parameterized.Parameters(name = "expect({0})")

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationchallenge-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationchallenge-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationchallenge-v3d0.json
index 8c5b82c..d1734c6 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationchallenge-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationchallenge-v3d0.json
@@ -3,10 +3,16 @@
   "status" : {
     "message" : "",
     "code" : 407,
-    "attributes" : { }
+    "attributes" : {
+      "@type" : "g:Map",
+      "@value" : [ ]
+    }
   },
   "result" : {
     "data" : null,
-    "meta" : { }
+    "meta" : {
+      "@type" : "g:Map",
+      "@value" : [ ]
+    }
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationresponse-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationresponse-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationresponse-v3d0.json
index 838e1fd..daceca2 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationresponse-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/authenticationresponse-v3d0.json
@@ -3,7 +3,7 @@
   "op" : "authentication",
   "processor" : "",
   "args" : {
-    "saslMechanism" : "PLAIN",
-    "sasl" : "AHN0ZXBocGhlbgBwYXNzd29yZA=="
+    "@type" : "g:Map",
+    "@value" : [ "saslMechanism", "PLAIN", "sasl", "AHN0ZXBocGhlbgBwYXNzd29yZA==" ]
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/metrics-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/metrics-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/metrics-v3d0.json
index 7b1e964..b4f86cd 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/metrics-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/metrics-v3d0.json
@@ -1,54 +1,49 @@
 {
   "@type" : "g:Metrics",
   "@value" : {
-    "dur" : {
+    "@type" : "g:Map",
+    "@value" : [ "dur", {
       "@type" : "g:Double",
       "@value" : 100.0
-    },
-    "counts" : {
-      "traverserCount" : {
+    }, "counts", {
+      "@type" : "g:Map",
+      "@value" : [ "traverserCount", {
         "@type" : "g:Int64",
         "@value" : 4
-      },
-      "elementCount" : {
+      }, "elementCount", {
         "@type" : "g:Int64",
         "@value" : 4
-      }
-    },
-    "name" : "TinkerGraphStep(vertex,[~label.eq(person)])",
-    "annotations" : {
-      "percentDur" : {
+      } ]
+    }, "name", "TinkerGraphStep(vertex,[~label.eq(person)])", "annotations", {
+      "@type" : "g:Map",
+      "@value" : [ "percentDur", {
         "@type" : "g:Double",
         "@value" : 25.0
-      }
-    },
-    "id" : "7.0.0()",
-    "metrics" : [ {
+      } ]
+    }, "id", "7.0.0()", "metrics", [ {
       "@type" : "g:Metrics",
       "@value" : {
-        "dur" : {
+        "@type" : "g:Map",
+        "@value" : [ "dur", {
           "@type" : "g:Double",
           "@value" : 100.0
-        },
-        "counts" : {
-          "traverserCount" : {
+        }, "counts", {
+          "@type" : "g:Map",
+          "@value" : [ "traverserCount", {
             "@type" : "g:Int64",
             "@value" : 7
-          },
-          "elementCount" : {
+          }, "elementCount", {
             "@type" : "g:Int64",
             "@value" : 7
-          }
-        },
-        "name" : "VertexStep(OUT,vertex)",
-        "annotations" : {
-          "percentDur" : {
+          } ]
+        }, "name", "VertexStep(OUT,vertex)", "annotations", {
+          "@type" : "g:Map",
+          "@value" : [ "percentDur", {
             "@type" : "g:Double",
             "@value" : 25.0
-          }
-        },
-        "id" : "3.0.0()"
+          } ]
+        }, "id", "3.0.0()" ]
       }
-    } ]
+    } ] ]
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/path-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/path-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/path-v3d0.json
index 54ff76d..9ccaa00 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/path-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/path-v3d0.json
@@ -9,97 +9,7 @@
           "@type" : "g:Int32",
           "@value" : 1
         },
-        "label" : "person",
-        "properties" : {
-          "name" : [ {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 0
-              },
-              "value" : "marko",
-              "label" : "name"
-            }
-          } ],
-          "location" : [ {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 6
-              },
-              "value" : "san diego",
-              "label" : "location",
-              "properties" : {
-                "startTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 1997
-                },
-                "endTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2001
-                }
-              }
-            }
-          }, {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 7
-              },
-              "value" : "santa cruz",
-              "label" : "location",
-              "properties" : {
-                "startTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2001
-                },
-                "endTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2004
-                }
-              }
-            }
-          }, {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 8
-              },
-              "value" : "brussels",
-              "label" : "location",
-              "properties" : {
-                "startTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2004
-                },
-                "endTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2005
-                }
-              }
-            }
-          }, {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 9
-              },
-              "value" : "santa fe",
-              "label" : "location",
-              "properties" : {
-                "startTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2005
-                }
-              }
-            }
-          } ]
-        }
+        "label" : "person"
       }
     }, {
       "@type" : "g:Vertex",
@@ -108,20 +18,7 @@
           "@type" : "g:Int32",
           "@value" : 10
         },
-        "label" : "software",
-        "properties" : {
-          "name" : [ {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 4
-              },
-              "value" : "gremlin",
-              "label" : "name"
-            }
-          } ]
-        }
+        "label" : "software"
       }
     }, {
       "@type" : "g:Vertex",
@@ -130,20 +27,7 @@
           "@type" : "g:Int32",
           "@value" : 11
         },
-        "label" : "software",
-        "properties" : {
-          "name" : [ {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 5
-              },
-              "value" : "tinkergraph",
-              "label" : "name"
-            }
-          } ]
-        }
+        "label" : "software"
       }
     } ]
   }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionclose-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionclose-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionclose-v3d0.json
index cc4386b..870c586 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionclose-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionclose-v3d0.json
@@ -3,9 +3,10 @@
   "op" : "close",
   "processor" : "session",
   "args" : {
-    "session" : {
+    "@type" : "g:Map",
+    "@value" : [ "session", {
       "@type" : "g:UUID",
       "@value" : "41d2e28a-20a4-4ab0-b379-d810dede3786"
-    }
+    } ]
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessioneval-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessioneval-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessioneval-v3d0.json
index 900e1ab..a62f70c 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessioneval-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessioneval-v3d0.json
@@ -3,17 +3,16 @@
   "op" : "eval",
   "processor" : "session",
   "args" : {
-    "gremlin" : "g.V(x)",
-    "language" : "gremlin-groovy",
-    "session" : {
+    "@type" : "g:Map",
+    "@value" : [ "gremlin", "g.V(x)", "language", "gremlin-groovy", "session", {
       "@type" : "g:UUID",
       "@value" : "41d2e28a-20a4-4ab0-b379-d810dede3786"
-    },
-    "bindings" : {
-      "x" : {
+    }, "bindings", {
+      "@type" : "g:Map",
+      "@value" : [ "x", {
         "@type" : "g:Int32",
         "@value" : 1
-      }
-    }
+      } ]
+    } ]
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionevalaliased-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionevalaliased-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionevalaliased-v3d0.json
index 924bf77..240a6ef 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionevalaliased-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionevalaliased-v3d0.json
@@ -3,20 +3,19 @@
   "op" : "eval",
   "processor" : "session",
   "args" : {
-    "gremlin" : "social.V(x)",
-    "language" : "gremlin-groovy",
-    "aliases" : {
-      "g" : "social"
-    },
-    "session" : {
+    "@type" : "g:Map",
+    "@value" : [ "gremlin", "social.V(x)", "language", "gremlin-groovy", "aliases", {
+      "@type" : "g:Map",
+      "@value" : [ "g", "social" ]
+    }, "session", {
       "@type" : "g:UUID",
       "@value" : "41d2e28a-20a4-4ab0-b379-d810dede3786"
-    },
-    "bindings" : {
-      "x" : {
+    }, "bindings", {
+      "@type" : "g:Map",
+      "@value" : [ "x", {
         "@type" : "g:Int32",
         "@value" : 1
-      }
-    }
+      } ]
+    } ]
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlesseval-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlesseval-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlesseval-v3d0.json
index 81e2f6c..dc8c8e6 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlesseval-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlesseval-v3d0.json
@@ -3,13 +3,13 @@
   "op" : "eval",
   "processor" : "",
   "args" : {
-    "gremlin" : "g.V(x)",
-    "language" : "gremlin-groovy",
-    "bindings" : {
-      "x" : {
+    "@type" : "g:Map",
+    "@value" : [ "gremlin", "g.V(x)", "language", "gremlin-groovy", "bindings", {
+      "@type" : "g:Map",
+      "@value" : [ "x", {
         "@type" : "g:Int32",
         "@value" : 1
-      }
-    }
+      } ]
+    } ]
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlessevalaliased-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlessevalaliased-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlessevalaliased-v3d0.json
index 0f6a54e..fc03a37 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlessevalaliased-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/sessionlessevalaliased-v3d0.json
@@ -3,16 +3,16 @@
   "op" : "eval",
   "processor" : "",
   "args" : {
-    "gremlin" : "social.V(x)",
-    "language" : "gremlin-groovy",
-    "aliases" : {
-      "g" : "social"
-    },
-    "bindings" : {
-      "x" : {
+    "@type" : "g:Map",
+    "@value" : [ "gremlin", "social.V(x)", "language", "gremlin-groovy", "aliases", {
+      "@type" : "g:Map",
+      "@value" : [ "g", "social" ]
+    }, "bindings", {
+      "@type" : "g:Map",
+      "@value" : [ "x", {
         "@type" : "g:Int32",
         "@value" : 1
-      }
-    }
+      } ]
+    } ]
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/standardresult-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/standardresult-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/standardresult-v3d0.json
index 857c6db..0be6d51 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/standardresult-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/standardresult-v3d0.json
@@ -3,7 +3,10 @@
   "status" : {
     "message" : "",
     "code" : 200,
-    "attributes" : { }
+    "attributes" : {
+      "@type" : "g:Map",
+      "@value" : [ ]
+    }
   },
   "result" : {
     "data" : [ {
@@ -106,6 +109,9 @@
         }
       }
     } ],
-    "meta" : { }
+    "meta" : {
+      "@type" : "g:Map",
+      "@value" : [ ]
+    }
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/traversalmetrics-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/traversalmetrics-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/traversalmetrics-v3d0.json
index fdd18a4..8e7effd 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/traversalmetrics-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/traversalmetrics-v3d0.json
@@ -1,114 +1,106 @@
 {
   "@type" : "g:TraversalMetrics",
   "@value" : {
-    "dur" : {
+    "@type" : "g:Map",
+    "@value" : [ "dur", {
       "@type" : "g:Double",
       "@value" : 0.004
-    },
-    "metrics" : [ {
+    }, "metrics", [ {
       "@type" : "g:Metrics",
       "@value" : {
-        "dur" : {
+        "@type" : "g:Map",
+        "@value" : [ "dur", {
           "@type" : "g:Double",
           "@value" : 100.0
-        },
-        "counts" : {
-          "traverserCount" : {
+        }, "counts", {
+          "@type" : "g:Map",
+          "@value" : [ "traverserCount", {
             "@type" : "g:Int64",
             "@value" : 4
-          },
-          "elementCount" : {
+          }, "elementCount", {
             "@type" : "g:Int64",
             "@value" : 4
-          }
-        },
-        "name" : "TinkerGraphStep(vertex,[~label.eq(person)])",
-        "annotations" : {
-          "percentDur" : {
+          } ]
+        }, "name", "TinkerGraphStep(vertex,[~label.eq(person)])", "annotations", {
+          "@type" : "g:Map",
+          "@value" : [ "percentDur", {
             "@type" : "g:Double",
             "@value" : 25.0
-          }
-        },
-        "id" : "7.0.0()"
+          } ]
+        }, "id", "7.0.0()" ]
       }
     }, {
       "@type" : "g:Metrics",
       "@value" : {
-        "dur" : {
+        "@type" : "g:Map",
+        "@value" : [ "dur", {
           "@type" : "g:Double",
           "@value" : 100.0
-        },
-        "counts" : {
-          "traverserCount" : {
+        }, "counts", {
+          "@type" : "g:Map",
+          "@value" : [ "traverserCount", {
             "@type" : "g:Int64",
             "@value" : 13
-          },
-          "elementCount" : {
+          }, "elementCount", {
             "@type" : "g:Int64",
             "@value" : 13
-          }
-        },
-        "name" : "VertexStep(OUT,vertex)",
-        "annotations" : {
-          "percentDur" : {
+          } ]
+        }, "name", "VertexStep(OUT,vertex)", "annotations", {
+          "@type" : "g:Map",
+          "@value" : [ "percentDur", {
             "@type" : "g:Double",
             "@value" : 25.0
-          }
-        },
-        "id" : "2.0.0()"
+          } ]
+        }, "id", "2.0.0()" ]
       }
     }, {
       "@type" : "g:Metrics",
       "@value" : {
-        "dur" : {
+        "@type" : "g:Map",
+        "@value" : [ "dur", {
           "@type" : "g:Double",
           "@value" : 100.0
-        },
-        "counts" : {
-          "traverserCount" : {
+        }, "counts", {
+          "@type" : "g:Map",
+          "@value" : [ "traverserCount", {
             "@type" : "g:Int64",
             "@value" : 7
-          },
-          "elementCount" : {
+          }, "elementCount", {
             "@type" : "g:Int64",
             "@value" : 7
-          }
-        },
-        "name" : "VertexStep(OUT,vertex)",
-        "annotations" : {
-          "percentDur" : {
+          } ]
+        }, "name", "VertexStep(OUT,vertex)", "annotations", {
+          "@type" : "g:Map",
+          "@value" : [ "percentDur", {
             "@type" : "g:Double",
             "@value" : 25.0
-          }
-        },
-        "id" : "3.0.0()"
+          } ]
+        }, "id", "3.0.0()" ]
       }
     }, {
       "@type" : "g:Metrics",
       "@value" : {
-        "dur" : {
+        "@type" : "g:Map",
+        "@value" : [ "dur", {
           "@type" : "g:Double",
           "@value" : 100.0
-        },
-        "counts" : {
-          "traverserCount" : {
+        }, "counts", {
+          "@type" : "g:Map",
+          "@value" : [ "traverserCount", {
             "@type" : "g:Int64",
             "@value" : 1
-          },
-          "elementCount" : {
+          }, "elementCount", {
             "@type" : "g:Int64",
             "@value" : 1
-          }
-        },
-        "name" : "TreeStep",
-        "annotations" : {
-          "percentDur" : {
+          } ]
+        }, "name", "TreeStep", "annotations", {
+          "@type" : "g:Map",
+          "@value" : [ "percentDur", {
             "@type" : "g:Double",
             "@value" : 25.0
-          }
-        },
-        "id" : "4.0.0()"
+          } ]
+        }, "id", "4.0.0()" ]
       }
-    } ]
+    } ] ]
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/tree-v3d0.json
----------------------------------------------------------------------
diff --git a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/tree-v3d0.json b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/tree-v3d0.json
index 74dcffc..77ba971 100644
--- a/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/tree-v3d0.json
+++ b/gremlin-tools/gremlin-io-test/src/test/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/_3_3_0/tree-v3d0.json
@@ -1,5 +1,5 @@
 {
-  "@type" : "g:Tree",
+  "@type" : "g:Map",
   "@value" : [ {
     "key" : {
       "@type" : "g:Vertex",
@@ -102,7 +102,7 @@
       }
     },
     "value" : {
-      "@type" : "g:Tree",
+      "@type" : "g:Map",
       "@value" : [ {
         "key" : {
           "@type" : "g:Vertex",
@@ -128,7 +128,7 @@
           }
         },
         "value" : {
-          "@type" : "g:Tree",
+          "@type" : "g:Map",
           "@value" : [ {
             "key" : {
               "@type" : "g:Vertex",
@@ -154,7 +154,7 @@
               }
             },
             "value" : {
-              "@type" : "g:Tree",
+              "@type" : "g:Map",
               "@value" : [ ]
             }
           } ]

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV3d0.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV3d0.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV3d0.java
index 685a8cc..c2eebf9 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV3d0.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV3d0.java
@@ -50,6 +50,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -194,7 +195,7 @@ public final class TinkerIoRegistryV3d0 extends AbstractIoRegistry {
             final List<? extends Vertex> vertices;
 
             jsonParser.nextToken();
-            final Map<String, Object> graphData = deserializationContext.readValue(jsonParser, Map.class);
+            final Map<String, Object> graphData = deserializationContext.readValue(jsonParser, LinkedHashMap.class);
             vertices = (List<DetachedVertex>) graphData.get(GraphSONTokens.VERTICES);
             edges = (List<DetachedEdge>) graphData.get(GraphSONTokens.EDGES);
 


[4/4] tinkerpop git commit: TINKERPOP-1427 Added g:Map for GraphSON 3.0

Posted by sp...@apache.org.
TINKERPOP-1427 Added g:Map for 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/90f5ee33
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/90f5ee33
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/90f5ee33

Branch: refs/heads/TINKERPOP-1427
Commit: 90f5ee331c4ea226ab260466619e712a9b03f0a4
Parents: ab7e4f0
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Jul 1 14:16:57 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Sat Jul 1 14:16:57 2017 -0400

----------------------------------------------------------------------
 .../AbstractGraphSONTypeSerializer.java         | 173 +++++++++++
 .../structure/io/graphson/GraphSONMapper.java   |   5 +-
 .../structure/io/graphson/GraphSONModule.java   |  11 +-
 .../structure/io/graphson/GraphSONReader.java   |   9 +-
 .../io/graphson/GraphSONSerializerProvider.java |   1 -
 .../io/graphson/GraphSONSerializersV2d0.java    |   2 +-
 .../io/graphson/GraphSONSerializersV3d0.java    |  28 +-
 .../graphson/GraphSONTypeResolverBuilder.java   |  10 +-
 .../io/graphson/GraphSONTypeSerializer.java     | 245 ---------------
 .../io/graphson/GraphSONTypeSerializerV2d0.java | 112 +++++++
 .../io/graphson/GraphSONTypeSerializerV3d0.java | 139 +++++++++
 .../io/graphson/GraphSONXModuleV2d0.java        |   8 +-
 .../io/graphson/GraphSONXModuleV3d0.java        |   8 +-
 .../io/graphson/JavaTimeSerializersV3d0.java    |   5 +
 .../io/graphson/JavaUtilSerializersV3d0.java    | 109 +++++--
 .../io/graphson/TraversalSerializersV3d0.java   | 146 +++++++--
 .../star/StarGraphGraphSONSerializerV3d0.java   | 165 +++++++++++
 .../GraphSONMapperEmbeddedTypeTest.java         |  39 ++-
 .../GraphSONMapperPartialEmbeddedTypeTest.java  | 297 +++++++++++++++++++
 .../io/graphson/GraphSONMapperTest.java         |   3 +
 ...aphSONMapperV2d0PartialEmbeddedTypeTest.java | 278 -----------------
 .../ser/GraphSONMessageSerializerV3d0Test.java  |  25 +-
 .../jsr223/PythonGraphSONJavaTranslator.java    |   5 +-
 .../server/GremlinDriverIntegrateTest.java      |  34 +++
 .../GremlinServerAuditLogIntegrateTest.java     |   7 +
 .../server/GremlinServerHttpIntegrateTest.java  |   2 +-
 .../server/GremlinServerIntegrateTest.java      |   2 +-
 .../gremlin/structure/io/IoCustomTest.java      |   7 +-
 .../tinkerpop/gremlin/structure/io/IoTest.java  |   4 +-
 .../gremlin/structure/io/util/CustomId.java     |  64 +++-
 gremlin-tools/gremlin-io-test/pom.xml           |   2 +-
 .../GraphSONTypedCompatibilityTest.java         |   7 +-
 .../_3_3_0/authenticationchallenge-v3d0.json    |  10 +-
 .../_3_3_0/authenticationresponse-v3d0.json     |   4 +-
 .../io/graphson/_3_3_0/metrics-v3d0.json        |  55 ++--
 .../structure/io/graphson/_3_3_0/path-v3d0.json | 122 +-------
 .../io/graphson/_3_3_0/sessionclose-v3d0.json   |   5 +-
 .../io/graphson/_3_3_0/sessioneval-v3d0.json    |  15 +-
 .../_3_3_0/sessionevalaliased-v3d0.json         |  21 +-
 .../graphson/_3_3_0/sessionlesseval-v3d0.json   |  12 +-
 .../_3_3_0/sessionlessevalaliased-v3d0.json     |  18 +-
 .../io/graphson/_3_3_0/standardresult-v3d0.json |  10 +-
 .../graphson/_3_3_0/traversalmetrics-v3d0.json  | 112 ++++---
 .../structure/io/graphson/_3_3_0/tree-v3d0.json |   8 +-
 .../structure/TinkerIoRegistryV3d0.java         |   3 +-
 45 files changed, 1449 insertions(+), 898 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
new file mode 100644
index 0000000..6eb65e1
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
@@ -0,0 +1,173 @@
+/*
+ * 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.shaded.jackson.annotation.JsonTypeInfo;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.databind.BeanProperty;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Extension of the Jackson's default TypeSerializer. An instance of this object will be passed to the serializers
+ * on which they can safely call the utility methods to serialize types and making it compatible with the version
+ * 2.0+ of GraphSON.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public abstract class AbstractGraphSONTypeSerializer extends TypeSerializer {
+
+    protected final TypeIdResolver idRes;
+    protected final String propertyName;
+    protected final TypeInfo typeInfo;
+    protected final String valuePropertyName;
+    protected final Map<Class, Class> classMap = new HashMap<>();
+
+    AbstractGraphSONTypeSerializer(final TypeIdResolver idRes, final String propertyName, final TypeInfo typeInfo,
+                                   final String valuePropertyName) {
+        this.idRes = idRes;
+        this.propertyName = propertyName;
+        this.typeInfo = typeInfo;
+        this.valuePropertyName = valuePropertyName;
+    }
+
+
+    @Override
+    public TypeSerializer forProperty(final BeanProperty beanProperty) {
+        return this;
+    }
+
+    @Override
+    public JsonTypeInfo.As getTypeInclusion() {
+        return null;
+    }
+
+    @Override
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    @Override
+    public TypeIdResolver getTypeIdResolver() {
+        return idRes;
+    }
+
+    @Override
+    public void writeTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+        if (canWriteTypeId()) {
+            writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
+        }
+    }
+
+    @Override
+    public void writeTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeStartObject();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(Map);
+    }
+
+    @Override
+    public void writeTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeStartArray();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(List);
+    }
+
+    @Override
+    public void writeTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+        if (canWriteTypeId()) {
+            writeTypeSuffix(jsonGenerator);
+        }
+    }
+
+    @Override
+    public void writeTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeEndObject();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(Map);
+    }
+
+    @Override
+    public void writeTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeEndArray();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(List);
+    }
+
+    @Override
+    public void writeCustomTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+        if (canWriteTypeId()) {
+            writeTypePrefix(jsonGenerator, s);
+        }
+    }
+
+    @Override
+    public void writeCustomTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+        jsonGenerator.writeStartObject();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
+    }
+
+    @Override
+    public void writeCustomTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+        jsonGenerator.writeStartArray();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
+    }
+
+    @Override
+    public void writeCustomTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+        if (canWriteTypeId()) {
+            writeTypeSuffix(jsonGenerator);
+        }
+    }
+
+    @Override
+    public void writeCustomTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+        jsonGenerator.writeEndObject();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
+    }
+
+    @Override
+    public void writeCustomTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
+        jsonGenerator.writeEndArray();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
+    }
+
+    protected boolean canWriteTypeId() {
+        return typeInfo != null
+                && typeInfo == TypeInfo.PARTIAL_TYPES;
+    }
+
+    protected void writeTypePrefix(final JsonGenerator jsonGenerator, final String s) throws IOException {
+        jsonGenerator.writeStartObject();
+        jsonGenerator.writeStringField(this.getPropertyName(), s);
+        jsonGenerator.writeFieldName(this.valuePropertyName);
+    }
+
+    protected void writeTypeSuffix(final JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeEndObject();
+    }
+
+    /**
+     * We force only **one** translation of a Java object to a domain specific object. i.e. users register typeIDs
+     * and serializers/deserializers for the predefined types we have in the spec. Graph, Vertex, Edge,
+     * VertexProperty, etc... And **not** their implementations (TinkerGraph, DetachedVertex, TinkerEdge, etc..)
+     */
+    protected abstract Class getClassFromObject(final Object o);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/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 d442dbc..9ec015b 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
@@ -92,9 +92,12 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
             om.findAndRegisterModules();
 
         // graphson 3.0 only allows type - there is no option to remove embedded types
+        if (version == GraphSONVersion.V3_0 && typeInfo == TypeInfo.NO_TYPES)
+            throw new IllegalStateException(String.format("GraphSON 3.0 does not support %s", TypeInfo.NO_TYPES));
+
         if (version == GraphSONVersion.V3_0 || (version == GraphSONVersion.V2_0 && typeInfo != TypeInfo.NO_TYPES)) {
             final GraphSONTypeIdResolver graphSONTypeIdResolver = new GraphSONTypeIdResolver();
-            final TypeResolverBuilder typer = new GraphSONTypeResolverBuilder()
+            final TypeResolverBuilder typer = new GraphSONTypeResolverBuilder(version)
                     .typesEmbedding(getTypeInfo())
                     .valuePropertyName(GraphSONTokens.VALUEPROP)
                     .init(JsonTypeInfo.Id.CUSTOM, graphSONTypeIdResolver)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/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 019112b..22dc6b2 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
@@ -71,6 +71,7 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.star.DirectionalStarGraph;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV1d0;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV2d0;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV3d0;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
 
 import java.time.Duration;
@@ -122,6 +123,9 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
                     put(Double.class, "Double");
                     put(Float.class, "Float");
 
+                    put(Map.Entry.class, "Entry");
+                    put(Map.class, "Map");
+
                     // Tinkerpop Graph objects
                     put(Lambda.class, "Lambda");
                     put(Vertex.class, "Vertex");
@@ -196,11 +200,12 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
             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(DirectionalStarGraph.class, new StarGraphGraphSONSerializerV3d0(normalize));
             addSerializer(Tree.class, new GraphSONSerializersV3d0.TreeJacksonSerializer());
 
             // java.util
             addSerializer(Map.Entry.class, new JavaUtilSerializersV3d0.MapEntryJacksonSerializer());
+            addSerializer(Map.class, new JavaUtilSerializersV3d0.MapJacksonSerializer());
 
             // need to explicitly add serializers for those types because Jackson doesn't do it at all.
             addSerializer(Integer.class, new GraphSONSerializersV3d0.IntegerGraphSONSerializer());
@@ -237,6 +242,10 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
             addDeserializer(TraversalMetrics.class, new GraphSONSerializersV3d0.TraversalMetricsJacksonDeserializer());
             addDeserializer(Tree.class, new GraphSONSerializersV3d0.TreeJacksonDeserializer());
 
+            // java.util
+            addDeserializer(Map.Entry.class, new JavaUtilSerializersV3d0.MapEntryJacksonDeserializer());
+            addDeserializer(Map.class, new JavaUtilSerializersV3d0.MapJacksonDeserializer());
+
             // numbers
             addDeserializer(Integer.class, new GraphSONSerializersV3d0.IntegerJackonsDeserializer());
             addDeserializer(Double.class, new GraphSONSerializersV3d0.DoubleJackonsDeserializer());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
index 3f63b96..056d3c8 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
@@ -52,6 +52,7 @@ import java.io.OutputStream;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Function;
@@ -73,8 +74,8 @@ public final class GraphSONReader implements GraphReader {
     private final GraphSONVersion version;
     private boolean unwrapAdjacencyList = false;
 
-    final TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {
-    };
+    final TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {};
+    final TypeReference<LinkedHashMap<String, Object>> linkedHashMapTypeReference = new TypeReference<LinkedHashMap<String, Object>>() {};
 
     private GraphSONReader(final Builder builder) {
         mapper = builder.mapper.createMapper();
@@ -173,7 +174,9 @@ public final class GraphSONReader implements GraphReader {
                              final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
                              final Function<Attachable<Edge>, Edge> edgeAttachMethod,
                              final Direction attachEdgesOfThisDirection) throws IOException {
-        final Map<String, Object> vertexData = mapper.readValue(inputStream, mapTypeReference);
+        // graphson v3 has special handling for generic Map instances, by forcing to linkedhashmap (which is probably
+        // what it should have been anyway) stargraph format can remain unchanged across all versions
+        final Map<String, Object> vertexData = mapper.readValue(inputStream, version == GraphSONVersion.V3_0 ? linkedHashMapTypeReference : mapTypeReference);
         final StarGraph starGraph = StarGraphGraphSONDeserializer.readStarGraphVertex(vertexData);
         if (vertexAttachMethod != null) vertexAttachMethod.apply(starGraph.getStarVertex());
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
index bd7f966..7744b79 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
@@ -44,7 +44,6 @@ final class GraphSONSerializerProvider extends DefaultSerializerProvider {
             setDefaultKeySerializer(new GraphSONSerializersV2d0.GraphSONKeySerializer());
             unknownTypeSerializer = new ToStringGraphSONSerializer();
         } else {
-            setDefaultKeySerializer(new GraphSONSerializersV3d0.GraphSONKeySerializer());
             unknownTypeSerializer = new ToStringGraphSONSerializer();
         }
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/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 095bfe6..717dcfa 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
@@ -703,4 +703,4 @@ class GraphSONSerializersV2d0 {
             return true;
         }
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/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
index 6f6e011..5fe8e74 100644
--- 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
@@ -64,6 +64,7 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -610,20 +611,21 @@ class GraphSONSerializersV3d0 {
         }
     }
 
-    static class MetricsJacksonDeserializer extends AbstractObjectDeserializer<Metrics> {
+    static class MetricsJacksonDeserializer extends StdDeserializer<Metrics> {
         public MetricsJacksonDeserializer() {
             super(Metrics.class);
         }
 
         @Override
-        public Metrics createObject(final Map<String, Object> metricsData) {
+        public Metrics deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final Map<String, Object> metricsData = deserializationContext.readValue(jsonParser, Map.class);
             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, new HashMap<>(0))).entrySet()) {
+            for (Map.Entry<String, Long> count : ((Map<String, Long>)metricsData.getOrDefault(GraphSONTokens.COUNTS, new LinkedHashMap<>(0))).entrySet()) {
                 m.setCount(count.getKey(), count.getValue());
             }
-            for (Map.Entry<String, Long> count : ((Map<String, Long>) metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, new HashMap<>(0))).entrySet()) {
+            for (Map.Entry<String, Long> count : ((Map<String, Long>) metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, new LinkedHashMap<>(0))).entrySet()) {
                 m.setAnnotation(count.getKey(), count.getValue());
             }
             for (MutableMetrics nested : (List<MutableMetrics>)metricsData.getOrDefault(GraphSONTokens.METRICS, new ArrayList<>(0))) {
@@ -631,21 +633,33 @@ class GraphSONSerializersV3d0 {
             }
             return m;
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
-    static class TraversalMetricsJacksonDeserializer extends AbstractObjectDeserializer<TraversalMetrics> {
+    static class TraversalMetricsJacksonDeserializer extends StdDeserializer<TraversalMetrics> {
 
         public TraversalMetricsJacksonDeserializer() {
             super(TraversalMetrics.class);
         }
 
         @Override
-        public TraversalMetrics createObject(final Map<String, Object> traversalMetricsData) {
+        public TraversalMetrics deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final Map<String, Object> traversalMetricsData = deserializationContext.readValue(jsonParser, Map.class);
+
             return new DefaultTraversalMetrics(
                     Math.round((Double) traversalMetricsData.get(GraphSONTokens.DURATION) * 1000000),
                     (List<MutableMetrics>) traversalMetricsData.get(GraphSONTokens.METRICS)
             );
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     static class TreeJacksonDeserializer extends StdDeserializer<Tree> {
@@ -703,4 +717,4 @@ class GraphSONSerializersV3d0 {
             return true;
         }
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
index 7d3d03c..0da512e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
@@ -34,11 +34,17 @@ import java.util.Collection;
  * deserializers. Contains the typeInfo level that should be provided by the GraphSONMapper.
  *
  * @author Kevin Gallardo (https://kgdo.me)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class GraphSONTypeResolverBuilder extends StdTypeResolverBuilder {
 
     private TypeInfo typeInfo;
     private String valuePropertyName;
+    private final GraphSONVersion version;
+
+    public GraphSONTypeResolverBuilder(final GraphSONVersion version) {
+        this.version = version;
+    }
 
     @Override
     public TypeDeserializer buildTypeDeserializer(final DeserializationConfig config, final JavaType baseType,
@@ -52,7 +58,9 @@ public class GraphSONTypeResolverBuilder extends StdTypeResolverBuilder {
     public TypeSerializer buildTypeSerializer(final SerializationConfig config, final JavaType baseType,
                                               final Collection<NamedType> subtypes) {
         final TypeIdResolver idRes = this.idResolver(config, baseType, subtypes, true, false);
-        return new GraphSONTypeSerializer(idRes, this.getTypeProperty(), typeInfo, valuePropertyName);
+        return version == GraphSONVersion.V2_0 ?
+                new GraphSONTypeSerializerV2d0(idRes, this.getTypeProperty(), typeInfo, valuePropertyName) :
+                new GraphSONTypeSerializerV3d0(idRes, this.getTypeProperty(), typeInfo, valuePropertyName);
     }
 
     public GraphSONTypeResolverBuilder valuePropertyName(final String valuePropertyName) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
deleted file mode 100644
index 78c670a..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tinkerpop.gremlin.structure.io.graphson;
-
-import org.apache.tinkerpop.gremlin.process.traversal.Operator;
-import org.apache.tinkerpop.gremlin.process.traversal.Order;
-import org.apache.tinkerpop.gremlin.process.traversal.Path;
-import org.apache.tinkerpop.gremlin.process.traversal.Pop;
-import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
-import org.apache.tinkerpop.gremlin.process.traversal.Scope;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
-import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
-import org.apache.tinkerpop.gremlin.structure.Column;
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Property;
-import org.apache.tinkerpop.gremlin.structure.T;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-import org.apache.tinkerpop.gremlin.util.function.Lambda;
-import org.apache.tinkerpop.shaded.jackson.annotation.JsonTypeInfo;
-import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
-import org.apache.tinkerpop.shaded.jackson.databind.BeanProperty;
-import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
-import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Extension of the Jackson's default TypeSerializer. An instance of this object will be passed to the serializers
- * on which they can safely call the utility methods to serialize types and making it compatible with the version
- * 2.0 of GraphSON.
- *
- * @author Kevin Gallardo (https://kgdo.me)
- */
-public class GraphSONTypeSerializer extends TypeSerializer {
-
-    private final TypeIdResolver idRes;
-    private final String propertyName;
-    private final TypeInfo typeInfo;
-    private final String valuePropertyName;
-    private final Map<Class, Class> classMap = new HashMap<>();
-
-    GraphSONTypeSerializer(final TypeIdResolver idRes, final String propertyName, final TypeInfo typeInfo,
-                           final String valuePropertyName) {
-        this.idRes = idRes;
-        this.propertyName = propertyName;
-        this.typeInfo = typeInfo;
-        this.valuePropertyName = valuePropertyName;
-    }
-
-    @Override
-    public TypeSerializer forProperty(final BeanProperty beanProperty) {
-        return this;
-    }
-
-    @Override
-    public JsonTypeInfo.As getTypeInclusion() {
-        return null;
-    }
-
-    @Override
-    public String getPropertyName() {
-        return propertyName;
-    }
-
-    @Override
-    public TypeIdResolver getTypeIdResolver() {
-        return idRes;
-    }
-
-    @Override
-    public void writeTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        if (canWriteTypeId()) {
-            writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
-        }
-    }
-
-    @Override
-    public void writeTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeStartObject();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(Map);
-    }
-
-    @Override
-    public void writeTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeStartArray();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(List);
-    }
-
-    @Override
-    public void writeTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        if (canWriteTypeId()) {
-            writeTypeSuffix(jsonGenerator);
-        }
-    }
-
-    @Override
-    public void writeTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeEndObject();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(Map);
-    }
-
-    @Override
-    public void writeTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeEndArray();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(List);
-    }
-
-    @Override
-    public void writeCustomTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        if (canWriteTypeId()) {
-            writeTypePrefix(jsonGenerator, s);
-        }
-    }
-
-    @Override
-    public void writeCustomTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        jsonGenerator.writeStartObject();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
-    }
-
-    @Override
-    public void writeCustomTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        jsonGenerator.writeStartArray();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
-    }
-
-    @Override
-    public void writeCustomTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        if (canWriteTypeId()) {
-            writeTypeSuffix(jsonGenerator);
-        }
-    }
-
-    @Override
-    public void writeCustomTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        jsonGenerator.writeEndObject();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
-    }
-
-    @Override
-    public void writeCustomTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator,final  String s) throws IOException {
-        jsonGenerator.writeEndArray();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
-    }
-
-    private boolean canWriteTypeId() {
-        return typeInfo != null
-                && typeInfo == TypeInfo.PARTIAL_TYPES;
-    }
-
-    private void writeTypePrefix(final JsonGenerator jsonGenerator, final String s) throws IOException {
-        jsonGenerator.writeStartObject();
-        jsonGenerator.writeStringField(this.getPropertyName(), s);
-        jsonGenerator.writeFieldName(this.valuePropertyName);
-    }
-
-    private void writeTypeSuffix(final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeEndObject();
-    }
-
-    /**
-     *  We force only **one** translation of a Java object to a domain specific object. i.e. users register typeIDs
-     *  and serializers/deserializers for the predefined types we have in the spec. Graph, Vertex, Edge,
-     *  VertexProperty, etc... And **not** their implementations (TinkerGraph, DetachedVertex, TinkerEdge, etc..)
-    */
-    private Class getClassFromObject(final Object o) {
-        final Class c = o.getClass();
-        if (classMap.containsKey(c))
-            return classMap.get(c);
-
-        final Class mapped;
-        if (Vertex.class.isAssignableFrom(c))
-            mapped = Vertex.class;
-        else if (Edge.class.isAssignableFrom(c))
-            mapped = Edge.class;
-        else if (Path.class.isAssignableFrom(c))
-            mapped = Path.class;
-        else if (VertexProperty.class.isAssignableFrom(c))
-            mapped = VertexProperty.class;
-        else if (Metrics.class.isAssignableFrom(c))
-            mapped = Metrics.class;
-        else if (TraversalMetrics.class.isAssignableFrom(c))
-            mapped = TraversalMetrics.class;
-        else if (Property.class.isAssignableFrom(c))
-            mapped = Property.class;
-        else if (ByteBuffer.class.isAssignableFrom(c))
-            mapped = ByteBuffer.class;
-        else if (InetAddress.class.isAssignableFrom(c))
-            mapped = InetAddress.class;
-        else if (Traverser.class.isAssignableFrom(c))
-            mapped = Traverser.class;
-        else if (Lambda.class.isAssignableFrom(c))
-            mapped = Lambda.class;
-        else if (VertexProperty.Cardinality.class.isAssignableFrom(c))
-            mapped = VertexProperty.Cardinality.class;
-        else if (Column.class.isAssignableFrom(c))
-            mapped = Column.class;
-        else if (Direction.class.isAssignableFrom(c))
-            mapped = Direction.class;
-        else if (Operator.class.isAssignableFrom(c))
-            mapped = Operator.class;
-        else if (Order.class.isAssignableFrom(c))
-            mapped = Order.class;
-        else if (Pop.class.isAssignableFrom(c))
-            mapped = Pop.class;
-        else if (SackFunctions.Barrier.class.isAssignableFrom(c))
-            mapped = SackFunctions.Barrier.class;
-        else if (TraversalOptionParent.Pick.class.isAssignableFrom(c))
-            mapped = TraversalOptionParent.Pick.class;
-        else if (Scope.class.isAssignableFrom(c))
-            mapped = Scope.class;
-        else if (T.class.isAssignableFrom(c))
-            mapped = T.class;
-        else
-            mapped = c;
-
-        classMap.put(c, mapped);
-        return mapped;
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
new file mode 100644
index 0000000..993f110
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
@@ -0,0 +1,112 @@
+/*
+ * 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.Operator;
+import org.apache.tinkerpop.gremlin.process.traversal.Order;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
+import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+import org.apache.tinkerpop.gremlin.structure.Column;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.util.function.Lambda;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * GraphSON 2.0 {@code TypeSerializer}.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class GraphSONTypeSerializerV2d0 extends AbstractGraphSONTypeSerializer {
+
+    GraphSONTypeSerializerV2d0(final TypeIdResolver idRes, final String propertyName, final TypeInfo typeInfo,
+                               final String valuePropertyName) {
+        super(idRes, propertyName, typeInfo, valuePropertyName);
+    }
+
+    @Override
+    protected Class getClassFromObject(final Object o) {
+        final Class c = o.getClass();
+        if (classMap.containsKey(c))
+            return classMap.get(c);
+
+        final Class mapped;
+        if (Vertex.class.isAssignableFrom(c))
+            mapped = Vertex.class;
+        else if (Edge.class.isAssignableFrom(c))
+            mapped = Edge.class;
+        else if (Path.class.isAssignableFrom(c))
+            mapped = Path.class;
+        else if (VertexProperty.class.isAssignableFrom(c))
+            mapped = VertexProperty.class;
+        else if (Metrics.class.isAssignableFrom(c))
+            mapped = Metrics.class;
+        else if (TraversalMetrics.class.isAssignableFrom(c))
+            mapped = TraversalMetrics.class;
+        else if (Property.class.isAssignableFrom(c))
+            mapped = Property.class;
+        else if (ByteBuffer.class.isAssignableFrom(c))
+            mapped = ByteBuffer.class;
+        else if (InetAddress.class.isAssignableFrom(c))
+            mapped = InetAddress.class;
+        else if (Traverser.class.isAssignableFrom(c))
+            mapped = Traverser.class;
+        else if (Lambda.class.isAssignableFrom(c))
+            mapped = Lambda.class;
+        else if (VertexProperty.Cardinality.class.isAssignableFrom(c))
+            mapped = VertexProperty.Cardinality.class;
+        else if (Column.class.isAssignableFrom(c))
+            mapped = Column.class;
+        else if (Direction.class.isAssignableFrom(c))
+            mapped = Direction.class;
+        else if (Operator.class.isAssignableFrom(c))
+            mapped = Operator.class;
+        else if (Order.class.isAssignableFrom(c))
+            mapped = Order.class;
+        else if (Pop.class.isAssignableFrom(c))
+            mapped = Pop.class;
+        else if (SackFunctions.Barrier.class.isAssignableFrom(c))
+            mapped = SackFunctions.Barrier.class;
+        else if (TraversalOptionParent.Pick.class.isAssignableFrom(c))
+            mapped = TraversalOptionParent.Pick.class;
+        else if (Scope.class.isAssignableFrom(c))
+            mapped = Scope.class;
+        else if (T.class.isAssignableFrom(c))
+            mapped = T.class;
+        else
+            mapped = c;
+
+        classMap.put(c, mapped);
+        return mapped;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
new file mode 100644
index 0000000..246d38f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
@@ -0,0 +1,139 @@
+/*
+ * 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.Operator;
+import org.apache.tinkerpop.gremlin.process.traversal.Order;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
+import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+import org.apache.tinkerpop.gremlin.structure.Column;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.util.function.Lambda;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.Map;
+
+/**
+ * GraphSON 2.0 {@code TypeSerializer}.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class GraphSONTypeSerializerV3d0 extends AbstractGraphSONTypeSerializer {
+
+    GraphSONTypeSerializerV3d0(final TypeIdResolver idRes, final String propertyName, final TypeInfo typeInfo,
+                               final String valuePropertyName) {
+        super(idRes, propertyName, typeInfo, valuePropertyName);
+    }
+
+    @Override
+    public void writeTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+        if (o instanceof Map || o instanceof Map.Entry) {
+            writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
+            jsonGenerator.writeStartArray();
+        } else {
+            jsonGenerator.writeStartObject();
+        }
+    }
+
+    @Override
+    public void writeTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+        if (o instanceof Map || o instanceof Map.Entry) {
+            jsonGenerator.writeEndArray();
+            writeTypeSuffix(jsonGenerator);
+        } else {
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    @Override
+    protected Class getClassFromObject(final Object o) {
+        final Class c = o.getClass();
+        if (classMap.containsKey(c))
+            return classMap.get(c);
+
+        final Class mapped;
+        if (Map.class.isAssignableFrom(c))
+            mapped = Map.class;
+        else if (Map.Entry.class.isAssignableFrom(c))
+            mapped = Map.Entry.class;
+        else if (Vertex.class.isAssignableFrom(c))
+            mapped = Vertex.class;
+        else if (Edge.class.isAssignableFrom(c))
+            mapped = Edge.class;
+        else if (Path.class.isAssignableFrom(c))
+            mapped = Path.class;
+        else if (VertexProperty.class.isAssignableFrom(c))
+            mapped = VertexProperty.class;
+        else if (Metrics.class.isAssignableFrom(c))
+            mapped = Metrics.class;
+        else if (TraversalMetrics.class.isAssignableFrom(c))
+            mapped = TraversalMetrics.class;
+        else if (Property.class.isAssignableFrom(c))
+            mapped = Property.class;
+        else if (ByteBuffer.class.isAssignableFrom(c))
+            mapped = ByteBuffer.class;
+        else if (InetAddress.class.isAssignableFrom(c))
+            mapped = InetAddress.class;
+        else if (Traverser.class.isAssignableFrom(c))
+            mapped = Traverser.class;
+        else if (Lambda.class.isAssignableFrom(c))
+            mapped = Lambda.class;
+        else if (VertexProperty.Cardinality.class.isAssignableFrom(c))
+            mapped = VertexProperty.Cardinality.class;
+        else if (Column.class.isAssignableFrom(c))
+            mapped = Column.class;
+        else if (Direction.class.isAssignableFrom(c))
+            mapped = Direction.class;
+        else if (Operator.class.isAssignableFrom(c))
+            mapped = Operator.class;
+        else if (Order.class.isAssignableFrom(c))
+            mapped = Order.class;
+        else if (Pop.class.isAssignableFrom(c))
+            mapped = Pop.class;
+        else if (SackFunctions.Barrier.class.isAssignableFrom(c))
+            mapped = SackFunctions.Barrier.class;
+        else if (TraversalOptionParent.Pick.class.isAssignableFrom(c))
+            mapped = TraversalOptionParent.Pick.class;
+        else if (Scope.class.isAssignableFrom(c))
+            mapped = Scope.class;
+        else if (T.class.isAssignableFrom(c))
+            mapped = T.class;
+        else
+            mapped = c;
+
+        classMap.put(c, mapped);
+        return mapped;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java
index 336d11c..0d4ba53 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java
@@ -18,10 +18,6 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.net.InetAddress;
@@ -45,6 +41,8 @@ import java.util.Map;
 
 /**
  * Version 2.0 of GraphSON extensions.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public final class GraphSONXModuleV2d0 extends GraphSONModule {
 
@@ -139,4 +137,4 @@ public final class GraphSONXModuleV2d0 extends GraphSONModule {
             return new GraphSONXModuleV2d0(normalize);
         }
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java
index 777c6c4..38caa09 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java
@@ -18,10 +18,6 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.net.InetAddress;
@@ -45,6 +41,8 @@ import java.util.Map;
 
 /**
  * Version 3.0 of GraphSON extensions.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public final class GraphSONXModuleV3d0 extends GraphSONModule {
 
@@ -139,4 +137,4 @@ public final class GraphSONXModuleV3d0 extends GraphSONModule {
             return new GraphSONXModuleV3d0(normalize);
         }
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java
index 1cb75e0..c1668e2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java
@@ -85,6 +85,11 @@ final class JavaTimeSerializersV3d0 {
         public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
             return parse(jsonParser.getText());
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java
index 816a3f7..900eeb8 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java
@@ -18,16 +18,22 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
-import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
-import org.apache.tinkerpop.shaded.jackson.databind.SerializationFeature;
+import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
+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.StdScalarSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
 
 import java.io.IOException;
-import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * GraphSON serializers for classes in {@code java.util.*} for the version 3.0 of GraphSON.
@@ -36,6 +42,31 @@ final class JavaUtilSerializersV3d0 {
 
     private JavaUtilSerializersV3d0() {}
 
+    ////////////////////////////// SERIALIZERS /////////////////////////////////
+
+    final static class MapJacksonSerializer extends StdSerializer<Map> {
+        public MapJacksonSerializer() {
+            super(Map.class);
+        }
+
+        @Override
+        public void serialize(final Map map, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            for(Map.Entry entry : (Set<Map.Entry>) map.entrySet()) {
+                jsonGenerator.writeObject(entry.getKey());
+                jsonGenerator.writeObject(entry.getValue());
+            }
+        }
+
+        @Override
+        public void serializeWithType(final Map map, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            typeSerializer.writeTypePrefixForObject(map, jsonGenerator);
+            serialize(map, jsonGenerator, serializerProvider);
+            typeSerializer.writeTypeSuffixForObject(map, jsonGenerator);
+        }
+    }
+
     final static class MapEntryJacksonSerializer extends StdSerializer<Map.Entry> {
 
         public MapEntryJacksonSerializer() {
@@ -45,41 +76,61 @@ final class JavaUtilSerializersV3d0 {
         @Override
         public void serialize(final Map.Entry entry, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
                 throws IOException {
-            jsonGenerator.writeStartObject();
-            ser(entry, jsonGenerator, serializerProvider);
-            jsonGenerator.writeEndObject();
+            jsonGenerator.writeObject(entry.getKey());
+            jsonGenerator.writeObject(entry.getValue());
         }
 
         @Override
         public void serializeWithType(final Map.Entry entry, final JsonGenerator jsonGenerator,
                                       final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
             typeSerializer.writeTypePrefixForObject(entry, jsonGenerator);
-            ser(entry, jsonGenerator, serializerProvider);
+            serialize(entry, jsonGenerator, serializerProvider);
             typeSerializer.writeTypeSuffixForObject(entry, jsonGenerator);
         }
+    }
+
+    ////////////////////////////// DESERIALIZERS /////////////////////////////////
+
+
+    static class MapJacksonDeserializer extends StdDeserializer<Map> {
+
+        protected MapJacksonDeserializer() {
+            super(Map.class);
+        }
+
+        @Override
+        public Map deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final Map<Object,Object> m = new LinkedHashMap<>();
+
+            while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
+                final Object key = deserializationContext.readValue(jsonParser, Object.class);
+                jsonParser.nextToken();
+                final Object val = deserializationContext.readValue(jsonParser, Object.class);
+                m.put(key, val);
+            }
+
+            return m;
+        }
+    }
+
+    static class MapEntryJacksonDeserializer extends StdDeserializer<Map.Entry> {
+
+        protected MapEntryJacksonDeserializer() {
+            super(Map.Entry.class);
+        }
+
+        @Override
+        public Map.Entry deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final Map<Object,Object> m = new HashMap<>();
+
+            while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
+                final Object key = deserializationContext.readValue(jsonParser, Object.class);
+                jsonParser.nextToken();
+                final Object val = deserializationContext.readValue(jsonParser, Object.class);
+                m.put(key, val);
+            }
 
-        private static void ser(final Map.Entry entry, final JsonGenerator jsonGenerator,
-                                final SerializerProvider serializerProvider) throws IOException {
-            // this treatment of keys is consistent with the current GraphSONKeySerializer which extends the
-            // StdKeySerializer
-            final Object key = entry.getKey();
-            final Class cls = key.getClass();
-            String k;
-            if (cls == String.class)
-                k = (String) key;
-            else if (Element.class.isAssignableFrom(cls))
-                k = ((Element) key).id().toString();
-            else if(Date.class.isAssignableFrom(cls)) {
-                if (serializerProvider.isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS))
-                    k = String.valueOf(((Date) key).getTime());
-                else
-                    k = serializerProvider.getConfig().getDateFormat().format((Date) key);
-            } else if(cls == Class.class)
-                k = ((Class) key).getName();
-            else
-                k = key.toString();
-
-            serializerProvider.defaultSerializeField(k, entry.getValue(), jsonGenerator);
+            return m.entrySet().iterator().next();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
index e4f6df9..57b6736 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
@@ -35,14 +35,19 @@ import org.apache.tinkerpop.gremlin.util.function.Lambda;
 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.core.JsonToken;
 import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 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.StdScalarSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -242,29 +247,40 @@ final class TraversalSerializersV3d0 {
     // DESERIALIZERS //
     //////////////////
 
-    final static class BytecodeJacksonDeserializer extends AbstractObjectDeserializer<Bytecode> {
+    final static class BytecodeJacksonDeserializer extends StdDeserializer<Bytecode> {
+        private static final JavaType listJavaType = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, Object.class);
+        private static final JavaType listListJavaType = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, listJavaType);
 
         public BytecodeJacksonDeserializer() {
             super(Bytecode.class);
         }
 
         @Override
-        public Bytecode createObject(final Map<String, Object> data) {
+        public Bytecode deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             final Bytecode bytecode = new Bytecode();
-            if (data.containsKey(GraphSONTokens.SOURCE)) {
-                final List<List<Object>> instructions = (List) data.get(GraphSONTokens.SOURCE);
-                for (final List<Object> instruction : instructions) {
-                    bytecode.addSource((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
-                }
-            }
-            if (data.containsKey(GraphSONTokens.STEP)) {
-                final List<List<Object>> instructions = (List) data.get(GraphSONTokens.STEP);
-                for (final List<Object> instruction : instructions) {
-                    bytecode.addStep((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.SOURCE)) {
+                    jsonParser.nextToken();
+                    final List<List<Object>> instructions = deserializationContext.readValue(jsonParser, listListJavaType);
+                    for (final List<Object> instruction : instructions) {
+                        bytecode.addSource((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+                    }
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.STEP)) {
+                    jsonParser.nextToken();
+                    final List<List<Object>> instructions = deserializationContext.readValue(jsonParser, listListJavaType);
+                    for (final List<Object> instruction : instructions) {
+                        bytecode.addStep((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+                    }
                 }
             }
             return bytecode;
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     final static class EnumJacksonDeserializer<A extends Enum> extends StdDeserializer<A> {
@@ -283,18 +299,34 @@ final class TraversalSerializersV3d0 {
             }
             throw new IOException("Unknown enum type: " + enumClass);
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
-    final static class PJacksonDeserializer extends AbstractObjectDeserializer<P> {
+    final static class PJacksonDeserializer extends StdDeserializer<P> {
 
         public PJacksonDeserializer() {
             super(P.class);
         }
 
         @Override
-        public P createObject(final Map<String, Object> data) {
-            final String predicate = (String) data.get(GraphSONTokens.PREDICATE);
-            final Object value = data.get(GraphSONTokens.VALUE);
+        public P deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            String predicate = null;
+            Object value = null;
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.PREDICATE)) {
+                    jsonParser.nextToken();
+                    predicate = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    value = deserializationContext.readValue(jsonParser, Object.class);
+                }
+            }
+
             if (predicate.equals(GraphSONTokens.AND) || predicate.equals(GraphSONTokens.OR)) {
                 return predicate.equals(GraphSONTokens.AND) ? new AndP((List<P>) value) : new OrP((List<P>) value);
             } else {
@@ -324,20 +356,38 @@ final class TraversalSerializersV3d0 {
                 }
             }
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
-    final static class LambdaJacksonDeserializer extends AbstractObjectDeserializer<Lambda> {
+    final static class LambdaJacksonDeserializer extends StdDeserializer<Lambda> {
 
         public LambdaJacksonDeserializer() {
             super(Lambda.class);
         }
 
         @Override
-        public Lambda createObject(final Map<String, Object> data) {
-            final String script = (String) data.get(GraphSONTokens.SCRIPT);
-            final String language = (String) data.get(GraphSONTokens.LANGUAGE);
-            final int arguments = ((Number) data.getOrDefault(GraphSONTokens.ARGUMENTS, -1)).intValue();
-            //
+        public Lambda deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            String script = null;
+            String language = null;
+            int arguments = -1;
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.SCRIPT)) {
+                    jsonParser.nextToken();
+                    script = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LANGUAGE)) {
+                    jsonParser.nextToken();
+                    language = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.ARGUMENTS)) {
+                    jsonParser.nextToken();
+                    arguments = jsonParser.getIntValue();
+                }
+            }
+
             if (-1 == arguments || arguments > 2)
                 return new Lambda.UnknownArgLambda(script, language, arguments);
             else if (0 == arguments)
@@ -347,29 +397,69 @@ final class TraversalSerializersV3d0 {
             else
                 return new Lambda.TwoArgLambda<>(script, language);
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
-    final static class BindingJacksonDeserializer extends AbstractObjectDeserializer<Bytecode.Binding> {
+    final static class BindingJacksonDeserializer extends StdDeserializer<Bytecode.Binding> {
 
         public BindingJacksonDeserializer() {
             super(Bytecode.Binding.class);
         }
 
         @Override
-        public Bytecode.Binding createObject(final Map<String, Object> data) {
-            return new Bytecode.Binding<>((String) data.get(GraphSONTokens.KEY), data.get(GraphSONTokens.VALUE));
+        public Bytecode.Binding deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            String k = null;
+            Object v = null;
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.KEY)) {
+                    jsonParser.nextToken();
+                    k = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    v = deserializationContext.readValue(jsonParser, Object.class);
+                }
+            }
+            return new Bytecode.Binding<>(k, v);
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 
-    static class TraverserJacksonDeserializer extends AbstractObjectDeserializer<Traverser> {
+    static class TraverserJacksonDeserializer extends StdDeserializer<Traverser> {
 
         public TraverserJacksonDeserializer() {
             super(Traverser.class);
         }
 
         @Override
-        public Traverser createObject(final Map<String, Object> data) {
-            return new DefaultRemoteTraverser<>(data.get(GraphSONTokens.VALUE), (Long) data.get(GraphSONTokens.BULK));
+        public Traverser deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            long bulk = 1;
+            Object v = null;
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.BULK)) {
+                    jsonParser.nextToken();
+                    bulk = deserializationContext.readValue(jsonParser, Long.class);
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    v = deserializationContext.readValue(jsonParser, Object.class);
+                }
+            }
+
+            return new DefaultRemoteTraverser<>(v, bulk);
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/90f5ee33/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV3d0.java
new file mode 100644
index 0000000..9a9682c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV3d0.java
@@ -0,0 +1,165 @@
+/*
+ * 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.util.star;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+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.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StarGraphGraphSONSerializerV3d0 extends StdSerializer<DirectionalStarGraph> {
+    private final boolean normalize;
+    public StarGraphGraphSONSerializerV3d0(final boolean normalize) {
+        super(DirectionalStarGraph.class);
+        this.normalize = normalize;
+    }
+
+    @Override
+    public void serialize(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+                          final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+        ser(starGraph, jsonGenerator, serializerProvider, null);
+    }
+
+    @Override
+    public void serializeWithType(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+                                  final SerializerProvider serializerProvider,
+                                  final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+        ser(starGraph, jsonGenerator, serializerProvider, typeSerializer);
+    }
+
+    private void ser(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+                     final SerializerProvider serializerProvider,
+                     final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+        final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+        GraphSONUtil.writeStartObject(starGraph, jsonGenerator, typeSerializer);
+        GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
+        jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
+        if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
+        if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
+        if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
+            jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+            GraphSONUtil.writeStartObject(starGraph, jsonGenerator, typeSerializer);
+            final Set<String> keys = normalize ? new TreeSet<>(starGraph.starVertex.vertexProperties.keySet()) : starGraph.starVertex.vertexProperties.keySet();
+            for (final String k : keys) {
+                final List<VertexProperty> vp = starGraph.starVertex.vertexProperties.get(k);
+                jsonGenerator.writeFieldName(k);
+                GraphSONUtil.writeStartArray(k, jsonGenerator, typeSerializer);
+
+                final List<VertexProperty> vertexProperties = normalize ?sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
+                for (final VertexProperty property : vertexProperties) {
+                    GraphSONUtil.writeStartObject(property, jsonGenerator, typeSerializer);
+                    GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer);
+                    GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer);
+
+                    final Iterator<Property> metaProperties = normalize ?
+                            IteratorUtils.list(property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
+                    if (metaProperties.hasNext()) {
+                        jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+                        GraphSONUtil.writeStartObject(metaProperties, jsonGenerator, typeSerializer);
+
+                        while (metaProperties.hasNext()) {
+                            final Property<Object> meta = metaProperties.next();
+                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+                        }
+                        GraphSONUtil.writeEndObject(metaProperties, jsonGenerator, typeSerializer);
+                    }
+                    GraphSONUtil.writeEndObject(property, jsonGenerator, typeSerializer);
+                }
+                GraphSONUtil.writeEndArray(k, jsonGenerator, typeSerializer);
+            }
+            GraphSONUtil.writeEndObject(starGraph, jsonGenerator, typeSerializer);
+        }
+        GraphSONUtil.writeEndObject(starGraph, jsonGenerator, typeSerializer);
+    }
+
+    private void writeEdges(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+                            final SerializerProvider serializerProvider,
+                            final TypeSerializer typeSerializer,
+                            final Direction direction)  throws IOException, JsonProcessingException {
+        // only write edges if there are some AND if the user requested them to be serialized AND if they match
+        // the direction being serialized by the format
+        final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+        final Direction edgeDirectionToSerialize = directionalStarGraph.getDirection();
+        final Map<String, List<Edge>> starEdges = direction.equals(Direction.OUT) ? starGraph.starVertex.outEdges : starGraph.starVertex.inEdges;
+        final boolean writeEdges = null != starEdges && edgeDirectionToSerialize != null
+                && (edgeDirectionToSerialize == direction || edgeDirectionToSerialize == Direction.BOTH);
+        if (writeEdges) {
+            jsonGenerator.writeFieldName(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
+            GraphSONUtil.writeStartObject(directionalStarGraph, jsonGenerator, typeSerializer);
+            final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
+            for (final String k : keys) {
+                final List<Edge> edges = starEdges.get(k);
+                jsonGenerator.writeFieldName(k);
+                GraphSONUtil.writeStartArray(k, jsonGenerator, typeSerializer);
+
+                final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
+                for (final Edge edge : edgesToWrite) {
+                    GraphSONUtil.writeStartObject(edge, jsonGenerator, typeSerializer);
+                    GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
+                    GraphSONUtil.writeWithType(direction.equals(Direction.OUT) ? GraphSONTokens.IN : GraphSONTokens.OUT,
+                            direction.equals(Direction.OUT) ? edge.inVertex().id() : edge.outVertex().id(),
+                            jsonGenerator, serializerProvider, typeSerializer);
+
+                    final Iterator<Property<Object>> edgeProperties = normalize ?
+                            IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+                    if (edgeProperties.hasNext()) {
+                        jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+                        GraphSONUtil.writeStartObject(edge, jsonGenerator, typeSerializer);
+                        while (edgeProperties.hasNext()) {
+                            final Property<Object> meta = edgeProperties.next();
+                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+                        }
+                        GraphSONUtil.writeEndObject(edge, jsonGenerator, typeSerializer);
+                    }
+                    GraphSONUtil.writeEndObject(edge, jsonGenerator, typeSerializer);
+                }
+                GraphSONUtil.writeEndArray(k, jsonGenerator, typeSerializer);
+            }
+            GraphSONUtil.writeEndObject(directionalStarGraph, jsonGenerator, typeSerializer);
+        }
+    }
+
+    private static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
+        Collections.sort(listToSort, comparator);
+        return listToSort;
+    }
+
+}


[2/4] tinkerpop git commit: TINKERPOP-1427 Should use GraphSON 3.0 in the serializer provider

Posted by sp...@apache.org.
TINKERPOP-1427 Should use GraphSON 3.0 in the serializer provider


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

Branch: refs/heads/TINKERPOP-1427
Commit: ab7e4f047838944c475bac39a8d25d8a599c9327
Parents: 72ebd7e
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 30 14:00:13 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jun 30 14:00:13 2017 -0400

----------------------------------------------------------------------
 .../structure/io/graphson/GraphSONSerializerProvider.java       | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ab7e4f04/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
index 458a2d9..bd7f966 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
@@ -40,9 +40,12 @@ final class GraphSONSerializerProvider extends DefaultSerializerProvider {
         if (version == GraphSONVersion.V1_0) {
             setDefaultKeySerializer(new GraphSONSerializersV1d0.GraphSONKeySerializer());
             unknownTypeSerializer = new ToStringSerializer();
-        } else {
+        } else if (version == GraphSONVersion.V2_0) {
             setDefaultKeySerializer(new GraphSONSerializersV2d0.GraphSONKeySerializer());
             unknownTypeSerializer = new ToStringGraphSONSerializer();
+        } else {
+            setDefaultKeySerializer(new GraphSONSerializersV3d0.GraphSONKeySerializer());
+            unknownTypeSerializer = new ToStringGraphSONSerializer();
         }
     }