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 2015/04/29 21:41:16 UTC

incubator-tinkerpop git commit: Add GraphReader/Writer functions for Property and VertexProperty.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master 2c0084902 -> ef0b93fcc


Add GraphReader/Writer functions for Property and VertexProperty.


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

Branch: refs/heads/master
Commit: ef0b93fcc35db9b8ccbadda11c2dc7d681db2fde
Parents: 2c00849
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Apr 29 15:40:55 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Apr 29 15:40:55 2015 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../gremlin/structure/io/GraphReader.java       |  31 ++-
 .../gremlin/structure/io/GraphWriter.java       |  18 ++
 .../structure/io/graphml/GraphMLReader.java     |  74 ++++---
 .../structure/io/graphml/GraphMLWriter.java     |  12 ++
 .../structure/io/graphson/GraphSONReader.java   |  23 +++
 .../io/graphson/GraphSONSerializers.java        |   3 +-
 .../structure/io/graphson/GraphSONTokens.java   |   1 +
 .../structure/io/graphson/GraphSONWriter.java   |  24 +++
 .../io/graphson/LegacyGraphSONReader.java       |  13 ++
 .../gremlin/structure/io/gryo/GryoReader.java   |  74 ++++---
 .../gremlin/structure/io/gryo/GryoWriter.java   |  18 ++
 .../util/detached/DetachedProperty.java         |   6 +
 .../util/detached/DetachedVertexProperty.java   |  15 ++
 .../tinkerpop/gremlin/structure/IoTest.java     | 191 ++++++++++++++++---
 .../gremlin/structure/SerializationTest.java    |   1 +
 16 files changed, 424 insertions(+), 81 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 49d1dfc..3fc133a 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -37,6 +37,7 @@ TinkerPop 3.0.0.M9 (NOT OFFICIALLY RELEASED YET)
 * Altered `GraphWriter.writeVertices()` method to take an `Iterator` of vertices rather than a `Traversal`.
 * GraphSON format for output from `GraphWriter.writeVertex`, `GraphWriter.writeVertices`, and `GraphWriter.writeGraph` have all changed now that they use `StarGraph` serialization.
 * Gryo format for output from `GraphWriter.writeVertex`, `GraphWriter.writeVertices`, and `GraphWriter.writeGraph` have all changed now that they use `StarGraph` serialization.
+* Added read and write methods to `GraphReader` and `GraphWriter` for `Property` and `VertexProperty`.
 * Reduced object creation in GraphSON during serialization.
 * Moved `T` tokens to the `structure/` package as its more general than `process/`.
 * `Attachable.attach()` now takes a `Method` to determine whether to attach via `GET`, `CREATE`, or `GET_OR_CREATE`.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java
index 3a57e58..ebcdf2f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java
@@ -21,8 +21,11 @@ package org.apache.tinkerpop.gremlin.structure.io;
 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.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
+import org.apache.tinkerpop.gremlin.structure.util.Host;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -111,7 +114,7 @@ public interface GraphReader {
      * transaction context with respect to this method (i.e. implementations should not commit the transaction for
      * the user).
      *
-     * @param inputStream a stream containing a single vertex as defined by the accompanying {@link GraphWriter}
+     * @param inputStream a stream containing at least one vertex as defined by the accompanying {@link GraphWriter}
      * @param edgeAttachMethod    a function that creates an edge from the stream where the first argument is the edge
      *                    identifier, the second argument is the out vertex id, the third is the in vertex id,
      *                    the fourth is the label, and the fifth is the list of properties as key/value pairs.
@@ -119,6 +122,32 @@ public interface GraphReader {
     public Edge readEdge(final InputStream inputStream, final Function<Attachable<Edge>, Edge> edgeAttachMethod) throws IOException;
 
     /**
+     * Reads a single vertex property from an {@link InputStream}.  It is expected that the user will manager their own
+     * transaction context with respect to this method (i.e. implementations should not commit the transaction for
+     * the user).
+     *
+     * @param inputStream a stream containing at least one vertex property as written by the accompanying
+     *                    {@link GraphWriter#writeVertexProperty(OutputStream, VertexProperty)} method
+     * @param vertexPropertyAttachMethod a function that creates re-attaches a vertex property to a {@link Host} object
+     * @return the value returned by the attach method
+     */
+    public VertexProperty readVertexProperty(final InputStream inputStream,
+                                             final Function<Attachable<VertexProperty>, VertexProperty> vertexPropertyAttachMethod) throws IOException;
+
+    /**
+     * Reads a single property from an {@link InputStream}.  It is expected that the user will manager their own
+     * transaction context with respect to this method (i.e. implementations should not commit the transaction for
+     * the user).
+     *
+     * @param inputStream a stream containing at least one property as written by the accompanying
+     *                    {@link GraphWriter#writeProperty(OutputStream, Property)} method
+     * @param propertyAttachMethod a function that creates re-attaches a property to a {@link Host} object
+     * @return the value returned by the attach method
+     */
+    public Property readProperty(final InputStream inputStream,
+                                 final Function<Attachable<Property>, Property> propertyAttachMethod) throws IOException;
+
+    /**
      * Reads an arbitrary object using the standard serializers.
      *
      * @param inputStream  a stream containing an object.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java
index cee6968..67e0c25 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java
@@ -22,7 +22,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 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.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -109,6 +111,22 @@ public interface GraphWriter {
     public void writeEdge(final OutputStream outputStream, final Edge e) throws IOException;
 
     /**
+     * Write a vertex property to a stream.
+     *
+     * @param outputStream The stream to write to.
+     * @param vp The vertex property to write.
+     */
+    public void writeVertexProperty(final OutputStream outputStream, final VertexProperty vp) throws IOException;
+
+    /**
+     * Write a property to a stream.
+     *
+     * @param outputStream The stream to write to.
+     * @param p The property to write.
+     */
+    public void writeProperty(final OutputStream outputStream, final Property p) throws IOException;
+
+    /**
      * Writes an arbitrary object to the stream.
      *
      * @param outputStream The stream to write to

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
index 88ac149..47a26a8 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
@@ -19,10 +19,12 @@
 package org.apache.tinkerpop.gremlin.structure.io.graphml;
 
 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.io.GraphReader;
 import org.apache.tinkerpop.gremlin.structure.io.Io;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
@@ -69,36 +71,6 @@ public class GraphMLReader implements GraphReader {
     }
 
     @Override
-    public Iterator<Vertex> readVertices(final InputStream inputStream,
-                                         final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
-                                         final Function<Attachable<Edge>, Edge> edgeAttachMethod,
-                                         final Direction attachEdgesOfThisDirection) throws IOException {
-        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
-    }
-
-    @Override
-    public Edge readEdge(final InputStream inputStream, final Function<Attachable<Edge>, Edge> edgeAttachMethod) throws IOException {
-        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
-    }
-
-    @Override
-    public Vertex readVertex(final InputStream inputStream, final Function<Attachable<Vertex>, Vertex> vertexAttachMethod) throws IOException {
-        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
-    }
-
-    @Override
-    public Vertex readVertex(final InputStream inputStream, final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
-                             final Function<Attachable<Edge>, Edge> edgeAttachMethod,
-                             final Direction attachEdgesOfThisDirection) throws IOException {
-        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
-    }
-
-    @Override
-    public <C> C readObject(final InputStream inputStream, final Class<? extends C> clazz) throws IOException {
-        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
-    }
-
-    @Override
     public void readGraph(final InputStream graphInputStream, final Graph graphToWriteTo) throws IOException {
         final Map<Object,Vertex> cache = new HashMap<>();
         final AtomicLong counter = new AtomicLong(0);
@@ -229,6 +201,48 @@ public class GraphMLReader implements GraphReader {
         }
     }
 
+    @Override
+    public Iterator<Vertex> readVertices(final InputStream inputStream,
+                                         final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
+                                         final Function<Attachable<Edge>, Edge> edgeAttachMethod,
+                                         final Direction attachEdgesOfThisDirection) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
+    public Vertex readVertex(final InputStream inputStream, final Function<Attachable<Vertex>, Vertex> vertexAttachMethod) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
+    public Vertex readVertex(final InputStream inputStream, final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
+                             final Function<Attachable<Edge>, Edge> edgeAttachMethod,
+                             final Direction attachEdgesOfThisDirection) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
+    public Edge readEdge(final InputStream inputStream, final Function<Attachable<Edge>, Edge> edgeAttachMethod) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
+    public VertexProperty readVertexProperty(final InputStream inputStream,
+                                             final Function<Attachable<VertexProperty>, VertexProperty> vertexPropertyAttachMethod) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
+    public Property readProperty(final InputStream inputStream,
+                                 final Function<Attachable<Property>, Property> propertyAttachMethod) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
+    public <C> C readObject(final InputStream inputStream, final Class<? extends C> clazz) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
     private static Vertex findOrCreate(final Object id, final Graph graphToWriteTo, final boolean supportsIds,
                                        final Map<Object,Vertex> cache, final Object... args) {
         if (cache.containsKey(id)) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java
index 7b28f64..b000d1e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java
@@ -22,7 +22,9 @@ 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.io.GraphWriter;
 import org.apache.tinkerpop.gremlin.structure.io.Io;
 import org.apache.tinkerpop.gremlin.structure.util.Comparators;
@@ -101,6 +103,16 @@ public class GraphMLWriter implements GraphWriter {
     }
 
     @Override
+    public void writeVertexProperty(final OutputStream outputStream, final VertexProperty vp) throws IOException {
+        throw Io.Exceptions.writerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
+    public void writeProperty(final OutputStream outputStream, final Property p) throws IOException {
+        throw Io.Exceptions.writerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
     public void writeObject(final OutputStream outputStream, final Object object) throws IOException {
         throw Io.Exceptions.writerFormatIsForFullGraphSerializationOnly(this.getClass());
     }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/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 7c0ebf1..7e767d7 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
@@ -23,11 +23,15 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 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.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.io.GraphReader;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
 import org.apache.tinkerpop.gremlin.structure.util.batch.BatchGraph;
 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.util.function.FunctionUtils;
@@ -152,6 +156,25 @@ public class GraphSONReader implements GraphReader {
         return edgeAttachMethod.apply(edge);
     }
 
+    @Override
+    public VertexProperty readVertexProperty(final InputStream inputStream,
+                                             final Function<Attachable<VertexProperty>, VertexProperty> vertexPropertyAttachMethod) throws IOException {
+        final Map<String, Object> vpData = mapper.readValue(inputStream, mapTypeReference);
+        final Map<String, Object> metaProperties = (Map<String, Object>) vpData.get(GraphSONTokens.PROPERTIES);
+        final DetachedVertexProperty vp = new DetachedVertexProperty(vpData.get(GraphSONTokens.ID),
+                vpData.get(GraphSONTokens.LABEL).toString(),
+                vpData.get(GraphSONTokens.VALUE), metaProperties);
+        return vertexPropertyAttachMethod.apply(vp);
+    }
+
+    @Override
+    public Property readProperty(final InputStream inputStream,
+                                 final Function<Attachable<Property>, Property> propertyAttachMethod) throws IOException {
+        final Map<String, Object> propertyData = mapper.readValue(inputStream, mapTypeReference);
+        final DetachedProperty p = new DetachedProperty(propertyData.get(GraphSONTokens.KEY).toString(), propertyData.get(GraphSONTokens.VALUE));
+        return propertyAttachMethod.apply(p);
+    }
+
     /**
      * {@inheritDoc}
      */

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java
index 126e17f..ed5a840 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java
@@ -72,7 +72,6 @@ class GraphSONSerializers {
                                       final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
             serializerVertexProperty(property, jsonGenerator, serializerProvider, typeSerializer, normalize);
         }
-
     }
 
     static class PropertyJacksonSerializer extends StdSerializer<Property> {
@@ -96,10 +95,10 @@ class GraphSONSerializers {
                                 final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
             jsonGenerator.writeStartObject();
             if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+            serializerProvider.defaultSerializeField(GraphSONTokens.KEY, property.key(), jsonGenerator);
             serializerProvider.defaultSerializeField(GraphSONTokens.VALUE, property.value(), jsonGenerator);
             jsonGenerator.writeEndObject();
         }
-
     }
 
     static class EdgeJacksonSerializer extends StdSerializer<Edge> {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
index 297db19..5fabb81 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java
@@ -27,6 +27,7 @@ public final class GraphSONTokens {
     public static final String TYPE = "type";
     public static final String VALUE = "value";
     public static final String PROPERTIES = "properties";
+    public static final String KEY = "key";
     public static final String EDGE = "edge";
     public static final String VERTEX = "vertex";
     public static final String IN = "inV";

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/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 5f9b879..d1c2430 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
@@ -22,7 +22,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 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.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.io.GraphWriter;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializer;
@@ -131,6 +133,28 @@ public class GraphSONWriter implements GraphWriter {
     }
 
     /**
+     * Write a {@link VertexProperty} object to the stream.
+     *
+     * @param outputStream The stream to write to.
+     * @param vp The vertex property to write.
+     */
+    @Override
+    public void writeVertexProperty(final OutputStream outputStream, final VertexProperty vp) throws IOException {
+        mapper.writeValue(outputStream, vp);
+    }
+
+    /**
+     * Write a {@link Property} object to the stream.
+     *
+     * @param outputStream The stream to write to.
+     * @param p The property to write.
+     */
+    @Override
+    public void writeProperty(final OutputStream outputStream, final Property p) throws IOException {
+        mapper.writeValue(outputStream, p);
+    }
+
+    /**
      * Writes an arbitrary object to the stream.  Note that Gremlin Server uses this method when serializing output,
      * thus the format of the GraphSON for a {@link Vertex} will be somewhat different from the format supplied
      * when using {@link #writeVertex(OutputStream, Vertex, Direction)}. For example, edges will never be included.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/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 852455f..3b37bed 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
@@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
 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;
@@ -146,6 +147,18 @@ public class LegacyGraphSONReader implements GraphReader {
     }
 
     @Override
+    public VertexProperty readVertexProperty(final InputStream inputStream,
+                                             final Function<Attachable<VertexProperty>, VertexProperty> vertexPropertyAttachMethod) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
+    public Property readProperty(final InputStream inputStream,
+                                 final Function<Attachable<Property>, Property> propertyAttachMethod) throws IOException {
+        throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
+    }
+
+    @Override
     public <C> C readObject(final InputStream inputStream, final Class<? extends C> clazz) throws IOException {
         throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
     }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
index cf19c62..5ca61bf 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
@@ -18,7 +18,11 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.gryo;
 
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
+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.util.iterator.IteratorUtils;
 import org.apache.tinkerpop.shaded.kryo.Kryo;
@@ -62,6 +66,28 @@ public class GryoReader implements GraphReader {
     }
 
     @Override
+    public void readGraph(final InputStream inputStream, final Graph graphToWriteTo) throws IOException {
+        // dual pass - create all vertices and store to cache the ids.  then create edges.  as long as we don't
+        // have vertex labels in the output we can't do this single pass
+        final Map<StarGraph.StarVertex,Vertex> cache = new HashMap<>();
+        final AtomicLong counter = new AtomicLong(0);
+        final boolean supportsTx = graphToWriteTo.features().graph().supportsTransactions();
+        IteratorUtils.iterate(new VertexInputIterator(new Input(inputStream), attachable -> {
+            final Vertex v = cache.put((StarGraph.StarVertex) attachable.get(), attachable.attach(Attachable.Method.create(graphToWriteTo)));
+            if (supportsTx && counter.incrementAndGet() % batchSize == 0)
+                graphToWriteTo.tx().commit();
+            return v;
+        }, null, null));
+        cache.entrySet().forEach(kv -> kv.getKey().edges(Direction.OUT).forEachRemaining(e -> {
+            ((StarGraph.StarEdge) e).attach(Attachable.Method.create(kv.getValue()));
+            if (supportsTx && counter.incrementAndGet() % batchSize == 0)
+                graphToWriteTo.tx().commit();
+        }));
+
+        if (supportsTx) graphToWriteTo.tx().commit();
+    }
+
+    @Override
     public Iterator<Vertex> readVertices(final InputStream inputStream,
                                          final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
                                          final Function<Attachable<Edge>, Edge> edgeAttachMethod,
@@ -70,14 +96,6 @@ public class GryoReader implements GraphReader {
     }
 
     @Override
-    public Edge readEdge(final InputStream inputStream, final Function<Attachable<Edge>, Edge> edgeAttachMethod) throws IOException {
-        final Input input = new Input(inputStream);
-        readHeader(input);
-        final Attachable<Edge> attachable = kryo.readObject(input, DetachedEdge.class);
-        return edgeAttachMethod.apply(attachable);
-    }
-
-    @Override
     public Vertex readVertex(final InputStream inputStream, final Function<Attachable<Vertex>, Vertex> vertexAttachMethod) throws IOException {
         return readVertex(inputStream, vertexAttachMethod, null, null);
     }
@@ -92,25 +110,29 @@ public class GryoReader implements GraphReader {
     }
 
     @Override
-    public void readGraph(final InputStream inputStream, final Graph graphToWriteTo) throws IOException {
-        // dual pass - create all vertices and store to cache the ids.  then create edges.  as long as we don't
-        // have vertex labels in the output we can't do this single pass
-        final Map<StarGraph.StarVertex,Vertex> cache = new HashMap<>();
-        final AtomicLong counter = new AtomicLong(0);
-        final boolean supportsTx = graphToWriteTo.features().graph().supportsTransactions();
-        IteratorUtils.iterate(new VertexInputIterator(new Input(inputStream), attachable -> {
-            final Vertex v = cache.put((StarGraph.StarVertex) attachable.get(), attachable.attach(Attachable.Method.create(graphToWriteTo)));
-            if (supportsTx && counter.incrementAndGet() % batchSize == 0)
-                graphToWriteTo.tx().commit();
-            return v;
-        }, null, null));
-        cache.entrySet().forEach(kv -> kv.getKey().edges(Direction.OUT).forEachRemaining(e -> {
-            ((StarGraph.StarEdge) e).attach(Attachable.Method.create(kv.getValue()));
-            if (supportsTx && counter.incrementAndGet() % batchSize == 0)
-                graphToWriteTo.tx().commit();
-        }));
+    public Edge readEdge(final InputStream inputStream, final Function<Attachable<Edge>, Edge> edgeAttachMethod) throws IOException {
+        final Input input = new Input(inputStream);
+        readHeader(input);
+        final Attachable<Edge> attachable = kryo.readObject(input, DetachedEdge.class);
+        return edgeAttachMethod.apply(attachable);
+    }
 
-        if (supportsTx) graphToWriteTo.tx().commit();
+    @Override
+    public VertexProperty readVertexProperty (final InputStream inputStream,
+                                              final Function<Attachable<VertexProperty>, VertexProperty> vertexPropertyAttachMethod) throws IOException {
+        final Input input = new Input(inputStream);
+        readHeader(input);
+        final Attachable<VertexProperty> attachable = kryo.readObject(input, DetachedVertexProperty.class);
+        return vertexPropertyAttachMethod.apply(attachable);
+    }
+
+    @Override
+    public Property readProperty(final InputStream inputStream,
+                                 final Function<Attachable<Property>, Property> propertyAttachMethod) throws IOException {
+        final Input input = new Input(inputStream);
+        readHeader(input);
+        final Attachable<Property> attachable = kryo.readObject(input, DetachedProperty.class);
+        return propertyAttachMethod.apply(attachable);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java
index 3d6714a..af7848b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java
@@ -21,7 +21,9 @@ package org.apache.tinkerpop.gremlin.structure.io.gryo;
 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.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.io.GraphWriter;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
@@ -91,6 +93,22 @@ public class GryoWriter implements GraphWriter {
     }
 
     @Override
+    public void writeVertexProperty(final OutputStream outputStream, final VertexProperty vp) throws IOException {
+        final Output output = new Output(outputStream);
+        writeHeader(output);
+        kryo.writeObject(output, DetachedFactory.detach(vp, true));
+        output.flush();
+    }
+
+    @Override
+    public void writeProperty(final OutputStream outputStream, final Property p) throws IOException {
+        final Output output = new Output(outputStream);
+        writeHeader(output);
+        kryo.writeObject(output, DetachedFactory.detach(p, true));
+        output.flush();
+    }
+
+    @Override
     public void writeObject(final OutputStream outputStream, final Object object) {
         final Output output = new Output(outputStream);
         this.kryo.writeClassAndObject(output, object);

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedProperty.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedProperty.java
index 6da0e4a..d7f5e28 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedProperty.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedProperty.java
@@ -47,6 +47,12 @@ public class DetachedProperty<V> implements Property<V>, Serializable, Attachabl
         this.element = DetachedFactory.detach(property.element(), false);
     }
 
+    public DetachedProperty(final String key, final V value) {
+        this.key = key;
+        this.value = value;
+        this.element = null;
+    }
+
     public DetachedProperty(final String key, final V value, final Element element) {
         this.key = key;
         this.value = value;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
index f76cfd8..069c14c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
@@ -23,6 +23,7 @@ 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.ElementHelper;
+import org.apache.tinkerpop.gremlin.structure.util.Host;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
 import java.util.Collections;
@@ -72,6 +73,20 @@ public class DetachedVertexProperty<V> extends DetachedElement<VertexProperty<V>
         }
     }
 
+    /**
+     * This constructor is used by GraphSON when deserializing and the {@link Host} is not known.
+     */
+    public DetachedVertexProperty(final Object id, final String label, final V value,
+                                  final Map<String, Object> properties) {
+        super(id, label);
+        this.value = value;
+
+        if (properties != null && !properties.isEmpty()) {
+            this.properties = new HashMap<>();
+            properties.entrySet().iterator().forEachRemaining(entry -> this.properties.put(entry.getKey(), Collections.singletonList(new DetachedProperty<>(entry.getKey(), entry.getValue(), this))));
+        }
+    }
+
     @Override
     public boolean isPresent() {
         return true;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/IoTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/IoTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/IoTest.java
index 09ce719..b555551 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/IoTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/IoTest.java
@@ -80,6 +80,7 @@ import java.io.StringWriter;
 import java.io.Writer;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -1396,7 +1397,7 @@ public class IoTest extends AbstractGremlinTest {
             try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
                 reader.readVertex(bais, attachable -> {
                             final Vertex detachedVertex = attachable.get();
-                            TestHelper.validateVertexEquality(v1, detachedVertex,true);
+                            TestHelper.validateVertexEquality(v1, detachedVertex, true);
                             calledVertex.set(true);
                             return detachedVertex;
                         },
@@ -1434,26 +1435,26 @@ public class IoTest extends AbstractGremlinTest {
             final GraphSONReader reader = graph.io(graphson).reader().create();
             try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
                 reader.readVertex(bais, attachable -> {
-                            final Vertex detachedVertex = attachable.get();
-                            assertEquals(v1.id(), graph.vertices(detachedVertex.id().toString()).next().id());
-                            assertEquals(v1.label(), detachedVertex.label());
-                            assertEquals(1, IteratorUtils.count(detachedVertex.properties()));
-                            assertEquals("marko", detachedVertex.value("name"));
-                            calledVertex.set(true);
-                            return null;
-                        },attachable -> {
-                            final Edge detachedEdge = attachable.get();
-                            assertEquals(e.id(), graph.edges(detachedEdge.id().toString()).next().id());
-                            assertEquals(v1.id(), graph.vertices(detachedEdge.outVertex().id().toString()).next().id());
-                            assertEquals(v2.id(), graph.vertices(detachedEdge.inVertex().id().toString()).next().id());
-                            assertEquals(v1.label(), detachedEdge.outVertex().label());
-                            assertEquals(e.label(), detachedEdge.label());
-                            assertEquals(1, IteratorUtils.count(detachedEdge.properties()));
-                            assertEquals(0.5d, detachedEdge.value("weight"), 0.000001d);                      // lossy
+                    final Vertex detachedVertex = attachable.get();
+                    assertEquals(v1.id(), graph.vertices(detachedVertex.id().toString()).next().id());
+                    assertEquals(v1.label(), detachedVertex.label());
+                    assertEquals(1, IteratorUtils.count(detachedVertex.properties()));
+                    assertEquals("marko", detachedVertex.value("name"));
+                    calledVertex.set(true);
+                    return null;
+                }, attachable -> {
+                    final Edge detachedEdge = attachable.get();
+                    assertEquals(e.id(), graph.edges(detachedEdge.id().toString()).next().id());
+                    assertEquals(v1.id(), graph.vertices(detachedEdge.outVertex().id().toString()).next().id());
+                    assertEquals(v2.id(), graph.vertices(detachedEdge.inVertex().id().toString()).next().id());
+                    assertEquals(v1.label(), detachedEdge.outVertex().label());
+                    assertEquals(e.label(), detachedEdge.label());
+                    assertEquals(1, IteratorUtils.count(detachedEdge.properties()));
+                    assertEquals(0.5d, detachedEdge.value("weight"), 0.000001d);                      // lossy
 
-                            calledEdge.set(true);
-                            return null;
-                        }, Direction.OUT);
+                    calledEdge.set(true);
+                    return null;
+                }, Direction.OUT);
             }
 
             assertTrue(calledVertex.get());
@@ -1483,7 +1484,7 @@ public class IoTest extends AbstractGremlinTest {
             try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
                 reader.readVertex(bais, attachable -> {
                     final Vertex detachedVertex = attachable.get();
-                    TestHelper.validateVertexEquality(v1, detachedVertex,true);
+                    TestHelper.validateVertexEquality(v1, detachedVertex, true);
                     calledVertex.set(true);
                     return detachedVertex;
                 }, attachable -> {
@@ -1572,7 +1573,7 @@ public class IoTest extends AbstractGremlinTest {
             try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
                 reader.readVertex(bais, attachable -> {
                             final Vertex detachedVertex = attachable.get();
-                            TestHelper.validateVertexEquality(v1, detachedVertex,true);
+                            TestHelper.validateVertexEquality(v1, detachedVertex, true);
                             calledVertex.set(true);
                             return detachedVertex;
                         },attachable -> {
@@ -1743,6 +1744,152 @@ public class IoTest extends AbstractGremlinTest {
         assertClassicGraph(graph, false, true);
     }
 
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    public void shouldReadWritePropertyGraphSON() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphSONWriter writer = graph.io(graphson).writer().create();
+            final Property p = g.E(convertToEdgeId("marko", "knows", "vadas")).next().property("weight");
+            writer.writeProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphSONReader reader = graph.io(graphson).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readProperty(bais, propertyAttachable -> {
+                    assertEquals(p.value(), propertyAttachable.get().value());
+                    assertEquals(p.key(), propertyAttachable.get().key());
+                    called.set(true);
+                    return propertyAttachable.get();
+                });
+            }
+
+            assertTrue(called.get());
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    public void shouldReadWriteVertexPropertyNoMetaPropertiesGraphSON() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphSONWriter writer = graph.io(graphson).writer().create();
+            final VertexProperty p = g.V(convertToVertexId("marko")).next().property("name");
+            writer.writeVertexProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphSONReader reader = graph.io(graphson).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertexProperty(bais, propertyAttachable -> {
+                    assertEquals(p.value(), propertyAttachable.get().value());
+                    assertEquals(p.key(), propertyAttachable.get().key());
+                    assertEquals(0, IteratorUtils.count(propertyAttachable.get().properties()));
+                    called.set(true);
+                    return propertyAttachable.get();
+                });
+            }
+
+            assertTrue(called.get());
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CREW)
+    public void shouldReadWriteVertexPropertyWithMetaPropertiesGraphSON() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphSONWriter writer = graph.io(graphson).writer().create();
+            final VertexProperty p = g.V(convertToVertexId("marko")).next().properties("location").next();
+            writer.writeVertexProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphSONReader reader = graph.io(graphson).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertexProperty(bais, propertyAttachable -> {
+                    assertEquals(p.value(), propertyAttachable.get().value());
+                    assertEquals(p.key(), propertyAttachable.get().key());
+                    assertEquals(IteratorUtils.count(p.properties()), IteratorUtils.count(propertyAttachable.get().properties()));
+                    assertEquals(p.property("startTime").value(), ((Property) propertyAttachable.get().properties("startTime").next()).value());
+                    assertEquals(p.property("endTime").value(), ((Property) propertyAttachable.get().properties("endTime").next()).value());
+                    called.set(true);
+                    return propertyAttachable.get();
+                });
+            }
+
+            assertTrue(called.get());
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    public void shouldReadWritePropertyGryo() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GryoWriter writer = graph.io(gryo).writer().create();
+            final Property p = g.E(convertToEdgeId("marko", "knows", "vadas")).next().property("weight");
+            writer.writeProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GryoReader reader = graph.io(gryo).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readProperty(bais, propertyAttachable -> {
+                    assertEquals(p.value(), propertyAttachable.get().value());
+                    assertEquals(p.key(), propertyAttachable.get().key());
+                    called.set(true);
+                    return propertyAttachable.get();
+                });
+            }
+
+            assertTrue(called.get());
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    public void shouldReadWriteVertexPropertyNoMetaPropertiesGryo() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GryoWriter writer = graph.io(gryo).writer().create();
+            final VertexProperty p = g.V(convertToVertexId("marko")).next().property("name");
+            writer.writeVertexProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GryoReader reader = graph.io(gryo).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertexProperty(bais, propertyAttachable -> {
+                    assertEquals(p.value(), propertyAttachable.get().value());
+                    assertEquals(p.key(), propertyAttachable.get().key());
+                    assertEquals(0, IteratorUtils.count(propertyAttachable.get().properties()));
+                    called.set(true);
+                    return propertyAttachable.get();
+                });
+            }
+
+            assertTrue(called.get());
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CREW)
+    public void shouldReadWriteVertexPropertyWithMetaPropertiesGryo() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GryoWriter writer = graph.io(gryo).writer().create();
+            final VertexProperty p = g.V(convertToVertexId("marko")).next().properties("location").next();
+            writer.writeVertexProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GryoReader reader = graph.io(gryo).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertexProperty(bais, propertyAttachable -> {
+                    assertEquals(p.value(), propertyAttachable.get().value());
+                    assertEquals(p.key(), propertyAttachable.get().key());
+                    assertEquals(IteratorUtils.count(p.properties()), IteratorUtils.count(propertyAttachable.get().properties()));
+                    assertEquals(p.property("startTime").value(), ((Property) propertyAttachable.get().properties("startTime").next()).value());
+                    assertEquals(p.property("endTime").value(), ((Property) propertyAttachable.get().properties("endTime").next()).value());
+                    called.set(true);
+                    return propertyAttachable.get();
+                });
+            }
+
+            assertTrue(called.get());
+        }
+    }
+
     public static void assertCrewGraph(final Graph g1, final boolean lossyForId) {
         assertEquals(new Long(6), g1.traversal().V().count().next());
         assertEquals(new Long(14), g1.traversal().E().count().next());

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ef0b93fc/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/SerializationTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/SerializationTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/SerializationTest.java
index bce7c9e..e335349 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/SerializationTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/SerializationTest.java
@@ -265,6 +265,7 @@ public class SerializationTest {
             final Map<String, Object> m = mapper.readValue(json, mapTypeReference);
 
             assertEquals(p.value(), m.get(GraphSONTokens.VALUE));
+            assertEquals(p.key(), m.get(GraphSONTokens.KEY));
         }
 
         @Test