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:09 UTC

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

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
new file mode 100644
index 0000000..4702092
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
@@ -0,0 +1,311 @@
+/*
+ * 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.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
+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.StdSerializer;
+
+import java.io.IOException;
+import java.time.*;
+
+/**
+ * GraphSON serializers for classes in {@code java.time.*} for the version 2.0 of GraphSON.
+ */
+final class JavaTimeSerializersV2d0 {
+
+    private JavaTimeSerializersV2d0() {}
+
+    /**
+     * Base class for serializing the {@code java.time.*} to ISO-8061 formats.
+     */
+    static abstract class AbstractJavaTimeSerializer<T> extends StdSerializer<T> {
+
+        public AbstractJavaTimeSerializer(final Class<T> clazz) {
+            super(clazz);
+        }
+
+        @Override
+        public void serialize(final T value, final JsonGenerator gen,
+                              final SerializerProvider serializerProvider) throws IOException {
+            gen.writeString(value.toString());
+        }
+
+        @Override
+        public void serializeWithType(final T value, final JsonGenerator gen,
+                                      final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException {
+            typeSer.writeTypePrefixForScalar(value, gen);
+            gen.writeString(value.toString());
+            typeSer.writeTypeSuffixForScalar(value, gen);
+        }
+    }
+    /**
+     * Base class for serializing the {@code java.time.*} from ISO-8061 formats.
+     */
+    abstract static class AbstractJavaTimeJacksonDeserializer<T> extends StdDeserializer<T> {
+        public AbstractJavaTimeJacksonDeserializer(final Class<T> clazz) {
+            super(clazz);
+        }
+
+        public abstract T parse(final String val);
+
+        @Override
+        public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
+            return parse(jsonParser.getText());
+        }
+    }
+
+    final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> {
+
+        public DurationJacksonSerializer() {
+            super(Duration.class);
+        }
+    }
+
+    final static class DurationJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Duration> {
+        public DurationJacksonDeserializer() {
+            super(Duration.class);
+        }
+
+        @Override
+        public Duration parse(final String val) {
+            return Duration.parse(val);
+        }
+    }
+
+    final static class InstantJacksonSerializer extends AbstractJavaTimeSerializer<Instant> {
+
+        public InstantJacksonSerializer() {
+            super(Instant.class);
+        }
+    }
+
+    final static class InstantJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Instant> {
+        public InstantJacksonDeserializer() {
+            super(Instant.class);
+        }
+
+        @Override
+        public Instant parse(final String val) {
+            return Instant.parse(val);
+        }
+    }
+
+    final static class LocalDateJacksonSerializer extends AbstractJavaTimeSerializer<LocalDate> {
+
+        public LocalDateJacksonSerializer() {
+            super(LocalDate.class);
+        }
+    }
+
+    final static class LocalDateJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDate> {
+        public LocalDateJacksonDeserializer() {
+            super(LocalDate.class);
+        }
+
+        @Override
+        public LocalDate parse(final String val) {
+            return LocalDate.parse(val);
+        }
+    }
+
+    final static class LocalDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalDateTime> {
+
+        public LocalDateTimeJacksonSerializer() {
+            super(LocalDateTime.class);
+        }
+    }
+
+    final static class LocalDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDateTime> {
+        public LocalDateTimeJacksonDeserializer() {
+            super(LocalDateTime.class);
+        }
+
+        @Override
+        public LocalDateTime parse(final String val) {
+            return LocalDateTime.parse(val);
+        }
+    }
+
+    final static class LocalTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalTime> {
+
+        public LocalTimeJacksonSerializer() {
+            super(LocalTime.class);
+        }
+    }
+
+    final static class LocalTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalTime> {
+        public LocalTimeJacksonDeserializer() {
+            super(LocalTime.class);
+        }
+
+        @Override
+        public LocalTime parse(final String val) {
+            return LocalTime.parse(val);
+        }
+    }
+
+    final static class MonthDayJacksonSerializer extends AbstractJavaTimeSerializer<MonthDay> {
+
+        public MonthDayJacksonSerializer() {
+            super(MonthDay.class);
+        }
+    }
+
+    final static class MonthDayJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<MonthDay> {
+        public MonthDayJacksonDeserializer() {
+            super(MonthDay.class);
+        }
+
+        @Override
+        public MonthDay parse(final String val) {
+            return MonthDay.parse(val);
+        }
+    }
+
+    final static class OffsetDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetDateTime> {
+
+        public OffsetDateTimeJacksonSerializer() {
+            super(OffsetDateTime.class);
+        }
+    }
+
+    final static class OffsetDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetDateTime> {
+        public OffsetDateTimeJacksonDeserializer() {
+            super(OffsetDateTime.class);
+        }
+
+        @Override
+        public OffsetDateTime parse(final String val) {
+            return OffsetDateTime.parse(val);
+        }
+    }
+
+    final static class OffsetTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetTime> {
+
+        public OffsetTimeJacksonSerializer() {
+            super(OffsetTime.class);
+        }
+    }
+
+    final static class OffsetTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetTime> {
+        public OffsetTimeJacksonDeserializer() {
+            super(OffsetTime.class);
+        }
+
+        @Override
+        public OffsetTime parse(final String val) {
+            return OffsetTime.parse(val);
+        }
+    }
+
+    final static class PeriodJacksonSerializer extends AbstractJavaTimeSerializer<Period> {
+
+        public PeriodJacksonSerializer() {
+            super(Period.class);
+        }
+    }
+
+    final static class PeriodJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Period> {
+        public PeriodJacksonDeserializer() {
+            super(Period.class);
+        }
+
+        @Override
+        public Period parse(final String val) {
+            return Period.parse(val);
+        }
+    }
+
+    final static class YearJacksonSerializer extends AbstractJavaTimeSerializer<Year> {
+
+        public YearJacksonSerializer() {
+            super(Year.class);
+        }
+    }
+
+    final static class YearJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Year> {
+        public YearJacksonDeserializer() {
+            super(Year.class);
+        }
+
+        @Override
+        public Year parse(final String val) {
+            return Year.parse(val);
+        }
+    }
+
+    final static class YearMonthJacksonSerializer extends AbstractJavaTimeSerializer<YearMonth> {
+
+        public YearMonthJacksonSerializer() {
+            super(YearMonth.class);
+        }
+    }
+
+    final static class YearMonthJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<YearMonth> {
+        public YearMonthJacksonDeserializer() {
+            super(YearMonth.class);
+        }
+
+        @Override
+        public YearMonth parse(final String val) {
+            return YearMonth.parse(val);
+        }
+    }
+
+    final static class ZonedDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<ZonedDateTime> {
+
+        public ZonedDateTimeJacksonSerializer() {
+            super(ZonedDateTime.class);
+        }
+    }
+
+    final static class ZonedDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZonedDateTime> {
+        public ZonedDateTimeJacksonDeserializer() {
+            super(ZonedDateTime.class);
+        }
+
+        @Override
+        public ZonedDateTime parse(final String val) {
+            return ZonedDateTime.parse(val);
+        }
+    }
+
+    final static class ZoneOffsetJacksonSerializer extends AbstractJavaTimeSerializer<ZoneOffset> {
+
+        public ZoneOffsetJacksonSerializer() {
+            super(ZoneOffset.class);
+        }
+    }
+
+    final static class ZoneOffsetJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZoneOffset> {
+        public ZoneOffsetJacksonDeserializer() {
+            super(ZoneOffset.class);
+        }
+
+        @Override
+        public ZoneOffset parse(final String val) {
+            return ZoneOffset.of(val);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV2d0.java
new file mode 100644
index 0000000..5dc095e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV2d0.java
@@ -0,0 +1,116 @@
+/*
+ * 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.Element;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializationFeature;
+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.ByteBufferSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * GraphSON serializers for classes in {@code java.util.*} for the version 2.0 of GraphSON.
+ */
+final class JavaUtilSerializersV2d0 {
+
+    private JavaUtilSerializersV2d0() {}
+
+    final static class MapEntryJacksonSerializer extends StdSerializer<Map.Entry> {
+
+        public MapEntryJacksonSerializer() {
+            super(Map.Entry.class);
+        }
+
+        @Override
+        public void serialize(final Map.Entry entry, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            ser(entry, jsonGenerator, serializerProvider);
+            jsonGenerator.writeEndObject();
+        }
+
+        @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);
+            typeSerializer.writeTypeSuffixForObject(entry, jsonGenerator);
+        }
+
+        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);
+        }
+    }
+
+    final static class GraphSONByteBufferSerializer extends StdSerializer<ByteBuffer> {
+
+        ByteBufferSerializer byteBufferSerializer;
+
+        public GraphSONByteBufferSerializer() {
+            super(ByteBuffer.class);
+            byteBufferSerializer = new ByteBufferSerializer();
+        }
+
+        @Override
+        public void serialize(ByteBuffer byteBuffer, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            ser(byteBuffer, jsonGenerator, serializerProvider);
+        }
+
+        @Override
+        public void serializeWithType(final ByteBuffer entry, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+
+            typeSerializer.writeCustomTypePrefixForScalar(entry, jsonGenerator, "ByteBuffer");
+            ser(entry, jsonGenerator, serializerProvider);
+            typeSerializer.writeCustomTypeSuffixForScalar(entry, jsonGenerator, "ByteBuffer");
+        }
+
+        private void ser(final ByteBuffer entry, final JsonGenerator jsonGenerator,
+                                final SerializerProvider serializerProvider) throws IOException {
+            byteBufferSerializer.serialize(entry, jsonGenerator, serializerProvider);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JsonParserConcat.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JsonParserConcat.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JsonParserConcat.java
new file mode 100644
index 0000000..73fe224
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JsonParserConcat.java
@@ -0,0 +1,81 @@
+/*
+ * 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.core.JsonParseException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
+import org.apache.tinkerpop.shaded.jackson.core.util.JsonParserSequence;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * Utility class to easily concatenate multiple JsonParsers. This class had to be implemented because the class it is
+ * extending, {@link JsonParserSequence}, inevitably skips a token when switching from one empty parser to a new one.
+ * I.e. it is automatically calling {@link JsonParser#nextToken()} when switching to the new parser, ignoring
+ * the current token.
+ *
+ * This class is used for high performance in GraphSON when trying to detect types.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class JsonParserConcat extends JsonParserSequence {
+    protected JsonParserConcat(JsonParser[] parsers) {
+        super(parsers);
+    }
+
+    public static JsonParserConcat createFlattened(JsonParser first, JsonParser second) {
+        if (!(first instanceof JsonParserConcat) && !(second instanceof JsonParserConcat)) {
+            return new JsonParserConcat(new JsonParser[]{first, second});
+        } else {
+            ArrayList p = new ArrayList();
+            if (first instanceof JsonParserConcat) {
+                ((JsonParserConcat) first).addFlattenedActiveParsers(p);
+            } else {
+                p.add(first);
+            }
+
+            if (second instanceof JsonParserConcat) {
+                ((JsonParserConcat) second).addFlattenedActiveParsers(p);
+            } else {
+                p.add(second);
+            }
+            return new JsonParserConcat((JsonParser[]) p.toArray(new JsonParser[p.size()]));
+        }
+    }
+
+    @Override
+    public JsonToken nextToken() throws IOException, JsonParseException {
+        JsonToken t = this.delegate.nextToken();
+        if (t != null) {
+            return t;
+        } else {
+            do {
+                if (!this.switchToNext()) {
+                    return null;
+                }
+                // call getCurrentToken() instead of nextToken() in JsonParserSequence.
+                t = this.delegate.getCurrentToken();
+            } while (t == null);
+
+            return t;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
index f015193..852d82d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.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.Property;
-import org.apache.tinkerpop.gremlin.structure.T;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-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.Io;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
@@ -37,11 +31,7 @@ import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Function;
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
new file mode 100644
index 0000000..110b2a0
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
@@ -0,0 +1,59 @@
+/*
+ * 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.databind.JsonDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * A {@link SimpleModule} extension that does the necessary work to make the automatic typed deserialization
+ * without full canonical class names work.
+ *
+ * Users of custom modules with the GraphSONMapper that want their objects to be deserialized automatically by the
+ * mapper, must extend this class with their module. It is the only required step.
+ *
+ * Using this basis module allows the serialization and deserialization of typed objects without having the whole
+ * canonical name of the serialized classes included in the Json payload. This is also necessary because Java
+ * does not provide an agnostic way to search in a classpath a find a class by its simple name. Although that could
+ * be done with an external library, later if we deem it necessary.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class TinkerPopJacksonModule extends SimpleModule {
+
+    private Map<String, Class> addedDeserializers = new LinkedHashMap<>();
+
+    public TinkerPopJacksonModule(String name) {
+        super(name);
+    }
+
+    @Override
+    public <T> SimpleModule addDeserializer(Class<T> type, JsonDeserializer<? extends T> deser) {
+        addedDeserializers.put(type.getSimpleName(), type);
+        return super.addDeserializer(type, deser);
+    }
+
+    public Map<String, Class> getAddedDeserializers() {
+        return addedDeserializers;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
new file mode 100644
index 0000000..fbd9e00
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.core.JsonGenerator;
+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.ToStringSerializer;
+
+import java.io.IOException;
+
+/**
+ * A different implementation of the {@link ToStringSerializer} that does not serialize types by calling
+ * `typeSerializer.writeTypePrefixForScalar()` for unknown objects, because it doesn't make sense when there is a
+ * custom types mechanism in place.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class ToStringGraphSONSerializer extends ToStringSerializer {
+    @Override
+    public void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, TypeSerializer typeSer) throws IOException {
+        this.serialize(value, gen, provider);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
new file mode 100644
index 0000000..ed7b58c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+public class DirectionalStarGraph {
+    private final Direction direction;
+    private final StarGraph starGraphToSerialize;
+
+    public DirectionalStarGraph(final StarGraph starGraphToSerialize, final Direction direction) {
+        this.direction = direction;
+        this.starGraphToSerialize = starGraphToSerialize;
+    }
+
+    public Direction getDirection() {
+        return direction;
+    }
+
+    public StarGraph getStarGraphToSerialize() {
+        return starGraphToSerialize;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
new file mode 100644
index 0000000..84a3fd4
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
@@ -0,0 +1,91 @@
+/*
+ * 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.Edge;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.util.Attachable;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * Provides helper functions for reading vertex and edges from their serialized GraphSON forms.
+ */
+public class StarGraphGraphSONDeserializer {
+
+    /**
+     * A helper function for reading vertex edges from a serialized {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraph} (i.e. a {@link java.util.Map}) generated by
+     * {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV1d0}.
+     */
+    public static void readStarGraphEdges(final Function<Attachable<Edge>, Edge> edgeMaker,
+                                          final StarGraph starGraph,
+                                          final Map<String, Object> vertexData,
+                                          final String direction) throws IOException {
+        final Map<String, List<Map<String,Object>>> edgeDatas = (Map<String, List<Map<String,Object>>>) vertexData.get(direction);
+        for (Map.Entry<String, List<Map<String,Object>>> edgeData : edgeDatas.entrySet()) {
+            for (Map<String,Object> inner : edgeData.getValue()) {
+                final StarGraph.StarEdge starEdge;
+                if (direction.equals(GraphSONTokens.OUT_E))
+                    starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addOutEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.IN)), T.id, inner.get(GraphSONTokens.ID));
+                else
+                    starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addInEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.OUT)), T.id, inner.get(GraphSONTokens.ID));
+
+                if (inner.containsKey(GraphSONTokens.PROPERTIES)) {
+                    final Map<String, Object> edgePropertyData = (Map<String, Object>) inner.get(GraphSONTokens.PROPERTIES);
+                    for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
+                        starEdge.property(epd.getKey(), epd.getValue());
+                    }
+                }
+
+                if (edgeMaker != null) edgeMaker.apply(starEdge);
+            }
+        }
+    }
+
+    /**
+     * A helper function for reading a serialized {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraph} from a {@link java.util.Map} generated by
+     * {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV1d0}.
+     */
+    public static StarGraph readStarGraphVertex(final Map<String, Object> vertexData) throws IOException {
+        final StarGraph starGraph = StarGraph.open();
+        starGraph.addVertex(T.id, vertexData.get(GraphSONTokens.ID), T.label, vertexData.get(GraphSONTokens.LABEL));
+        if (vertexData.containsKey(GraphSONTokens.PROPERTIES)) {
+            final Map<String, List<Map<String, Object>>> properties = (Map<String, List<Map<String, Object>>>) vertexData.get(GraphSONTokens.PROPERTIES);
+            for (Map.Entry<String, List<Map<String, Object>>> property : properties.entrySet()) {
+                for (Map<String, Object> p : property.getValue()) {
+                    final StarGraph.StarVertexProperty vp = (StarGraph.StarVertexProperty) starGraph.getStarVertex().property(VertexProperty.Cardinality.list, property.getKey(), p.get(GraphSONTokens.VALUE), T.id, p.get(GraphSONTokens.ID));
+                    if (p.containsKey(GraphSONTokens.PROPERTIES)) {
+                        final Map<String, Object> edgePropertyData = (Map<String, Object>) p.get(GraphSONTokens.PROPERTIES);
+                        for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
+                            vp.property(epd.getKey(), epd.getValue());
+                        }
+                    }
+                }
+            }
+        }
+
+        return starGraph;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
deleted file mode 100644
index 3d1a16a..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
+++ /dev/null
@@ -1,250 +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.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.T;
-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.Attachable;
-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.ArrayList;
-import java.util.Collections;
-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.TreeSet;
-import java.util.function.Function;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public class StarGraphGraphSONSerializer extends StdSerializer<StarGraphGraphSONSerializer.DirectionalStarGraph> {
-    private final boolean normalize;
-    public StarGraphGraphSONSerializer(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();
-        jsonGenerator.writeStartObject();
-        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-        GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
-        jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
-        if (directionalStarGraph.direction != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
-        if (directionalStarGraph.direction != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
-        if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
-            jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
-            if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-            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.writeArrayFieldStart(k);
-                if (typeSerializer != null) {
-                    jsonGenerator.writeString(ArrayList.class.getName());
-                    jsonGenerator.writeStartArray();
-                }
-
-                final List<VertexProperty> vertexProperties = normalize ?sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
-                for (final VertexProperty property : vertexProperties) {
-                    jsonGenerator.writeStartObject();
-                    if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-                    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.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
-                        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-                        while (metaProperties.hasNext()) {
-                            final Property<Object> meta = metaProperties.next();
-                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
-                        }
-                        jsonGenerator.writeEndObject();
-                    }
-                    jsonGenerator.writeEndObject();
-                }
-                jsonGenerator.writeEndArray();
-                if (typeSerializer != null) jsonGenerator.writeEndArray();
-            }
-            jsonGenerator.writeEndObject();
-        }
-    }
-
-    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.writeObjectFieldStart(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
-            if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-            final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
-            for (final String k : keys) {
-                final List<Edge> edges = starEdges.get(k);
-                jsonGenerator.writeArrayFieldStart(k);
-                if (typeSerializer != null) {
-                    jsonGenerator.writeString(ArrayList.class.getName());
-                    jsonGenerator.writeStartArray();
-                }
-
-                final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
-                for (final Edge edge : edgesToWrite) {
-                    jsonGenerator.writeStartObject();
-                    if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-                    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.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
-                        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-                        while (edgeProperties.hasNext()) {
-                            final Property<Object> meta = edgeProperties.next();
-                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
-                        }
-                        jsonGenerator.writeEndObject();
-                    }
-                    jsonGenerator.writeEndObject();
-                }
-                jsonGenerator.writeEndArray();
-                if (typeSerializer != null) jsonGenerator.writeEndArray();
-            }
-            jsonGenerator.writeEndObject();
-        }
-    }
-
-    /**
-     * A helper function for reading vertex edges from a serialized {@link StarGraph} (i.e. a {@link Map}) generated by
-     * {@link StarGraphGraphSONSerializer}.
-     */
-    public static void readStarGraphEdges(final Function<Attachable<Edge>, Edge> edgeMaker,
-                                          final StarGraph starGraph,
-                                          final Map<String, Object> vertexData,
-                                          final String direction) throws IOException {
-        final Map<String, List<Map<String,Object>>> edgeDatas = (Map<String, List<Map<String,Object>>>) vertexData.get(direction);
-        for (Map.Entry<String, List<Map<String,Object>>> edgeData : edgeDatas.entrySet()) {
-            for (Map<String,Object> inner : edgeData.getValue()) {
-                final StarGraph.StarEdge starEdge;
-                if (direction.equals(GraphSONTokens.OUT_E))
-                    starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addOutEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.IN)), T.id, inner.get(GraphSONTokens.ID));
-                else
-                    starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addInEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.OUT)), T.id, inner.get(GraphSONTokens.ID));
-
-                if (inner.containsKey(GraphSONTokens.PROPERTIES)) {
-                    final Map<String, Object> edgePropertyData = (Map<String, Object>) inner.get(GraphSONTokens.PROPERTIES);
-                    for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
-                        starEdge.property(epd.getKey(), epd.getValue());
-                    }
-                }
-
-                if (edgeMaker != null) edgeMaker.apply(starEdge);
-            }
-        }
-    }
-
-    /**
-     * A helper function for reading a serialized {@link StarGraph} from a {@link Map} generated by
-     * {@link StarGraphGraphSONSerializer}.
-     */
-    public static StarGraph readStarGraphVertex(final Map<String, Object> vertexData) throws IOException {
-        final StarGraph starGraph = StarGraph.open();
-        starGraph.addVertex(T.id, vertexData.get(GraphSONTokens.ID), T.label, vertexData.get(GraphSONTokens.LABEL));
-        if (vertexData.containsKey(GraphSONTokens.PROPERTIES)) {
-            final Map<String, List<Map<String, Object>>> properties = (Map<String, List<Map<String, Object>>>) vertexData.get(GraphSONTokens.PROPERTIES);
-            for (Map.Entry<String, List<Map<String, Object>>> property : properties.entrySet()) {
-                for (Map<String, Object> p : property.getValue()) {
-                    final StarGraph.StarVertexProperty vp = (StarGraph.StarVertexProperty) starGraph.getStarVertex().property(VertexProperty.Cardinality.list, property.getKey(), p.get(GraphSONTokens.VALUE), T.id, p.get(GraphSONTokens.ID));
-                    if (p.containsKey(GraphSONTokens.PROPERTIES)) {
-                        final Map<String, Object> edgePropertyData = (Map<String, Object>) p.get(GraphSONTokens.PROPERTIES);
-                        for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
-                            vp.property(epd.getKey(), epd.getValue());
-                        }
-                    }
-                }
-            }
-        }
-
-        return starGraph;
-    }
-
-    private static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
-        Collections.sort(listToSort, comparator);
-        return listToSort;
-    }
-
-    public static class DirectionalStarGraph {
-        private final Direction direction;
-        private final StarGraph starGraphToSerialize;
-
-        public DirectionalStarGraph(final StarGraph starGraphToSerialize, final Direction direction) {
-            this.direction = direction;
-            this.starGraphToSerialize = starGraphToSerialize;
-        }
-
-        public Direction getDirection() {
-            return direction;
-        }
-
-        public StarGraph getStarGraphToSerialize() {
-            return starGraphToSerialize;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
new file mode 100644
index 0000000..bbd5591
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
@@ -0,0 +1,167 @@
+/*
+ * 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.*;
+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.*;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StarGraphGraphSONSerializerV1d0 extends StdSerializer<DirectionalStarGraph> {
+    private final boolean normalize;
+    public StarGraphGraphSONSerializerV1d0(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();
+        jsonGenerator.writeStartObject();
+        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+        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.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+            if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+            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.writeArrayFieldStart(k);
+                if (typeSerializer != null) {
+                    jsonGenerator.writeString(ArrayList.class.getName());
+                    jsonGenerator.writeStartArray();
+                }
+
+                final List<VertexProperty> vertexProperties = normalize ? sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
+                for (final VertexProperty property : vertexProperties) {
+                    jsonGenerator.writeStartObject();
+                    if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+                    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.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+                        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+                        while (metaProperties.hasNext()) {
+                            final Property<Object> meta = metaProperties.next();
+                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+                        }
+                        jsonGenerator.writeEndObject();
+                    }
+                    jsonGenerator.writeEndObject();
+                }
+                jsonGenerator.writeEndArray();
+                if (typeSerializer != null) jsonGenerator.writeEndArray();
+            }
+            jsonGenerator.writeEndObject();
+        }
+        // For some reason, this wasn't closed.
+        jsonGenerator.writeEndObject();
+    }
+
+    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.writeObjectFieldStart(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
+            if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+            final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
+            for (final String k : keys) {
+                final List<Edge> edges = starEdges.get(k);
+                jsonGenerator.writeArrayFieldStart(k);
+                if (typeSerializer != null) {
+                    jsonGenerator.writeString(ArrayList.class.getName());
+                    jsonGenerator.writeStartArray();
+                }
+
+                final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
+                for (final Edge edge : edgesToWrite) {
+                    jsonGenerator.writeStartObject();
+                    if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+                    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.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+                        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+                        while (edgeProperties.hasNext()) {
+                            final Property<Object> meta = edgeProperties.next();
+                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+                        }
+                        jsonGenerator.writeEndObject();
+                    }
+                    jsonGenerator.writeEndObject();
+                }
+                jsonGenerator.writeEndArray();
+                if (typeSerializer != null) jsonGenerator.writeEndArray();
+            }
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
+        Collections.sort(listToSort, comparator);
+        return listToSort;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
new file mode 100644
index 0000000..2e0bc53
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
@@ -0,0 +1,158 @@
+/*
+ * 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.*;
+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.Attachable;
+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.*;
+import java.util.function.Function;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StarGraphGraphSONSerializerV2d0 extends StdSerializer<DirectionalStarGraph> {
+    private final boolean normalize;
+    public StarGraphGraphSONSerializerV2d0(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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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
new file mode 100644
index 0000000..6b5f7e9
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
@@ -0,0 +1,292 @@
+/*
+ * 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.databind.ObjectMapper;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.time.*;
+import java.util.*;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests automatic typed serialization/deserialization for GraphSON 2.0.
+ */
+public class GraphSONMapperV2d0PartialEmbeddedTypeTest {
+
+    private final ObjectMapper mapper = GraphSONMapper.build()
+            .version(GraphSONVersion.V2_0)
+            .typeInfo(GraphSONMapper.TypeInfo.PARTIAL_TYPES)
+            .create()
+            .createMapper();
+
+    @Test
+    public void shouldHandleDuration()throws Exception  {
+        final Duration o = Duration.ZERO;
+        assertEquals(o, serializeDeserialize(o, Duration.class));
+    }
+    @Test
+    public void shouldHandleInstant()throws Exception  {
+        final Instant o = Instant.ofEpochMilli(System.currentTimeMillis());
+        assertEquals(o, serializeDeserialize(o, Instant.class));
+    }
+
+    @Test
+    public void shouldHandleLocalDate()throws Exception  {
+        final LocalDate o = LocalDate.now();
+        assertEquals(o, serializeDeserialize(o, LocalDate.class));
+    }
+
+    @Test
+    public void shouldHandleLocalDateTime()throws Exception  {
+        final LocalDateTime o = LocalDateTime.now();
+        assertEquals(o, serializeDeserialize(o, LocalDateTime.class));
+    }
+
+    @Test
+    public void shouldHandleLocalTime()throws Exception  {
+        final LocalTime o = LocalTime.now();
+        assertEquals(o, serializeDeserialize(o, LocalTime.class));
+    }
+
+    @Test
+    public void shouldHandleMonthDay()throws Exception  {
+        final MonthDay o = MonthDay.now();
+        assertEquals(o, serializeDeserialize(o, MonthDay.class));
+    }
+
+    @Test
+    public void shouldHandleOffsetDateTime()throws Exception  {
+        final OffsetDateTime o = OffsetDateTime.now();
+        assertEquals(o, serializeDeserialize(o, OffsetDateTime.class));
+    }
+
+    @Test
+    public void shouldHandleOffsetTime()throws Exception  {
+        final OffsetTime o = OffsetTime.now();
+        assertEquals(o, serializeDeserialize(o, OffsetTime.class));
+    }
+
+    @Test
+    public void shouldHandlePeriod()throws Exception  {
+        final Period o = Period.ofDays(3);
+        assertEquals(o, serializeDeserialize(o, Period.class));
+    }
+
+    @Test
+    public void shouldHandleYear()throws Exception  {
+        final Year o = Year.now();
+        assertEquals(o, serializeDeserialize(o, Year.class));
+    }
+
+    @Test
+    public void shouldHandleYearMonth()throws Exception  {
+        final YearMonth o = YearMonth.now();
+        assertEquals(o, serializeDeserialize(o, YearMonth.class));
+    }
+
+    @Test
+    public void shouldHandleZonedDateTime()throws Exception  {
+        final ZonedDateTime o = ZonedDateTime.now();
+        assertEquals(o, serializeDeserialize(o, ZonedDateTime.class));
+    }
+
+    @Test
+    public void shouldHandleZonedOffset()throws Exception  {
+        final ZoneOffset o  = ZonedDateTime.now().getOffset();
+        assertEquals(o, serializeDeserialize(o, ZoneOffset.class));
+    }
+
+    @Test
+    public void shouldHandleDurationAuto() throws Exception {
+        final Duration o = Duration.ZERO;
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleInstantAuto() throws Exception {
+        final Instant o = Instant.ofEpochMilli(System.currentTimeMillis());
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleLocalDateAuto() throws Exception {
+        final LocalDate o = LocalDate.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleLocalDateTimeAuto() throws Exception {
+        final LocalDateTime o = LocalDateTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleLocalTimeAuto() throws Exception {
+        final LocalTime o = LocalTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleMonthDayAuto() throws Exception {
+        final MonthDay o = MonthDay.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleOffsetDateTimeAuto() throws Exception {
+        final OffsetDateTime o = OffsetDateTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleOffsetTimeAuto() throws Exception {
+        final OffsetTime o = OffsetTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandlePeriodAuto() throws Exception {
+        final Period o = Period.ofDays(3);
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleYearAuto() throws Exception {
+        final Year o = Year.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleYearMonthAuto() throws Exception {
+        final YearMonth o = YearMonth.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleZonedDateTimeAuto() throws Exception {
+        final ZonedDateTime o = ZonedDateTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleZonedOffsetAuto() throws Exception {
+        final ZoneOffset o = ZonedDateTime.now().getOffset();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly() throws Exception {
+        UUID uuid = UUID.randomUUID();
+        List myList = new ArrayList<>();
+
+        List myList2 = new ArrayList<>();
+        myList2.add(UUID.randomUUID());
+        myList2.add(33L);
+        myList2.add(84);
+        Map map2 = new HashMap<>();
+        map2.put("eheh", UUID.randomUUID());
+        map2.put("normal", "normal");
+        myList2.add(map2);
+
+        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(myList));
+    }
+
+    @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. Cannot deserialize the value with the detected type contained in the JSON (\"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(funObject, FunObject.class).toString());
+        assertEquals(funObject.getClass(), serializeDeserialize(funObject, FunObject.class).getClass());
+    }
+
+
+    // 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;
+        }
+    }
+
+    public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception {
+        try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+            mapper.writeValue(stream, o);
+
+            try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+                return mapper.readValue(inputStream, clazz);
+            }
+        }
+    }
+
+    public <T> T serializeDeserializeAuto(final Object o) throws Exception {
+        try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+            mapper.writeValue(stream, o);
+
+            try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+                // Object.class is the wildcard that triggers the auto discovery.
+                return (T)mapper.readValue(inputStream, Object.class);
+            }
+        }
+    }
+
+}