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 2016/06/30 17:34:10 UTC

[41/50] [abbrv] tinkerpop git commit: TINKERPOP-1274: GraphSON 2.0.

TINKERPOP-1274: GraphSON 2.0.


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

Branch: refs/heads/TINKERPOP-1274
Commit: b44ec666f846d9acc7b0223887cb0b5e2e0789bd
Parents: 0554b59
Author: Kevin Gallardo <ke...@datastax.com>
Authored: Tue Jun 28 19:38:32 2016 +0100
Committer: Kevin Gallardo <ke...@datastax.com>
Committed: Thu Jun 30 10:39:47 2016 +0100

----------------------------------------------------------------------
 .../structure/io/graphson/GraphSONIo.java       |   6 +-
 .../structure/io/graphson/GraphSONMapper.java   |  78 ++-
 .../structure/io/graphson/GraphSONModule.java   | 106 ++---
 .../structure/io/graphson/GraphSONReader.java   |  23 +-
 .../io/graphson/GraphSONSerializerProvider.java |  28 +-
 .../io/graphson/GraphSONSerializersV1d0.java    |  16 +-
 .../io/graphson/GraphSONSerializersV2d0.java    | 467 ++++++++++++++++++
 .../io/graphson/GraphSONTypeDeserializer.java   | 201 ++++++++
 .../io/graphson/GraphSONTypeIdResolver.java     | 134 ++++++
 .../graphson/GraphSONTypeResolverBuilder.java   |  60 +++
 .../io/graphson/GraphSONTypeSerializer.java     | 160 +++++++
 .../structure/io/graphson/GraphSONUtil.java     |  29 ++
 .../structure/io/graphson/GraphSONWriter.java   |  12 +-
 .../io/graphson/JavaTimeSerializersV1d0.java    |  14 +-
 .../io/graphson/JavaTimeSerializersV2d0.java    | 311 ++++++++++++
 .../io/graphson/JavaUtilSerializersV2d0.java    | 116 +++++
 .../structure/io/graphson/JsonParserConcat.java |  81 ++++
 .../io/graphson/LegacyGraphSONReader.java       |  14 +-
 .../io/graphson/TinkerPopJacksonModule.java     |  59 +++
 .../io/graphson/ToStringGraphSONSerializer.java |  41 ++
 .../util/star/DirectionalStarGraph.java         |  39 ++
 .../star/StarGraphGraphSONDeserializer.java     |  91 ++++
 .../util/star/StarGraphGraphSONSerializer.java  | 250 ----------
 .../star/StarGraphGraphSONSerializerV1d0.java   | 167 +++++++
 .../star/StarGraphGraphSONSerializerV2d0.java   | 158 +++++++
 ...aphSONMapperV2d0PartialEmbeddedTypeTest.java | 292 ++++++++++++
 .../io/graphson/GraphSONMapperV2d0Test.java     | 171 +++++++
 .../AbstractGraphSONMessageSerializerV2d0.java  | 248 ++++++++++
 .../GraphSONMessageSerializerGremlinV2d0.java   |  68 +++
 .../ser/GraphSONMessageSerializerV2d0.java      | 124 +++++
 ...raphSONMessageSerializerGremlinV2d0Test.java | 321 +++++++++++++
 .../ser/GraphSONMessageSerializerV2d0Test.java  | 474 +++++++++++++++++++
 .../structure/TinkerIoRegistryV2d0.java         | 227 +++++++++
 .../structure/IoDataGenerationTest.java         | 109 ++++-
 .../TinkerGraphGraphSONSerializerV2d0Test.java  | 156 ++++++
 35 files changed, 4444 insertions(+), 407 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
index 0354a11..31cc6f2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
@@ -22,11 +22,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.io.Io;
 import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
 
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
 
 /**
  * Constructs GraphSON IO implementations given a {@link Graph} and {@link IoRegistry}. Implementers of the {@link Graph}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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 be5377a..8f20ef7 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
@@ -33,6 +33,7 @@ import org.javatuples.Pair;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * An extension to the standard Jackson {@code ObjectMapper} which automatically registers the standard
@@ -60,14 +61,17 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
     private final boolean normalize;
     private final boolean embedTypes;
     private final GraphSONVersion version;
+    private final TypeInfo typeInfo;
 
     private GraphSONMapper(final List<SimpleModule> customModules, final boolean loadCustomSerializers,
-                           final boolean normalize, final boolean embedTypes, final GraphSONVersion version) {
+                           final boolean normalize, final boolean embedTypes, final GraphSONVersion version,
+                           final TypeInfo typeInfo) {
         this.customModules = customModules;
         this.loadCustomSerializers = loadCustomSerializers;
         this.normalize = normalize;
         this.embedTypes = embedTypes;
         this.version = version;
+        this.typeInfo = typeInfo;
     }
 
     @Override
@@ -75,6 +79,16 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
         final ObjectMapper om = new ObjectMapper();
         om.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
 
+        GraphSONModule graphSONModule = version.getBuilder().create(normalize);
+        om.registerModule(graphSONModule);
+        customModules.forEach(om::registerModule);
+
+
+        // plugin external serialization modules
+        if (loadCustomSerializers)
+            om.findAndRegisterModules();
+
+
         if (version == GraphSONVersion.V1_0) {
             if (embedTypes) {
                 final TypeResolverBuilder<?> typer = new StdTypeResolverBuilder()
@@ -84,29 +98,41 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
                 om.setDefaultTyping(typer);
             }
         } else if (version == GraphSONVersion.V2_0) {
+            if (typeInfo != TypeInfo.NO_TYPES) {
+                GraphSONTypeIdResolver graphSONTypeIdResolver = new GraphSONTypeIdResolver();
+                final TypeResolverBuilder typer = new GraphSONTypeResolverBuilder()
+                        .typesEmbedding(getTypeInfo())
+                        .init(JsonTypeInfo.Id.CUSTOM, graphSONTypeIdResolver)
+                        .typeProperty(GraphSONTokens.CLASS);
 
+                // Register types to typeResolver for the GraphSON module
+                for (Map.Entry<String, Class> typeDeser : graphSONModule.getAddedDeserializers().entrySet()) {
+                    graphSONTypeIdResolver.addCustomType(typeDeser.getKey(), typeDeser.getValue());
+                }
+
+                // Register types to typeResolver for the Custom modules
+                customModules.forEach(e -> {
+                    if (e instanceof TinkerPopJacksonModule) {
+                        for (Map.Entry<String, Class> typeDeser : ((TinkerPopJacksonModule) e).getAddedDeserializers().entrySet()) {
+                            graphSONTypeIdResolver.addCustomType(typeDeser.getKey(), typeDeser.getValue());
+                        }
+                    }
+                });
+                om.setDefaultTyping(typer);
+            }
         } else {
-            throw new IllegalStateException("Unknown GraphSONVersion");
+            throw new IllegalStateException("Unknown GraphSONVersion : " + version);
         }
 
-        if (normalize)
-            om.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
-
         // this provider toStrings all unknown classes and converts keys in Map objects that are Object to String.
-        final DefaultSerializerProvider provider = new GraphSONSerializerProvider();
-        provider.setDefaultKeySerializer(new GraphSONSerializersV1d0.GraphSONKeySerializer());
+        final DefaultSerializerProvider provider = new GraphSONSerializerProvider(version);
         om.setSerializerProvider(provider);
 
-        om.registerModule(version.getBuilder().create(normalize));
-        customModules.forEach(om::registerModule);
-
-        // plugin external serialization modules
-        if (loadCustomSerializers)
-            om.findAndRegisterModules();
+        if (normalize)
+            om.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
 
         // keep streams open to accept multiple values (e.g. multiple vertices)
         om.getFactory().disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
-
         return om;
     }
 
@@ -118,6 +144,15 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
         return new Builder();
     }
 
+    public TypeInfo getTypeInfo() {
+        return this.typeInfo;
+    }
+
+    public enum TypeInfo {
+        NO_TYPES,
+        PARTIAL_TYPES
+    }
+
     public static class Builder implements Mapper.Builder<Builder> {
         private List<SimpleModule> customModules = new ArrayList<>();
         private boolean loadCustomModules = false;
@@ -125,6 +160,8 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
         private boolean embedTypes = false;
         private List<IoRegistry> registries = new ArrayList<>();
         private GraphSONVersion version = GraphSONVersion.V1_0;
+        // GraphSON 2.0 should have types activated by default, otherwise use there's no point in using it instead of 1.0.
+        private TypeInfo typeInfo = TypeInfo.PARTIAL_TYPES;
 
         private Builder() {
         }
@@ -187,13 +224,24 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
             return this;
         }
 
+        /**
+         * Specify if the values are going to be typed or not, and at which level.
+         *
+         * The level can be NO_TYPES or PARTIAL_TYPES, and could be extended in the future.
+         */
+        public Builder typeInfo(final TypeInfo typeInfo) {
+            this.typeInfo = typeInfo;
+            return this;
+        }
+
         public GraphSONMapper create() {
             registries.forEach(registry -> {
                 final List<Pair<Class, SimpleModule>> simpleModules = registry.find(GraphSONIo.class, SimpleModule.class);
                 simpleModules.stream().map(Pair::getValue1).forEach(this.customModules::add);
             });
 
-            return new GraphSONMapper(customModules, loadCustomModules, normalize, embedTypes, version);
+            return new GraphSONMapper(customModules, loadCustomModules, normalize, embedTypes, version, typeInfo);
         }
+
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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 639e90d..06630f4 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
@@ -19,30 +19,20 @@
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializer;
-import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
-
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.MonthDay;
-import java.time.OffsetDateTime;
-import java.time.OffsetTime;
-import java.time.Period;
-import java.time.Year;
-import java.time.YearMonth;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
+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 java.nio.ByteBuffer;
+import java.time.*;
 import java.util.Map;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
 
 /**
  * The set of serializers that handle the core graph interfaces.  These serializers support normalization which
@@ -54,7 +44,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-abstract class GraphSONModule extends SimpleModule {
+abstract class GraphSONModule extends TinkerPopJacksonModule {
 
     GraphSONModule(final String name) {
         super(name);
@@ -64,54 +54,55 @@ abstract class GraphSONModule extends SimpleModule {
      * Version 2.0 of GraphSON.
      */
     static final class GraphSONModuleV2d0 extends GraphSONModule {
-
         /**
          * Constructs a new object.
          */
         protected GraphSONModuleV2d0(final boolean normalize) {
             super("graphson-2.0");
+
             // graph
-            addSerializer(Edge.class, new GraphSONSerializersV1d0.EdgeJacksonSerializer(normalize));
-            addSerializer(Vertex.class, new GraphSONSerializersV1d0.VertexJacksonSerializer(normalize));
-            addSerializer(VertexProperty.class, new GraphSONSerializersV1d0.VertexPropertyJacksonSerializer(normalize));
-            addSerializer(Property.class, new GraphSONSerializersV1d0.PropertyJacksonSerializer());
-            addSerializer(TraversalMetrics.class, new GraphSONSerializersV1d0.TraversalMetricsJacksonSerializer());
-            addSerializer(TraversalExplanation.class, new GraphSONSerializersV1d0.TraversalExplanationJacksonSerializer());
-            addSerializer(Path.class, new GraphSONSerializersV1d0.PathJacksonSerializer());
-            addSerializer(StarGraphGraphSONSerializer.DirectionalStarGraph.class, new StarGraphGraphSONSerializer(normalize));
-            addSerializer(Tree.class, new GraphSONSerializersV1d0.TreeJacksonSerializer());
+            addSerializer(Edge.class, new GraphSONSerializersV2d0.EdgeJacksonSerializer(normalize));
+            addSerializer(Vertex.class, new GraphSONSerializersV2d0.VertexJacksonSerializer(normalize));
+            addSerializer(VertexProperty.class, new GraphSONSerializersV2d0.VertexPropertyJacksonSerializer(normalize));
+            addSerializer(Property.class, new GraphSONSerializersV2d0.PropertyJacksonSerializer());
+            addSerializer(TraversalMetrics.class, new GraphSONSerializersV2d0.TraversalMetricsJacksonSerializer());
+            addSerializer(TraversalExplanation.class, new GraphSONSerializersV2d0.TraversalExplanationJacksonSerializer());
+            addSerializer(Path.class, new GraphSONSerializersV2d0.PathJacksonSerializer());
+            addSerializer(DirectionalStarGraph.class, new StarGraphGraphSONSerializerV2d0(normalize));
+            addSerializer(Tree.class, new GraphSONSerializersV2d0.TreeJacksonSerializer());
 
             // java.util
-            addSerializer(Map.Entry.class, new JavaUtilSerializersV1d0.MapEntryJacksonSerializer());
+            addSerializer(Map.Entry.class, new JavaUtilSerializersV2d0.MapEntryJacksonSerializer());
+            addSerializer(ByteBuffer.class, new JavaUtilSerializersV2d0.GraphSONByteBufferSerializer());
 
             // java.time
-            addSerializer(Duration.class, new JavaTimeSerializersV1d0.DurationJacksonSerializer());
-            addSerializer(Instant.class, new JavaTimeSerializersV1d0.InstantJacksonSerializer());
-            addSerializer(LocalDate.class, new JavaTimeSerializersV1d0.LocalDateJacksonSerializer());
-            addSerializer(LocalDateTime.class, new JavaTimeSerializersV1d0.LocalDateTimeJacksonSerializer());
-            addSerializer(LocalTime.class, new JavaTimeSerializersV1d0.LocalTimeJacksonSerializer());
-            addSerializer(MonthDay.class, new JavaTimeSerializersV1d0.MonthDayJacksonSerializer());
-            addSerializer(OffsetDateTime.class, new JavaTimeSerializersV1d0.OffsetDateTimeJacksonSerializer());
-            addSerializer(OffsetTime.class, new JavaTimeSerializersV1d0.OffsetTimeJacksonSerializer());
-            addSerializer(Period.class, new JavaTimeSerializersV1d0.PeriodJacksonSerializer());
-            addSerializer(Year.class, new JavaTimeSerializersV1d0.YearJacksonSerializer());
-            addSerializer(YearMonth.class, new JavaTimeSerializersV1d0.YearMonthJacksonSerializer());
-            addSerializer(ZonedDateTime.class, new JavaTimeSerializersV1d0.ZonedDateTimeJacksonSerializer());
-            addSerializer(ZoneOffset.class, new JavaTimeSerializersV1d0.ZoneOffsetJacksonSerializer());
-
-            addDeserializer(Duration.class, new JavaTimeSerializersV1d0.DurationJacksonDeserializer());
-            addDeserializer(Instant.class, new JavaTimeSerializersV1d0.InstantJacksonDeserializer());
-            addDeserializer(LocalDate.class, new JavaTimeSerializersV1d0.LocalDateJacksonDeserializer());
-            addDeserializer(LocalDateTime.class, new JavaTimeSerializersV1d0.LocalDateTimeJacksonDeserializer());
-            addDeserializer(LocalTime.class, new JavaTimeSerializersV1d0.LocalTimeJacksonDeserializer());
-            addDeserializer(MonthDay.class, new JavaTimeSerializersV1d0.MonthDayJacksonDeserializer());
-            addDeserializer(OffsetDateTime.class, new JavaTimeSerializersV1d0.OffsetDateTimeJacksonDeserializer());
-            addDeserializer(OffsetTime.class, new JavaTimeSerializersV1d0.OffsetTimeJacksonDeserializer());
-            addDeserializer(Period.class, new JavaTimeSerializersV1d0.PeriodJacksonDeserializer());
-            addDeserializer(Year.class, new JavaTimeSerializersV1d0.YearJacksonDeserializer());
-            addDeserializer(YearMonth.class, new JavaTimeSerializersV1d0.YearMonthJacksonDeserializer());
-            addDeserializer(ZonedDateTime.class, new JavaTimeSerializersV1d0.ZonedDateTimeJacksonDeserializer());
-            addDeserializer(ZoneOffset.class, new JavaTimeSerializersV1d0.ZoneOffsetJacksonDeserializer());
+            addSerializer(Duration.class, new JavaTimeSerializersV2d0.DurationJacksonSerializer());
+            addSerializer(Instant.class, new JavaTimeSerializersV2d0.InstantJacksonSerializer());
+            addSerializer(LocalDate.class, new JavaTimeSerializersV2d0.LocalDateJacksonSerializer());
+            addSerializer(LocalDateTime.class, new JavaTimeSerializersV2d0.LocalDateTimeJacksonSerializer());
+            addSerializer(LocalTime.class, new JavaTimeSerializersV2d0.LocalTimeJacksonSerializer());
+            addSerializer(MonthDay.class, new JavaTimeSerializersV2d0.MonthDayJacksonSerializer());
+            addSerializer(OffsetDateTime.class, new JavaTimeSerializersV2d0.OffsetDateTimeJacksonSerializer());
+            addSerializer(OffsetTime.class, new JavaTimeSerializersV2d0.OffsetTimeJacksonSerializer());
+            addSerializer(Period.class, new JavaTimeSerializersV2d0.PeriodJacksonSerializer());
+            addSerializer(Year.class, new JavaTimeSerializersV2d0.YearJacksonSerializer());
+            addSerializer(YearMonth.class, new JavaTimeSerializersV2d0.YearMonthJacksonSerializer());
+            addSerializer(ZonedDateTime.class, new JavaTimeSerializersV2d0.ZonedDateTimeJacksonSerializer());
+            addSerializer(ZoneOffset.class, new JavaTimeSerializersV2d0.ZoneOffsetJacksonSerializer());
+
+            addDeserializer(Duration.class, new JavaTimeSerializersV2d0.DurationJacksonDeserializer());
+            addDeserializer(Instant.class, new JavaTimeSerializersV2d0.InstantJacksonDeserializer());
+            addDeserializer(LocalDate.class, new JavaTimeSerializersV2d0.LocalDateJacksonDeserializer());
+            addDeserializer(LocalDateTime.class, new JavaTimeSerializersV2d0.LocalDateTimeJacksonDeserializer());
+            addDeserializer(LocalTime.class, new JavaTimeSerializersV2d0.LocalTimeJacksonDeserializer());
+            addDeserializer(MonthDay.class, new JavaTimeSerializersV2d0.MonthDayJacksonDeserializer());
+            addDeserializer(OffsetDateTime.class, new JavaTimeSerializersV2d0.OffsetDateTimeJacksonDeserializer());
+            addDeserializer(OffsetTime.class, new JavaTimeSerializersV2d0.OffsetTimeJacksonDeserializer());
+            addDeserializer(Period.class, new JavaTimeSerializersV2d0.PeriodJacksonDeserializer());
+            addDeserializer(Year.class, new JavaTimeSerializersV2d0.YearJacksonDeserializer());
+            addDeserializer(YearMonth.class, new JavaTimeSerializersV2d0.YearMonthJacksonDeserializer());
+            addDeserializer(ZonedDateTime.class, new JavaTimeSerializersV2d0.ZonedDateTimeJacksonDeserializer());
+            addDeserializer(ZoneOffset.class, new JavaTimeSerializersV2d0.ZoneOffsetJacksonDeserializer());
         }
 
         public static Builder build() {
@@ -126,6 +117,7 @@ abstract class GraphSONModule extends SimpleModule {
             public GraphSONModule create(final boolean normalize) {
                 return new GraphSONModuleV2d0(normalize);
             }
+
         }
     }
 
@@ -147,7 +139,7 @@ abstract class GraphSONModule extends SimpleModule {
             addSerializer(TraversalMetrics.class, new GraphSONSerializersV1d0.TraversalMetricsJacksonSerializer());
             addSerializer(TraversalExplanation.class, new GraphSONSerializersV1d0.TraversalExplanationJacksonSerializer());
             addSerializer(Path.class, new GraphSONSerializersV1d0.PathJacksonSerializer());
-            addSerializer(StarGraphGraphSONSerializer.DirectionalStarGraph.class, new StarGraphGraphSONSerializer(normalize));
+            addSerializer(DirectionalStarGraph.class, new StarGraphGraphSONSerializerV1d0(normalize));
             addSerializer(Tree.class, new GraphSONSerializersV1d0.TreeJacksonSerializer());
            
             // java.util

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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 d95fdff..6f15979 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
@@ -18,13 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-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.structure.*;
 import org.apache.tinkerpop.gremlin.structure.io.GraphReader;
 import org.apache.tinkerpop.gremlin.structure.io.GraphWriter;
 import org.apache.tinkerpop.gremlin.structure.io.Mapper;
@@ -35,7 +29,7 @@ import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
-import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializer;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONDeserializer;
 import org.apache.tinkerpop.gremlin.util.function.FunctionUtils;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.apache.tinkerpop.shaded.jackson.core.type.TypeReference;
@@ -44,12 +38,7 @@ import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 import org.apache.tinkerpop.shaded.jackson.databind.node.JsonNodeType;
 import org.javatuples.Pair;
 
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
+import java.io.*;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -169,14 +158,14 @@ public final class GraphSONReader implements GraphReader {
                              final Function<Attachable<Edge>, Edge> edgeAttachMethod,
                              final Direction attachEdgesOfThisDirection) throws IOException {
         final Map<String, Object> vertexData = mapper.readValue(inputStream, mapTypeReference);
-        final StarGraph starGraph = StarGraphGraphSONSerializer.readStarGraphVertex(vertexData);
+        final StarGraph starGraph = StarGraphGraphSONDeserializer.readStarGraphVertex(vertexData);
         if (vertexAttachMethod != null) vertexAttachMethod.apply(starGraph.getStarVertex());
 
         if (vertexData.containsKey(GraphSONTokens.OUT_E) && (attachEdgesOfThisDirection == Direction.BOTH || attachEdgesOfThisDirection == Direction.OUT))
-            StarGraphGraphSONSerializer.readStarGraphEdges(edgeAttachMethod, starGraph, vertexData, GraphSONTokens.OUT_E);
+            StarGraphGraphSONDeserializer.readStarGraphEdges(edgeAttachMethod, starGraph, vertexData, GraphSONTokens.OUT_E);
 
         if (vertexData.containsKey(GraphSONTokens.IN_E) && (attachEdgesOfThisDirection == Direction.BOTH || attachEdgesOfThisDirection == Direction.IN))
-            StarGraphGraphSONSerializer.readStarGraphEdges(edgeAttachMethod, starGraph, vertexData, GraphSONTokens.IN_E);
+            StarGraphGraphSONDeserializer.readStarGraphEdges(edgeAttachMethod, starGraph, vertexData, GraphSONTokens.IN_E);
 
         return starGraph.getStarVertex();
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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 ed20fd9..c4dcddd 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
@@ -26,32 +26,48 @@ import org.apache.tinkerpop.shaded.jackson.databind.ser.SerializerFactory;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.ToStringSerializer;
 
 /**
- * Implementation of the {@code DefaultSerializerProvider} for Jackson that users the {@code ToStringSerializer} for
+ * Implementation of the {@code DefaultSerializerProvider} for Jackson that uses the {@code ToStringSerializer} for
  * unknown types.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 final class GraphSONSerializerProvider extends DefaultSerializerProvider {
     private static final long serialVersionUID = 1L;
-    private static final ToStringSerializer toStringSerializer = new ToStringSerializer();
+    private final JsonSerializer<Object> unknownTypeSerializer;
 
-    public GraphSONSerializerProvider() {
+    public GraphSONSerializerProvider(GraphSONVersion version) {
         super();
+        if (version == GraphSONVersion.V1_0) {
+            setDefaultKeySerializer(new GraphSONSerializersV1d0.GraphSONKeySerializer());
+            unknownTypeSerializer = new ToStringSerializer();
+        } else {
+            setDefaultKeySerializer(new GraphSONSerializersV2d0.GraphSONKeySerializer());
+            unknownTypeSerializer = new ToStringGraphSONSerializer();
+        }
     }
 
     protected GraphSONSerializerProvider(final SerializerProvider src,
-                                         final SerializationConfig config, final SerializerFactory f) {
+                                         final SerializationConfig config, final SerializerFactory f,
+                                         final GraphSONVersion version) {
         super(src, config, f);
+        if (version == GraphSONVersion.V1_0) {
+            setDefaultKeySerializer(new GraphSONSerializersV1d0.GraphSONKeySerializer());
+            unknownTypeSerializer = new ToStringSerializer();
+        } else {
+            setDefaultKeySerializer(new GraphSONSerializersV2d0.GraphSONKeySerializer());
+            unknownTypeSerializer = new ToStringGraphSONSerializer();
+        }
+
     }
 
     @Override
     public JsonSerializer<Object> getUnknownTypeSerializer(final Class<?> aClass) {
-        return toStringSerializer;
+        return unknownTypeSerializer;
     }
 
     @Override
     public GraphSONSerializerProvider createInstance(final SerializationConfig config,
                                                      final SerializerFactory jsf) {
-        return new GraphSONSerializerProvider(this, config, jsf);
+        return new GraphSONSerializerProvider(this, config, jsf, GraphSONVersion.V1_0);
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java
index 2411d8f..7e78222 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java
@@ -21,14 +21,11 @@ package org.apache.tinkerpop.gremlin.structure.io.graphson;
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
 import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Element;
-import org.apache.tinkerpop.gremlin.structure.Property;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.*;
 import org.apache.tinkerpop.gremlin.structure.util.Comparators;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -42,15 +39,8 @@ import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
 import org.javatuples.Pair;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
 
 /**
  * GraphSON serializers for graph-based objects such as vertices, edges, properties, and paths. These serializers

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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
new file mode 100644
index 0000000..e4f8280
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -0,0 +1,467 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.io.graphson;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
+import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+import org.apache.tinkerpop.gremlin.structure.*;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.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.StdKeySerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.javatuples.Pair;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil.*;
+
+/**
+ * GraphSON serializers for graph-based objects such as vertices, edges, properties, and paths. These serializers
+ * present a generalized way to serialize the implementations of core interfaces.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class GraphSONSerializersV2d0 {
+
+    private GraphSONSerializersV2d0() {
+    }
+
+    final static class VertexPropertyJacksonSerializer extends StdSerializer<VertexProperty> {
+
+        private final boolean normalize;
+
+        public VertexPropertyJacksonSerializer(final boolean normalize) {
+            super(VertexProperty.class);
+            this.normalize = normalize;
+        }
+
+        @Override
+        public void serialize(final VertexProperty property, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            serializerVertexProperty(property, jsonGenerator, serializerProvider, null, normalize, true);
+        }
+
+        @Override
+        public void serializeWithType(final VertexProperty property, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            serializerVertexProperty(property, jsonGenerator, serializerProvider, typeSerializer, normalize, true);
+        }
+    }
+
+    final static class PropertyJacksonSerializer extends StdSerializer<Property> {
+
+        public PropertyJacksonSerializer() {
+            super(Property.class);
+        }
+
+        @Override
+        public void serialize(final Property property, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            ser(property, jsonGenerator, serializerProvider, null);
+        }
+
+        @Override
+        public void serializeWithType(final Property property, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            ser(property, jsonGenerator, serializerProvider, typeSerializer);
+        }
+
+        private static void ser(final Property property, final JsonGenerator jsonGenerator,
+                                final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            writeStartObject(property, jsonGenerator, typeSerializer);
+
+            serializerProvider.defaultSerializeField(GraphSONTokens.KEY, property.key(), jsonGenerator);
+            serializerProvider.defaultSerializeField(GraphSONTokens.VALUE, property.value(), jsonGenerator);
+
+            writeEndObject(property, jsonGenerator, typeSerializer);
+        }
+    }
+
+    final static class EdgeJacksonSerializer extends StdSerializer<Edge> {
+
+        private final boolean normalize;
+
+        public EdgeJacksonSerializer(final boolean normalize) {
+            super(Edge.class);
+            this.normalize = normalize;
+        }
+
+
+        @Override
+        public void serialize(final Edge edge, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            ser(edge, jsonGenerator, serializerProvider, null);
+        }
+
+        @Override
+        public void serializeWithType(final Edge edge, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            ser(edge, jsonGenerator, serializerProvider, typeSerializer);
+        }
+
+        private void ser(final Edge edge, final JsonGenerator jsonGenerator,
+                         final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            writeStartObject(edge, jsonGenerator, typeSerializer);
+
+            GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
+            jsonGenerator.writeStringField(GraphSONTokens.LABEL, edge.label());
+            jsonGenerator.writeStringField(GraphSONTokens.TYPE, GraphSONTokens.EDGE);
+            jsonGenerator.writeStringField(GraphSONTokens.IN_LABEL, edge.inVertex().label());
+            jsonGenerator.writeStringField(GraphSONTokens.OUT_LABEL, edge.outVertex().label());
+            GraphSONUtil.writeWithType(GraphSONTokens.IN, edge.inVertex().id(), jsonGenerator, serializerProvider, typeSerializer);
+            GraphSONUtil.writeWithType(GraphSONTokens.OUT, edge.outVertex().id(), jsonGenerator, serializerProvider, typeSerializer);
+            writeProperties(edge, jsonGenerator, serializerProvider, typeSerializer);
+
+            writeEndObject(edge, jsonGenerator, typeSerializer);
+        }
+
+        private void writeProperties(final Edge edge, final JsonGenerator jsonGenerator,
+                                     final SerializerProvider serializerProvider,
+                                     final TypeSerializer typeSerializer) throws IOException {
+            final Iterator<Property<Object>> elementProperties = normalize ?
+                    IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+            if (elementProperties.hasNext()) {
+                jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+                writeStartObject(edge, jsonGenerator, typeSerializer);
+
+                while (elementProperties.hasNext()) {
+                    final Property<Object> elementProperty = elementProperties.next();
+                    GraphSONUtil.writeWithType(elementProperty.key(), elementProperty.value(), jsonGenerator, serializerProvider, typeSerializer);
+                }
+
+                writeEndObject(edge, jsonGenerator, typeSerializer);
+            }
+        }
+
+    }
+
+    final static class VertexJacksonSerializer extends StdSerializer<Vertex> {
+
+        private final boolean normalize;
+
+        public VertexJacksonSerializer(final boolean normalize) {
+            super(Vertex.class);
+            this.normalize = normalize;
+        }
+
+        @Override
+        public void serialize(final Vertex vertex, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            ser(vertex, jsonGenerator, serializerProvider, null);
+        }
+
+        @Override
+        public void serializeWithType(final Vertex vertex, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            ser(vertex, jsonGenerator, serializerProvider, typeSerializer);
+        }
+
+        private void ser(final Vertex vertex, final JsonGenerator jsonGenerator,
+                         final SerializerProvider serializerProvider, final TypeSerializer typeSerializer)
+                throws IOException {
+            writeStartObject(vertex, jsonGenerator, typeSerializer);
+
+            GraphSONUtil.writeWithType(GraphSONTokens.ID, vertex.id(), jsonGenerator, serializerProvider, typeSerializer);
+            jsonGenerator.writeStringField(GraphSONTokens.LABEL, vertex.label());
+            jsonGenerator.writeStringField(GraphSONTokens.TYPE, GraphSONTokens.VERTEX);
+            writeProperties(vertex, jsonGenerator, serializerProvider, typeSerializer);
+
+            writeEndObject(vertex, jsonGenerator, typeSerializer);
+        }
+
+        private void writeProperties(final Vertex vertex, final JsonGenerator jsonGenerator,
+                                     final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+            writeStartObject(vertex, jsonGenerator, typeSerializer);
+
+            final List<String> keys = normalize ?
+                    IteratorUtils.list(vertex.keys().iterator(), Comparator.naturalOrder()) : new ArrayList<>(vertex.keys());
+            for (String key : keys) {
+                final Iterator<VertexProperty<Object>> vertexProperties = normalize ?
+                        IteratorUtils.list(vertex.properties(key), Comparators.PROPERTY_COMPARATOR).iterator() : vertex.properties(key);
+                if (vertexProperties.hasNext()) {
+                    jsonGenerator.writeFieldName(key);
+                    writeStartArray(vertex, jsonGenerator, typeSerializer);
+
+                    while (vertexProperties.hasNext()) {
+                        serializerVertexProperty(vertexProperties.next(), jsonGenerator, serializerProvider, typeSerializer, normalize, false);
+                    }
+
+                    writeEndArray(vertex, jsonGenerator, typeSerializer);
+                }
+            }
+
+            writeEndObject(vertex, jsonGenerator, typeSerializer);
+        }
+
+    }
+
+    final static class PathJacksonSerializer extends StdSerializer<Path> {
+
+        public PathJacksonSerializer() {
+            super(Path.class);
+        }
+
+        @Override
+        public void serialize(final Path path, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException, JsonGenerationException {
+            ser(path, jsonGenerator, null);
+        }
+
+        @Override
+        public void serializeWithType(final Path path, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer)
+                throws IOException, JsonProcessingException {
+            ser(path, jsonGenerator, typeSerializer);
+        }
+
+        private static void ser(final Path path, final JsonGenerator jsonGenerator, final TypeSerializer typeSerializer)
+                throws IOException {
+            writeStartObject(path, jsonGenerator, typeSerializer);
+
+            jsonGenerator.writeObjectField(GraphSONTokens.LABELS, path.labels());
+            jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, path.objects());
+
+            writeEndObject(path, jsonGenerator, typeSerializer);
+        }
+
+    }
+
+    final static class TreeJacksonSerializer extends StdSerializer<Tree> {
+
+        public TreeJacksonSerializer() {
+            super(Tree.class);
+        }
+
+        @Override
+        public void serialize(final Tree tree, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+            ser(tree, jsonGenerator, null);
+        }
+
+        @Override
+        public void serializeWithType(final Tree tree, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer)
+                throws IOException, JsonProcessingException {
+            ser(tree, jsonGenerator, typeSerializer);
+        }
+
+        private static void ser(final Tree tree, final JsonGenerator jsonGenerator, final TypeSerializer typeSerializer)
+                throws IOException {
+            writeStartObject(tree, jsonGenerator, typeSerializer);
+
+            Set<Map.Entry<Element, Tree>> set = tree.entrySet();
+            for (Map.Entry<Element, Tree> entry : set) {
+                jsonGenerator.writeFieldName(entry.getKey().id().toString());
+                writeStartObject(entry, jsonGenerator, typeSerializer);
+                jsonGenerator.writeObjectField(GraphSONTokens.KEY, entry.getKey());
+                jsonGenerator.writeObjectField(GraphSONTokens.VALUE, entry.getValue());
+                writeEndObject(entry, jsonGenerator, typeSerializer);
+            }
+
+            writeEndObject(tree, jsonGenerator, typeSerializer);
+        }
+    }
+
+    /**
+     * Maps in the JVM can have {@link Object} as a key, but in JSON they must be a {@link String}.
+     */
+    final static class GraphSONKeySerializer extends StdKeySerializer {
+
+        @Override
+        public void serialize(final Object o, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException {
+            ser(o, jsonGenerator, serializerProvider);
+        }
+
+        @Override
+        public void serializeWithType(final Object o, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            ser(o, jsonGenerator, serializerProvider);
+        }
+
+        private void ser(final Object o, final JsonGenerator jsonGenerator,
+                         final SerializerProvider serializerProvider) throws IOException {
+            if (Element.class.isAssignableFrom(o.getClass()))
+                jsonGenerator.writeFieldName((((Element) o).id()).toString());
+            else
+                super.serialize(o, jsonGenerator, serializerProvider);
+        }
+    }
+
+    final static class TraversalExplanationJacksonSerializer extends StdSerializer<TraversalExplanation> {
+        public TraversalExplanationJacksonSerializer() {
+            super(TraversalExplanation.class);
+        }
+
+        @Override
+        public void serialize(final TraversalExplanation traversalExplanation, final JsonGenerator jsonGenerator,
+                              final SerializerProvider serializerProvider) throws IOException {
+            ser(traversalExplanation, jsonGenerator);
+        }
+
+        @Override
+        public void serializeWithType(final TraversalExplanation value, final JsonGenerator gen,
+                                      final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException {
+            ser(value, gen);
+        }
+
+        public void ser(final TraversalExplanation te, final JsonGenerator jsonGenerator) throws IOException {
+            final Map<String, Object> m = new HashMap<>();
+            m.put(GraphSONTokens.ORIGINAL, getStepsAsList(te.getOriginalTraversal()));
+
+            final List<Pair<TraversalStrategy, Traversal.Admin<?, ?>>> strategyTraversals = te.getStrategyTraversals();
+
+            final List<Map<String, Object>> intermediates = new ArrayList<>();
+            for (final Pair<TraversalStrategy, Traversal.Admin<?, ?>> pair : strategyTraversals) {
+                final Map<String, Object> intermediate = new HashMap<>();
+                intermediate.put(GraphSONTokens.STRATEGY, pair.getValue0().toString());
+                intermediate.put(GraphSONTokens.CATEGORY, pair.getValue0().getTraversalCategory().getSimpleName());
+                intermediate.put(GraphSONTokens.TRAVERSAL, getStepsAsList(pair.getValue1()));
+                intermediates.add(intermediate);
+            }
+            m.put(GraphSONTokens.INTERMEDIATE, intermediates);
+
+            if (strategyTraversals.isEmpty())
+                m.put(GraphSONTokens.FINAL, getStepsAsList(te.getOriginalTraversal()));
+            else
+                m.put(GraphSONTokens.FINAL, getStepsAsList(strategyTraversals.get(strategyTraversals.size() - 1).getValue1()));
+
+            jsonGenerator.writeObject(m);
+        }
+
+        private List<String> getStepsAsList(final Traversal.Admin<?, ?> t) {
+            final List<String> steps = new ArrayList<>();
+            t.getSteps().iterator().forEachRemaining(s -> steps.add(s.toString()));
+            return steps;
+        }
+    }
+
+    final static class TraversalMetricsJacksonSerializer extends StdSerializer<TraversalMetrics> {
+        public TraversalMetricsJacksonSerializer() {
+            super(TraversalMetrics.class);
+        }
+
+        @Override
+        public void serialize(final TraversalMetrics property, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            serializeInternal(property, jsonGenerator);
+        }
+
+        @Override
+        public void serializeWithType(final TraversalMetrics property, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+            serializeInternal(property, jsonGenerator);
+        }
+
+        private static void serializeInternal(final TraversalMetrics traversalMetrics, final JsonGenerator jsonGenerator) throws IOException {
+            // creation of the map enables all the fields to be properly written with their type if required
+            final Map<String, Object> m = new HashMap<>();
+            m.put(GraphSONTokens.DURATION, traversalMetrics.getDuration(TimeUnit.NANOSECONDS) / 1000000d);
+            final List<Map<String, Object>> metrics = new ArrayList<>();
+            traversalMetrics.getMetrics().forEach(it -> metrics.add(metricsToMap(it)));
+            m.put(GraphSONTokens.METRICS, metrics);
+
+            jsonGenerator.writeObject(m);
+        }
+
+        private static Map<String, Object> metricsToMap(final Metrics metrics) {
+            final Map<String, Object> m = new HashMap<>();
+            m.put(GraphSONTokens.ID, metrics.getId());
+            m.put(GraphSONTokens.NAME, metrics.getName());
+            m.put(GraphSONTokens.COUNTS, metrics.getCounts());
+            m.put(GraphSONTokens.DURATION, metrics.getDuration(TimeUnit.NANOSECONDS) / 1000000d);
+
+            if (!metrics.getAnnotations().isEmpty()) {
+                m.put(GraphSONTokens.ANNOTATIONS, metrics.getAnnotations());
+            }
+
+            if (!metrics.getNested().isEmpty()) {
+                final List<Map<String, Object>> nested = new ArrayList<>();
+                metrics.getNested().forEach(it -> nested.add(metricsToMap(it)));
+                m.put(GraphSONTokens.METRICS, nested);
+            }
+            return m;
+        }
+    }
+
+    private static void serializerVertexProperty(final VertexProperty property, final JsonGenerator jsonGenerator,
+                                                 final SerializerProvider serializerProvider,
+                                                 final TypeSerializer typeSerializer, final boolean normalize,
+                                                 final boolean includeLabel) throws IOException {
+        writeStartObject(property, jsonGenerator, typeSerializer);
+
+        GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer);
+        GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer);
+        if (includeLabel) jsonGenerator.writeStringField(GraphSONTokens.LABEL, property.label());
+        tryWriteMetaProperties(property, jsonGenerator, serializerProvider, typeSerializer, normalize);
+
+        writeEndObject(property, jsonGenerator, typeSerializer);
+    }
+
+    private static void tryWriteMetaProperties(final VertexProperty property, final JsonGenerator jsonGenerator,
+                                               final SerializerProvider serializerProvider,
+                                               final TypeSerializer typeSerializer, final boolean normalize) throws IOException {
+        // when "detached" you can't check features of the graph it detached from so it has to be
+        // treated differently from a regular VertexProperty implementation.
+        if (property instanceof DetachedVertexProperty) {
+            // only write meta properties key if they exist
+            if (property.properties().hasNext()) {
+                writeMetaProperties(property, jsonGenerator, serializerProvider, typeSerializer, normalize);
+            }
+        } else {
+            // still attached - so we can check the features to see if it's worth even trying to write the
+            // meta properties key
+            if (property.graph().features().vertex().supportsMetaProperties() && property.properties().hasNext()) {
+                writeMetaProperties(property, jsonGenerator, serializerProvider, typeSerializer, normalize);
+            }
+        }
+    }
+
+    private static void writeMetaProperties(final VertexProperty property, final JsonGenerator jsonGenerator,
+                                            final SerializerProvider serializerProvider,
+                                            final TypeSerializer typeSerializer, final boolean normalize) throws IOException {
+        jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+        writeStartObject(property, jsonGenerator, typeSerializer);
+
+        final Iterator<Property<Object>> metaProperties = normalize ?
+                IteratorUtils.list((Iterator<Property<Object>>) property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
+        while (metaProperties.hasNext()) {
+            final Property<Object> metaProperty = metaProperties.next();
+            GraphSONUtil.writeWithType(metaProperty.key(), metaProperty.value(), jsonGenerator, serializerProvider, typeSerializer);
+        }
+
+        writeEndObject(property, jsonGenerator, typeSerializer);
+    }
+
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
new file mode 100644
index 0000000..a7583fc
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
@@ -0,0 +1,201 @@
+/*
+ * 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.structure.io.graphson.GraphSONMapper.TypeInfo;
+import org.apache.tinkerpop.shaded.jackson.annotation.JsonTypeInfo;
+import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
+import org.apache.tinkerpop.shaded.jackson.databind.BeanProperty;
+import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.impl.TypeDeserializerBase;
+import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
+import org.apache.tinkerpop.shaded.jackson.databind.util.TokenBuffer;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Contains main logic for the whole JSON to Java deserialization. Handles types embedded with the version 2.0 of GraphSON.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class GraphSONTypeDeserializer extends TypeDeserializerBase {
+    private final TypeIdResolver idRes;
+    private final String propertyName;
+    private final JavaType baseType;
+    private final TypeInfo typeInfo;
+
+    private static final JavaType mapJavaType = TypeFactory.defaultInstance().constructType(Map.class);
+    private static final JavaType arrayJavaType = TypeFactory.defaultInstance().constructType(List.class);
+
+
+    GraphSONTypeDeserializer(JavaType baseType, TypeIdResolver idRes, String typePropertyName,
+                             TypeInfo typeInfo){
+        super(baseType, idRes, typePropertyName, false, null);
+        this.baseType = baseType;
+        this.idRes = idRes;
+        this.propertyName = typePropertyName;
+        this.typeInfo = typeInfo;
+    }
+
+    @Override
+    public TypeDeserializer forProperty(BeanProperty beanProperty) {
+        return this;
+    }
+
+    @Override
+    public JsonTypeInfo.As getTypeInclusion() {
+        return JsonTypeInfo.As.WRAPPER_ARRAY;
+    }
+
+
+    @Override
+    public TypeIdResolver getTypeIdResolver() {
+        return idRes;
+    }
+
+    @Override
+    public Class<?> getDefaultImpl() {
+        return null;
+    }
+
+    @Override
+    public Object deserializeTypedFromObject(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+        return deserialize(jsonParser, deserializationContext);
+    }
+
+    @Override
+    public Object deserializeTypedFromArray(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+        return deserialize(jsonParser, deserializationContext);
+    }
+
+    @Override
+    public Object deserializeTypedFromScalar(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+        return deserialize(jsonParser, deserializationContext);
+    }
+
+    @Override
+    public Object deserializeTypedFromAny(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+        return deserialize(jsonParser, deserializationContext);
+    }
+
+    /**
+     * Main logic for the deserialization.
+     */
+    private Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+        TokenBuffer buf = new TokenBuffer(jsonParser.getCodec(), false);
+
+        // Detect type
+        try {
+            // The Type pattern is START_ARRAY -> START_OBJECT -> TEXT_FIELD(propertyName).
+            if (jsonParser.getCurrentToken() == JsonToken.START_ARRAY) {
+                buf.writeStartArray();
+                JsonToken t1 = jsonParser.nextToken();
+
+                if (t1 == JsonToken.START_OBJECT) {
+                    buf.writeStartObject();
+                    String nextFieldName = jsonParser.nextFieldName();
+
+                    if (nextFieldName != null) {
+                        if (nextFieldName.equals(propertyName)) {
+                            // Detected type pattern
+                            // Find deserializer
+                            // Deserialize with deserializer
+                            String typeName = jsonParser.nextTextValue();
+                            JavaType typeFromId = idRes.typeFromId(typeName);
+
+                            // Detected a type and extracted the value, but still want to make sure that the extracted type
+                            // corresponds to what was given in parameter, if a type has been explicitly specified in param.
+                            if (!baseType.isJavaLangObject() && baseType != typeFromId) {
+                                throw new InstantiationException(
+                                        String.format("Cannot deserialize the value with the detected type contained in the JSON (\"%s\") " +
+                                                "to the type specified in parameter to the object mapper (%s). " +
+                                                "Those types are incompatible.", typeName, baseType.getRawClass().toString())
+                                );
+                            }
+
+                            JsonDeserializer jsonDeserializer = deserializationContext.findContextualValueDeserializer(typeFromId, null);
+
+                            // Position the next token right on the value
+                            if (jsonParser.nextToken() == JsonToken.END_OBJECT) {
+                                // Locate the cursor on the value to deser
+                                jsonParser.nextValue();
+                                Object value = jsonDeserializer.deserialize(jsonParser, deserializationContext);
+                                // IMPORTANT - Close the JSON ARRAY
+                                jsonParser.nextToken();
+                                return value;
+                            }
+                        }
+                    }
+
+                }
+            }
+        } catch (Exception e) {
+            throw deserializationContext.mappingException("Could not deserialize the JSON value as required. " + e.getMessage());
+        }
+
+        JsonParser toUseParser;
+        JsonParser bufferParser = buf.asParser();
+        JsonToken t = bufferParser.nextToken();
+
+        // While searching for the type pattern, we may have moved the cursor of the original JsonParser in param.
+        // To compensate, we have filled consistently a TokenBuffer that should contain the equivalent of
+        // what we skipped while searching for the pattern.
+        // This has an huge positive impact on performances, since JsonParser does not have a 'rewind()',
+        // the only other solution would have been to copy the whole original JsonParser. Which we avoid here and use
+        // an efficient structure made of TokenBuffer + JsonParserSequence/Concat.
+        if (t != null)
+            toUseParser = JsonParserConcat.createFlattened(bufferParser, jsonParser);
+
+        // If the cursor hasn't been moved, no need to concatenate the original JsonParser with the TokenBuffer's one.
+        else
+            toUseParser = jsonParser;
+
+        // If a type has been specified in parameter :
+        if (!baseType.isJavaLangObject()) {
+            JsonDeserializer jsonDeserializer = deserializationContext.findContextualValueDeserializer(baseType, null);
+            return jsonDeserializer.deserialize(toUseParser, deserializationContext);
+        }
+        // Otherwise, detect the current structure :
+        else {
+            if (toUseParser.isExpectedStartArrayToken()) {
+                return deserializationContext.findContextualValueDeserializer(arrayJavaType, null).deserialize(toUseParser, deserializationContext);
+            } else if (toUseParser.isExpectedStartObjectToken()) {
+                return deserializationContext.findContextualValueDeserializer(mapJavaType, null).deserialize(toUseParser, deserializationContext);
+            } else {
+                // There's JavaLangObject in param, there's no type detected in the payload, the payload isn't a JSON Map or JSON List
+                // then consider it a simple type, even though we shouldn't be here if it was a simple type.
+                // TODO : maybe throw an error instead?
+                // throw deserializationContext.mappingException("Roger, we have a problem deserializing");
+                JsonDeserializer jsonDeserializer = deserializationContext.findContextualValueDeserializer(baseType, null);
+                return jsonDeserializer.deserialize(toUseParser, deserializationContext);
+            }
+        }
+    }
+
+    private boolean canReadTypeId() {
+        return this.typeInfo == TypeInfo.PARTIAL_TYPES;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java
new file mode 100644
index 0000000..97790ef
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java
@@ -0,0 +1,134 @@
+/*
+ * 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.databind.DatabindContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
+import org.apache.tinkerpop.shaded.jackson.databind.util.TokenBuffer;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.sql.Timestamp;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Provides quick lookup for Type deserialization extracted from the JSON payload. As well as the Java Object to types
+ * compatible for the version 2.0 of GraphSON.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class GraphSONTypeIdResolver implements TypeIdResolver {
+
+    private final Map<String, JavaType> idToType = new HashMap<>();
+
+    GraphSONTypeIdResolver() {
+        // Need to add all the "Standard typed scalar" classes manually...
+        Arrays.asList(
+                Float.class,
+                Long.class,
+                Short.class,
+                BigInteger.class,
+                BigDecimal.class,
+                Byte.class,
+                Character.class,
+                UUID.class,
+                InetAddress.class,
+                InetSocketAddress.class,
+                ByteBuffer.class,
+                Class.class,
+                Calendar.class,
+                Date.class,
+                TimeZone.class,
+                Timestamp.class,
+                AtomicBoolean.class,
+                AtomicReference.class,
+                TokenBuffer.class
+        ).forEach(e -> idToType.put(e.getSimpleName(), TypeFactory.defaultInstance().constructType(e)));
+    }
+
+    public Map<String, JavaType> getIdToType() {
+        return idToType;
+    }
+
+    public GraphSONTypeIdResolver addCustomType(Class clasz) {
+        // May override types already registered, that's wanted.
+        getIdToType().put(clasz.getSimpleName(), TypeFactory.defaultInstance().constructType(clasz));
+        return this;
+    }
+
+    // Override manually a type definition.
+    public GraphSONTypeIdResolver addCustomType(String name, Class clasz) {
+        // May override types already registered, that's wanted.
+        getIdToType().put(name, TypeFactory.defaultInstance().constructType(clasz));
+        return this;
+    }
+
+    @Override
+    public void init(JavaType javaType) {
+    }
+
+    @Override
+    public String idFromValue(Object o) {
+        return idFromValueAndType(o, null);
+    }
+
+    @Override
+    public String idFromValueAndType(Object o, Class<?> aClass) {
+        // May be improved later
+        return o.getClass().getSimpleName();
+    }
+
+    @Override
+    public String idFromBaseType() {
+        return null;
+    }
+
+    @Override
+    public JavaType typeFromId(String s) {
+        return typeFromId(null, s);
+    }
+
+    @Override
+    public JavaType typeFromId(DatabindContext databindContext, String s) {
+        // Get the type from the string from the stored Map. If not found, default to deserialize as a String.
+        return getIdToType().get(s) != null
+                ? getIdToType().get(s)
+                // TODO: shouldn't we fail instead, if the type is not found? Or log something?
+                : TypeFactory.defaultInstance().constructType(String.class);
+    }
+
+    @Override
+    public String getDescForKnownTypeIds() {
+        // TODO (?)
+        return "GraphSON advanced typing system";
+    }
+
+    @Override
+    public JsonTypeInfo.Id getMechanism() {
+        return JsonTypeInfo.Id.CUSTOM;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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
new file mode 100644
index 0000000..87ab3a3
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
@@ -0,0 +1,60 @@
+/*
+ * 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.structure.io.graphson.GraphSONMapper.TypeInfo;
+import org.apache.tinkerpop.shaded.jackson.databind.DeserializationConfig;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializationConfig;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.NamedType;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
+
+import java.util.Collection;
+
+/**
+ * Creates the Type serializers as well as the Typed deserializers that will be provided to the serializers and
+ * deserializers. Contains the typeInfo level that should be provided by the GraphSONMapper.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class GraphSONTypeResolverBuilder extends StdTypeResolverBuilder {
+
+    private TypeInfo typeInfo;
+
+    @Override
+    public TypeDeserializer buildTypeDeserializer(DeserializationConfig config, JavaType baseType, Collection<NamedType> subtypes) {
+        TypeIdResolver idRes = this.idResolver(config, baseType, subtypes, false, true);
+        return new GraphSONTypeDeserializer(baseType, idRes, this.getTypeProperty(), typeInfo);
+    }
+
+
+    @Override
+    public TypeSerializer buildTypeSerializer(SerializationConfig config, JavaType baseType, Collection<NamedType> subtypes) {
+        TypeIdResolver idRes = this.idResolver(config, baseType, subtypes, true, false);
+        return new GraphSONTypeSerializer(idRes, this.getTypeProperty(), typeInfo);
+    }
+
+    public StdTypeResolverBuilder typesEmbedding(TypeInfo typeInfo) {
+        this.typeInfo = typeInfo;
+        return this;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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
new file mode 100644
index 0000000..5511b10
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
@@ -0,0 +1,160 @@
+/*
+ * 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.structure.io.graphson.GraphSONMapper.TypeInfo;
+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;
+
+/**
+ * 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;
+
+    GraphSONTypeSerializer(TypeIdResolver idRes, String propertyName, TypeInfo typeInfo) {
+        this.idRes = idRes;
+        this.propertyName = propertyName;
+        this.typeInfo = typeInfo;
+    }
+
+    @Override
+    public TypeSerializer forProperty(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(Object o, JsonGenerator jsonGenerator) throws IOException {
+        if (canWriteTypeId()) {
+            writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValue(o));
+        }
+    }
+
+    @Override
+    public void writeTypePrefixForObject(Object o, JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeStartObject();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(Map);
+    }
+
+    @Override
+    public void writeTypePrefixForArray(Object o, JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeStartArray();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(List);
+    }
+
+    @Override
+    public void writeTypeSuffixForScalar(Object o, JsonGenerator jsonGenerator) throws IOException {
+        if (canWriteTypeId()) {
+            writeTypeSuffix(jsonGenerator);
+        }
+    }
+
+    @Override
+    public void writeTypeSuffixForObject(Object o, JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeEndObject();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(Map);
+    }
+
+    @Override
+    public void writeTypeSuffixForArray(Object o, JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeEndArray();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(List);
+    }
+
+    @Override
+    public void writeCustomTypePrefixForScalar(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+        if (canWriteTypeId()) {
+            writeTypePrefix(jsonGenerator, s);
+        }
+    }
+
+    @Override
+    public void writeCustomTypePrefixForObject(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+        jsonGenerator.writeStartObject();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
+    }
+
+    @Override
+    public void writeCustomTypePrefixForArray(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+        jsonGenerator.writeStartArray();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
+    }
+
+    @Override
+    public void writeCustomTypeSuffixForScalar(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+        if (canWriteTypeId()) {
+            writeTypeSuffix(jsonGenerator);
+        }
+    }
+
+    @Override
+    public void writeCustomTypeSuffixForObject(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+        jsonGenerator.writeEndObject();
+        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
+    }
+
+    @Override
+    public void writeCustomTypeSuffixForArray(Object o, JsonGenerator jsonGenerator, 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(JsonGenerator jsonGenerator, String s) throws IOException {
+        jsonGenerator.writeStartArray();
+        jsonGenerator.writeStartObject();
+        jsonGenerator.writeStringField(this.getPropertyName(), s);
+        jsonGenerator.writeEndObject();
+    }
+
+    private void writeTypeSuffix(JsonGenerator jsonGenerator) throws IOException {
+        jsonGenerator.writeEndArray();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
index 9ff427c..3b3ad79 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
@@ -55,4 +55,33 @@ public final class GraphSONUtil {
             serializer.serialize(object, jsonGenerator, serializerProvider);
         }
     }
+
+    public static void writeStartObject(Object o, JsonGenerator jsonGenerator, TypeSerializer typeSerializer) throws IOException {
+        if (typeSerializer != null)
+            typeSerializer.writeTypePrefixForObject(o, jsonGenerator);
+        else
+            jsonGenerator.writeStartObject();
+    }
+
+    public static void writeEndObject(Object o, JsonGenerator jsonGenerator, TypeSerializer typeSerializer) throws IOException {
+        if (typeSerializer != null)
+            typeSerializer.writeTypeSuffixForObject(o, jsonGenerator);
+        else
+            jsonGenerator.writeEndObject();
+    }
+
+    public static void writeStartArray(Object o, JsonGenerator jsonGenerator, TypeSerializer typeSerializer) throws IOException {
+        if (typeSerializer != null)
+            typeSerializer.writeTypePrefixForArray(o, jsonGenerator);
+        else
+            jsonGenerator.writeStartArray();
+    }
+
+
+    public static void writeEndArray(Object o, JsonGenerator jsonGenerator, TypeSerializer typeSerializer) throws IOException {
+        if (typeSerializer != null)
+            typeSerializer.writeTypeSuffixForArray(o, jsonGenerator);
+        else
+            jsonGenerator.writeEndArray();
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
index 37ed9a0..1dd2c9c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
@@ -18,17 +18,11 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Element;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.structure.Property;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.*;
 import org.apache.tinkerpop.gremlin.structure.io.GraphWriter;
 import org.apache.tinkerpop.gremlin.structure.io.Mapper;
+import org.apache.tinkerpop.gremlin.structure.util.star.DirectionalStarGraph;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
-import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 
 import java.io.*;
@@ -74,7 +68,7 @@ public final class GraphSONWriter implements GraphWriter {
      */
     @Override
     public void writeVertex(final OutputStream outputStream, final Vertex v, final Direction direction) throws IOException {
-        mapper.writeValue(outputStream, new StarGraphGraphSONSerializer.DirectionalStarGraph(StarGraph.of(v), direction));
+        mapper.writeValue(outputStream, new DirectionalStarGraph(StarGraph.of(v), direction));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java
index 763c1d9..ba4b056 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java
@@ -27,19 +27,7 @@ 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.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.MonthDay;
-import java.time.OffsetDateTime;
-import java.time.OffsetTime;
-import java.time.Period;
-import java.time.Year;
-import java.time.YearMonth;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
+import java.time.*;
 
 /**
  * GraphSON serializers for classes in {@code java.time.*}.