You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2015/06/12 22:30:13 UTC

[1/8] incubator-tinkerpop git commit: commented out the high range assertions in ProfileTest as they tend to fail from time to time in some environments

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/xmatch-lost bf3fe790c -> d4847b816


commented out the high range assertions in ProfileTest as they tend to fail from time to time in some environments


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

Branch: refs/heads/xmatch-lost
Commit: 89d0ac57b13b31254d5c6db3f233b785a8f49bf1
Parents: 2507140
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Fri Jun 12 14:32:38 2015 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Fri Jun 12 14:32:38 2015 +0200

----------------------------------------------------------------------
 .../process/traversal/step/sideEffect/ProfileTest.java    | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/89d0ac57/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/ProfileTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/ProfileTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/ProfileTest.java
index 09d8767..017f9ea 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/ProfileTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/ProfileTest.java
@@ -189,15 +189,15 @@ public abstract class ProfileTest extends AbstractGremlinProcessTest {
         // 6 elements w/ a 10ms sleep each = 60ms with 10ms for other computation.
         assertTrue("Duration should be at least the length of the sleep (59ms): " + metrics.getDuration(TimeUnit.MILLISECONDS),
                 metrics.getDuration(TimeUnit.MILLISECONDS) >= 59);
-        assertTrue("Check that duration is within tolerant range: " + metrics.getDuration(TimeUnit.MILLISECONDS),
-                metrics.getDuration(TimeUnit.MILLISECONDS) < 130);
+        //assertTrue("Check that duration is within tolerant range: " + metrics.getDuration(TimeUnit.MILLISECONDS),
+        //        metrics.getDuration(TimeUnit.MILLISECONDS) < 130);
 
         // 6 elements w/ a 5ms sleep each = 30ms plus 20ms for other computation
         metrics = traversalMetrics.getMetrics(2);
         assertTrue("Duration should be at least the length of the sleep (29ms): " + metrics.getDuration(TimeUnit.MILLISECONDS),
                 metrics.getDuration(TimeUnit.MILLISECONDS) >= 29);
-        assertTrue("Check that duration is within tolerant range: " + metrics.getDuration(TimeUnit.MILLISECONDS),
-                metrics.getDuration(TimeUnit.MILLISECONDS) < 70);
+        //assertTrue("Check that duration is within tolerant range: " + metrics.getDuration(TimeUnit.MILLISECONDS),
+        //        metrics.getDuration(TimeUnit.MILLISECONDS) < 70);
 
         double totalPercentDuration = 0;
         for (Metrics m : traversalMetrics.getMetrics()) {
@@ -350,4 +350,4 @@ public abstract class ProfileTest extends AbstractGremlinProcessTest {
             return (Traversal) g.V().where(__.in("created").count().is(1l)).values("name").profile();
         }
     }
-}
\ No newline at end of file
+}


[7/8] incubator-tinkerpop git commit: Merge branch 'master' into xmatch

Posted by ok...@apache.org.
Merge branch 'master' into xmatch


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

Branch: refs/heads/xmatch-lost
Commit: a4f5267670a8a675b33f824311e0d77afa416f80
Parents: e0444ed be988ce
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Fri Jun 12 14:22:55 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Fri Jun 12 14:22:55 2015 -0600

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |    2 +
 .../tinkerpop/gremlin/server/GremlinServer.java |    8 +-
 .../traversal/step/sideEffect/ProfileTest.java  |   10 +-
 .../tinkerpop/gremlin/structure/GraphTest.java  |    3 +-
 .../structure/StructureStandardSuite.java       |   10 +
 .../tinkerpop/gremlin/structure/VertexTest.java |    3 +-
 .../gremlin/structure/io/IoCustomTest.java      |  143 ++
 .../gremlin/structure/io/IoEdgeTest.java        |  149 ++
 .../gremlin/structure/io/IoGraphTest.java       |  226 ++
 .../gremlin/structure/io/IoPropertyTest.java    |  150 ++
 .../tinkerpop/gremlin/structure/io/IoTest.java  | 2048 ++----------------
 .../gremlin/structure/io/IoVertexTest.java      |  485 +++++
 .../gremlin/structure/io/util/CustomId.java     |   92 +
 .../tinkergraph/TinkerGraphProvider.java        |   30 +-
 14 files changed, 1487 insertions(+), 1872 deletions(-)
----------------------------------------------------------------------



[6/8] incubator-tinkerpop git commit: GremlinServer now returns the ServerGremlinExecutor on start().

Posted by ok...@apache.org.
GremlinServer now returns the ServerGremlinExecutor on start().


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

Branch: refs/heads/xmatch-lost
Commit: be988ce8236a91593365f363af44e20c49b13adf
Parents: 0b3e50e
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 12 14:43:47 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jun 12 14:43:47 2015 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                                           | 1 +
 .../org/apache/tinkerpop/gremlin/server/GremlinServer.java   | 8 ++++----
 2 files changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/be988ce8/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 3e31faa..fa4a8a6 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ TinkerPop 3.0.0.GA (NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 * Added `Path.getSingle(pop,label)` and `Path.getList(label)` as default helpers in `Path`.
+* Changed `GremlinServer.start()` to return a `CompletableFuture` that contains the constructed `ServerGremlinExecutor`.
 * Restructured `IoTest` breaking it up into smaller and more logically grouped test cases.
 * Gremlin Server `Settings` now has sensible defaults thus allowing the server to be started with no additional configuration.
 * Fixed garbled characters in Gremlin Console that notably showed up in `:help`

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/be988ce8/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
index 8b66a84..f34ccc8 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/GremlinServer.java
@@ -64,7 +64,7 @@ public class GremlinServer {
     private Channel ch;
 
     private CompletableFuture<Void> serverStopped = null;
-    private CompletableFuture<Void> serverStarted = null;
+    private CompletableFuture<ServerGremlinExecutor<EventLoopGroup>> serverStarted = null;
 
     private final EventLoopGroup bossGroup;
     private final EventLoopGroup workerGroup;
@@ -110,14 +110,14 @@ public class GremlinServer {
     /**
      * Start Gremlin Server with {@link Settings} provided to the constructor.
      */
-    public synchronized CompletableFuture<Void> start() throws Exception {
+    public synchronized CompletableFuture<ServerGremlinExecutor<EventLoopGroup>> start() throws Exception {
         if(serverStarted != null) {
             // server already started - don't get it rolling again
             return serverStarted;
         }
 
         serverStarted = new CompletableFuture<>();
-        final CompletableFuture<Void> serverReadyFuture = serverStarted = new CompletableFuture<>();
+        final CompletableFuture<ServerGremlinExecutor<EventLoopGroup>> serverReadyFuture = serverStarted = new CompletableFuture<>();
         try {
             final ServerBootstrap b = new ServerBootstrap();
 
@@ -156,7 +156,7 @@ public class GremlinServer {
                                 settings.threadPoolWorker, settings.gremlinPool, settings.threadPoolBoss);
                         logger.info("Channel started at port {}.", settings.port);
 
-                        serverReadyFuture.complete(null);
+                        serverReadyFuture.complete(serverGremlinExecutor);
                     } else {
                         serverReadyFuture.completeExceptionally(new IOException(
                                 String.format("Could not bind to %s and %s - perhaps something else is bound to that address.", settings.host, settings.port)));


[2/8] incubator-tinkerpop git commit: Restructure the IoTest into smaller test groups.

Posted by ok...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoVertexTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoVertexTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoVertexTest.java
new file mode 100644
index 0000000..60ccfdd
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoVertexTest.java
@@ -0,0 +1,485 @@
+/*
+ * 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;
+
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.FeatureRequirement;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.TestHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+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.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.gryo.VertexByteArrayInputStream;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import static org.apache.tinkerpop.gremlin.structure.Graph.Features.DataTypeFeatures.FEATURE_STRING_VALUES;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeThat;
+import static org.mockito.Mockito.mock;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class IoVertexTest extends AbstractGremlinTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"graphson", false, false,
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.graphson()).reader().create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().create()},
+                {"graphson-embedded", true, false,
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.graphson()).reader().mapper(g.io(IoCore.graphson()).mapper().embedTypes(true).create()).create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().mapper(g.io(IoCore.graphson()).mapper().embedTypes(true).create()).create()},
+                {"gryo", true, true,
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.gryo()).reader().create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.gryo()).writer().create()}
+        });
+    }
+
+    @Parameterized.Parameter(value = 0)
+    public String ioType;
+
+    @Parameterized.Parameter(value = 1)
+    public boolean assertViaDirectEquality;
+
+    @Parameterized.Parameter(value = 2)
+    public boolean assertEdgesAtSameTimeAsVertex;
+
+    @Parameterized.Parameter(value = 3)
+    public Function<Graph, GraphReader> readerMaker;
+
+    @Parameterized.Parameter(value = 4)
+    public Function<Graph, GraphWriter> writerMaker;
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteVertexWithBOTHEdges() throws Exception {
+        final Vertex v1 = graph.addVertex("name", "marko", T.label, "person");
+
+        final Vertex v2 = graph.addVertex(T.label, "person");
+        final Edge e1 = v2.addEdge("friends", v1, "weight", 0.5d);
+        final Edge e2 = v1.addEdge("friends", v2, "weight", 1.0d);
+
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeVertex(os, v1, Direction.BOTH);
+
+            final AtomicBoolean calledVertex = new AtomicBoolean(false);
+            final AtomicBoolean calledEdge1 = new AtomicBoolean(false);
+            final AtomicBoolean calledEdge2 = new AtomicBoolean(false);
+
+            final GraphReader reader = readerMaker.apply(graph);
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertex(bais, attachable -> {
+                    final Vertex detachedVertex = attachable.get();
+                    if (assertViaDirectEquality) {
+                        TestHelper.validateVertexEquality(v1, detachedVertex, assertEdgesAtSameTimeAsVertex);
+                    } else {
+                        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 detachedVertex;
+                }, attachable -> {
+                    final Edge detachedEdge = attachable.get();
+                    final Predicate<Edge> matcher = assertViaDirectEquality ? e -> detachedEdge.id().equals(e.id()) :
+                            e -> graph.edges(detachedEdge.id().toString()).next().id().equals(e.id());
+                    if (matcher.test(e1)) {
+                        if (assertViaDirectEquality) {
+                            TestHelper.validateEdgeEquality(e1, detachedEdge);
+                        } else {
+                            assertEquals(e1.id(), graph.edges(detachedEdge.id().toString()).next().id());
+                            assertEquals(v1.id(), graph.vertices(detachedEdge.inVertex().id().toString()).next().id());
+                            assertEquals(v2.id(), graph.vertices(detachedEdge.outVertex().id().toString()).next().id());
+                            assertEquals(v2.label(), detachedEdge.inVertex().label());
+                            assertEquals(e1.label(), detachedEdge.label());
+                            assertEquals(1, IteratorUtils.count(detachedEdge.properties()));
+                            assertEquals(0.5d, detachedEdge.value("weight"), 0.000001d);
+                        }
+                        calledEdge1.set(true);
+                    } else if (matcher.test(e2)) {
+                        if (assertViaDirectEquality) {
+                            TestHelper.validateEdgeEquality(e2, detachedEdge);
+                        } else {
+                            assertEquals(e2.id(), graph.edges(detachedEdge.id().toString()).next().id());
+                            assertEquals(v2.id(), graph.vertices(detachedEdge.inVertex().id().toString()).next().id());
+                            assertEquals(v1.id(), graph.vertices(detachedEdge.outVertex().id().toString()).next().id());
+                            assertEquals(v1.label(), detachedEdge.outVertex().label());
+                            assertEquals(e2.label(), detachedEdge.label());
+                            assertEquals(1, IteratorUtils.count(detachedEdge.properties()));
+                            assertEquals(1.0d, detachedEdge.value("weight"), 0.000001d);
+                        }
+                        calledEdge2.set(true);
+                    } else {
+                        fail("An edge id generated that does not exist");
+                    }
+
+                    return null;
+                }, Direction.BOTH);
+            }
+
+            assertTrue(calledVertex.get());
+            assertTrue(calledEdge1.get());
+            assertTrue(calledEdge2.get());
+        }
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteVertexWithINEdges() throws Exception {
+        final Vertex v1 = graph.addVertex("name", "marko", T.label, "person");
+
+        final Vertex v2 = graph.addVertex(T.label, "person");
+        final Edge e = v2.addEdge("friends", v1, "weight", 0.5d);
+
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeVertex(os, v1, Direction.IN);
+
+            final AtomicBoolean calledVertex = new AtomicBoolean(false);
+            final AtomicBoolean calledEdge = new AtomicBoolean(false);
+
+            final GraphReader reader = readerMaker.apply(graph);
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertex(bais, attachable -> {
+                    final Vertex detachedVertex = attachable.get();
+                    if (assertViaDirectEquality) {
+                        TestHelper.validateVertexEquality(v1, detachedVertex, assertEdgesAtSameTimeAsVertex);
+                    } else {
+                        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 detachedVertex;
+                }, attachable -> {
+                    final Edge detachedEdge = attachable.get();
+                    if (assertViaDirectEquality)
+                        TestHelper.validateEdgeEquality(e, detachedEdge);
+                    else {
+                        assertEquals(e.id(), graph.edges(detachedEdge.id().toString()).next().id());
+                        assertEquals(v1.id(), graph.vertices(detachedEdge.inVertex().id().toString()).next().id());
+                        assertEquals(v2.id(), graph.vertices(detachedEdge.outVertex().id().toString()).next().id());
+                        assertEquals(v2.label(), detachedEdge.inVertex().label());
+                        assertEquals(e.label(), detachedEdge.label());
+                        assertEquals(1, IteratorUtils.count(detachedEdge.properties()));
+                        assertEquals(0.5d, detachedEdge.value("weight"), 0.000001d);
+                    }
+                    calledEdge.set(true);
+
+                    return detachedEdge;
+                }, Direction.IN);
+            }
+
+            assertTrue(calledVertex.get());
+            assertTrue(calledEdge.get());
+        }
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteVertexWithOUTEdges() throws Exception {
+        final Vertex v1 = graph.addVertex("name", "marko", T.label, "person");
+
+        final Vertex v2 = graph.addVertex(T.label, "person");
+        final Edge e = v1.addEdge("friends", v2, "weight", 0.5d);
+
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeVertex(os, v1, Direction.OUT);
+
+            final AtomicBoolean calledVertex = new AtomicBoolean(false);
+            final AtomicBoolean calledEdge = new AtomicBoolean(false);
+            final GraphReader reader = readerMaker.apply(graph);
+
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertex(bais, attachable -> {
+                            final Vertex detachedVertex = attachable.get();
+                            if (assertViaDirectEquality) {
+                                TestHelper.validateVertexEquality(v1, detachedVertex, assertEdgesAtSameTimeAsVertex);
+                            } else {
+                                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 detachedVertex;
+                        },
+                        attachable -> {
+                            final Edge detachedEdge = attachable.get();
+                            if (assertViaDirectEquality)
+                                TestHelper.validateEdgeEquality(e, detachedEdge);
+                            else {
+                                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);
+                            }
+                            calledEdge.set(true);
+
+                            return detachedEdge;
+                        }, Direction.OUT);
+            }
+
+            assertTrue(calledVertex.get());
+            assertTrue(calledEdge.get());
+        }
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteVertexNoEdges() throws Exception {
+        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
+        final Vertex v2 = graph.addVertex();
+        v1.addEdge("friends", v2, "weight", 0.5d);
+        assertVertexToSerialize(v1, true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteDetachedVertexNoEdges() throws Exception {
+        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
+        final Vertex v2 = graph.addVertex();
+        v1.addEdge("friends", v2, "weight", 0.5d);
+        assertVertexToSerialize(DetachedFactory.detach(v1, true), true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteDetachedVertexAsReferenceNoEdges() throws Exception {
+        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
+        final Vertex v2 = graph.addVertex();
+        v1.addEdge("friends", v2, "weight", 0.5d);
+        assertVertexToSerialize(DetachedFactory.detach(v1, false), false);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_MULTI_PROPERTIES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_META_PROPERTIES)
+    public void shouldReadWriteVertexMultiPropsNoEdges() throws Exception {
+        final Vertex v1 = graph.addVertex("name", "marko", "name", "mark", "acl", "rw");
+        v1.property(VertexProperty.Cardinality.single, "propsSquared", 123, "x", "a", "y", "b");
+        final Vertex v2 = graph.addVertex();
+        v1.addEdge("friends", v2, "weight", 0.5d);
+
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeVertex(os, v1);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphReader reader = readerMaker.apply(graph);
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertex(bais, attachable -> {
+                    final Vertex detachedVertex = attachable.get();
+                    assertEquals(v1.id(), assertViaDirectEquality ? detachedVertex.id() : graph.vertices(detachedVertex.id().toString()).next().id());
+                    assertEquals(v1.label(), detachedVertex.label());
+                    assertEquals(4, IteratorUtils.count(detachedVertex.properties()));
+                    assertEquals("a", detachedVertex.property("propsSquared").value("x"));
+                    assertEquals("b", detachedVertex.property("propsSquared").value("y"));
+                    assertEquals(2, IteratorUtils.count(detachedVertex.properties("name")));
+                    assertTrue(IteratorUtils.stream(detachedVertex.properties("name")).allMatch(p -> p.key().equals("name") && (p.value().equals("marko") || p.value().equals("mark"))));
+                    assertEquals(v1.value("acl"), detachedVertex.value("acl").toString());
+                    called.set(true);
+                    return mock(Vertex.class);
+                });
+            }
+            assertTrue(called.get());
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    public void shouldReadWriteVerticesNoEdges() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeVertices(os, g.V().has("age", P.gt(30)));
+
+            final AtomicInteger called = new AtomicInteger(0);
+            final GraphReader reader = readerMaker.apply(graph);
+
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                final Iterator<Vertex> itty = reader.readVertices(bais,
+                        attachable -> {
+                            final Vertex detachedVertex = attachable.get();
+                            called.incrementAndGet();
+                            return detachedVertex;
+                        }, null, null);
+
+                assertNotNull(itty.next());
+                assertNotNull(itty.next());
+                assertFalse(itty.hasNext());
+            }
+
+            assertEquals(2, called.get());
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
+    public void shouldReadWriteVerticesNoEdgesToGraphSONManual() throws Exception {
+        assumeThat(ioType, startsWith("graphson"));
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeVertices(os, g.V().has("age", P.gt(30)));
+
+            final AtomicInteger called = new AtomicInteger(0);
+            final GraphReader reader = readerMaker.apply(graph);
+            try (final BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(os.toByteArray())))) {
+                String line = br.readLine();
+                reader.readVertex(new ByteArrayInputStream(line.getBytes()),
+                        attachable -> {
+                            called.incrementAndGet();
+                            return mock(Vertex.class);
+                        });
+
+                line = br.readLine();
+                reader.readVertex(new ByteArrayInputStream(line.getBytes()),
+                        detachedVertex -> {
+                            called.incrementAndGet();
+                            return mock(Vertex.class);
+                        });
+            }
+
+            assertEquals(2, called.get());
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
+    public void shouldReadWriteVerticesNoEdgesToGryoManual() throws Exception {
+        assumeThat(ioType, is("gryo"));
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeVertices(os, g.V().has("age", P.gt(30)));
+
+            final AtomicInteger called = new AtomicInteger(0);
+            final GraphReader reader = readerMaker.apply(graph);
+            try (final VertexByteArrayInputStream vbais = new VertexByteArrayInputStream(new ByteArrayInputStream(os.toByteArray()))) {
+                final byte[] y = vbais.readVertexBytes().toByteArray();
+                reader.readVertex(new ByteArrayInputStream(y),
+                        attachable -> {
+                            final Vertex detachedVertex = attachable.get();
+                            called.incrementAndGet();
+                            return detachedVertex;
+                        });
+
+                final byte[] z = vbais.readVertexBytes().toByteArray();
+                reader.readVertex(new ByteArrayInputStream(z),
+                        attachable -> {
+                            final Vertex detachedVertex = attachable.get();
+                            called.incrementAndGet();
+                            return detachedVertex;
+                        });
+            }
+
+            assertEquals(2, called.get());
+        }
+    }
+
+    private void assertVertexToSerialize(final Vertex toSerialize, final boolean assertProperties) throws IOException {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeVertex(os, toSerialize);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphReader reader = readerMaker.apply(graph);
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readVertex(bais, attachable -> {
+                    final Vertex detachedVertex = attachable.get();
+                    if (assertViaDirectEquality) {
+                        TestHelper.validateVertexEquality(toSerialize, detachedVertex, false); // don't assert edges - there are none
+                    } else {
+                        assertEquals(toSerialize.id(), graph.vertices(detachedVertex.id().toString()).next().id());
+                        assertEquals(toSerialize.label(), detachedVertex.label());
+                        if (assertProperties) {
+                            assertEquals(2, IteratorUtils.count(detachedVertex.properties()));
+                            assertEquals(toSerialize.value("name"), detachedVertex.value("name").toString());
+                            assertEquals(toSerialize.value("acl"), detachedVertex.value("acl").toString());
+                        } else {
+                            assertEquals(0, IteratorUtils.count(detachedVertex.properties()));
+                        }
+                    }
+
+                    assertEquals(0, IteratorUtils.count(detachedVertex.edges(Direction.BOTH)));
+
+                    called.set(true);
+                    return mock(Vertex.class);
+                });
+            }
+            assertTrue(called.get());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java
new file mode 100644
index 0000000..0e4dbe0
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/util/CustomId.java
@@ -0,0 +1,92 @@
+/*
+ * 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.util;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+import org.apache.tinkerpop.gremlin.structure.io.IoTest;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+
+import java.io.IOException;
+import java.util.UUID;
+
+/**
+ * A mock identifier for use in ensuring that custom serializers work around element identifiers.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class CustomId {
+    private String cluster;
+    private UUID elementId;
+
+    private CustomId() {
+        // required no-arg for gryo serialization
+    }
+
+    public CustomId(final String cluster, final UUID elementId) {
+        this.cluster = cluster;
+        this.elementId = elementId;
+    }
+
+    public String getCluster() {
+        return cluster;
+    }
+
+    public UUID getElementId() {
+        return elementId;
+    }
+
+    @Override
+    public String toString() {
+        return cluster + ":" + elementId;
+    }
+
+    public static class CustomIdJacksonSerializer extends StdSerializer<CustomId> {
+        public CustomIdJacksonSerializer() {
+            super(CustomId.class);
+        }
+
+        @Override
+        public void serialize(final CustomId customId, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException, JsonGenerationException {
+            // when types are not embedded, stringify or resort to JSON primitive representations of the
+            // type so that non-jvm languages can better interoperate with the TinkerPop stack.
+            jsonGenerator.writeString(customId.toString());
+        }
+
+        @Override
+        public void serializeWithType(final CustomId customId, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+            // when the type is included add "class" as a key and then try to utilize as much of the
+            // default serialization provided by jackson data-bind as possible.  for example, write
+            // the uuid as an object so that when jackson serializes it, it uses the uuid serializer
+            // to write it out with the type.  in this way, data-bind should be able to deserialize
+            // it back when types are embedded.
+            jsonGenerator.writeStartObject();
+            jsonGenerator.writeStringField(GraphSONTokens.CLASS, CustomId.class.getName());
+            jsonGenerator.writeStringField("cluster", customId.getCluster());
+            jsonGenerator.writeObjectField("elementId", customId.getElementId());
+            jsonGenerator.writeEndObject();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
index f970214..cf85f2d 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
@@ -24,7 +24,9 @@ import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.GraphTest;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.IoEdgeTest;
 import org.apache.tinkerpop.gremlin.structure.io.IoTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoVertexTest;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedGraphTest;
 import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphTest;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge;
@@ -126,18 +128,24 @@ public class TinkerGraphProvider extends AbstractGraphProvider {
                 return TinkerGraph.DefaultIdManager.LONG;
             else if (testsThatNeedUuidIdManager.contains(testMethodName))
                 return TinkerGraph.DefaultIdManager.UUID;
-        } else if (test.equals(IoTest.class)) {
+        }  else if (test.equals(IoEdgeTest.class)) {
             final Set<String> testsThatNeedLongIdManager = new HashSet<String>(){{
-                add("shouldReadWriteEdgeToGraphSON");
-                add("shouldReadWriteDetachedEdgeAsReferenceToGraphSON");
-                add("shouldReadWriteDetachedEdgeToGraphSON");
-                add("shouldReadWriteVertexNoEdgesToGraphSON");
-                add("shouldReadWriteDetachedVertexNoEdgesToGraphSON");
-                add("shouldReadWriteDetachedVertexAsReferenceNoEdgesToGraphSON");
-                add("shouldReadWriteVertexMultiPropsNoEdgesToGraphSON");
-                add("shouldReadWriteVertexWithOUTEdgesToGraphSON");
-                add("shouldReadWriteVertexWithINEdgesToGraphSON");
-                add("shouldReadWriteVertexWithBOTHEdgesToGraphSON");
+                add("shouldReadWriteEdge[graphson]");
+                add("shouldReadWriteDetachedEdgeAsReference[graphson]");
+                add("shouldReadWriteDetachedEdge[graphson]");
+            }};
+
+            if (testsThatNeedLongIdManager.contains(testMethodName))
+                return TinkerGraph.DefaultIdManager.LONG;
+        } else if (test.equals(IoVertexTest.class)) {
+            final Set<String> testsThatNeedLongIdManager = new HashSet<String>(){{
+                add("shouldReadWriteVertexWithBOTHEdges[graphson]");
+                add("shouldReadWriteVertexWithINEdges[graphson]");
+                add("shouldReadWriteVertexWithOUTEdges[graphson]");
+                add("shouldReadWriteVertexNoEdges[graphson]");
+                add("shouldReadWriteDetachedVertexNoEdges[graphson]");
+                add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson]");
+                add("shouldReadWriteVertexMultiPropsNoEdges[graphson]");
             }};
 
             if (testsThatNeedLongIdManager.contains(testMethodName))


[5/8] incubator-tinkerpop git commit: Update changelog.

Posted by ok...@apache.org.
Update changelog.


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

Branch: refs/heads/xmatch-lost
Commit: 0b3e50e3d8842eb5df325711eb3ce329156aee37
Parents: 3ca54a6
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 12 14:23:22 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jun 12 14:23:22 2015 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/0b3e50e3/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index c65a036..3e31faa 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ TinkerPop 3.0.0.GA (NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 * Added `Path.getSingle(pop,label)` and `Path.getList(label)` as default helpers in `Path`.
+* Restructured `IoTest` breaking it up into smaller and more logically grouped test cases.
 * Gremlin Server `Settings` now has sensible defaults thus allowing the server to be started with no additional configuration.
 * Fixed garbled characters in Gremlin Console that notably showed up in `:help`
 * `GraphTraversal.and()` (and `or()`) now take `Object...` composed of `P` predicates or `Traversals` to be converted to `TraversalP`.


[3/8] incubator-tinkerpop git commit: Restructure the IoTest into smaller test groups.

Posted by ok...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java
index 3ed7e54..dc2e18d 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoTest.java
@@ -18,19 +18,12 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io;
 
-import com.fasterxml.jackson.core.JsonGenerationException;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
 import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.databind.ser.std.StdSerializer;
 import org.apache.commons.configuration.Configuration;
 import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
 import org.apache.tinkerpop.gremlin.FeatureRequirement;
-import org.apache.tinkerpop.gremlin.GraphManager;
 import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.TestHelper;
 import org.apache.tinkerpop.gremlin.structure.Direction;
@@ -39,32 +32,24 @@ import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Graph.Features.EdgePropertyFeatures;
 import org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures;
-import org.apache.tinkerpop.gremlin.process.traversal.P;
-import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLIo;
 import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLReader;
 import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLResourceAccess;
 import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLWriter;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONIo;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
-import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONResourceAccess;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONWriter;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.LegacyGraphSONReader;
-import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoIo;
-import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoMapper;
-import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoReader;
-import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoWriter;
-import org.apache.tinkerpop.gremlin.structure.io.gryo.VertexByteArrayInputStream;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
+import org.apache.tinkerpop.gremlin.structure.io.util.CustomId;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
 
 import javax.xml.XMLConstants;
 import javax.xml.transform.Source;
@@ -85,1814 +70,232 @@ import java.io.OutputStream;
 import java.io.Reader;
 import java.io.StringWriter;
 import java.io.Writer;
-import java.util.Iterator;
 import java.util.List;
 import java.util.UUID;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.apache.tinkerpop.gremlin.structure.Graph.Features.ElementFeatures.FEATURE_ANY_IDS;
 import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VariableFeatures.FEATURE_VARIABLES;
 import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexFeatures.FEATURE_USER_SUPPLIED_IDS;
 import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures.*;
-import static org.apache.tinkerpop.gremlin.structure.io.IoCore.graphml;
 import static org.apache.tinkerpop.gremlin.structure.io.IoCore.graphson;
-import static org.apache.tinkerpop.gremlin.structure.io.IoCore.gryo;
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.mock;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 /**
  * @author Joshua Shinavier (http://fortytwo.net)
  * @author Stephen Mallette (http://stephen.genoprime.com)
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
-public class IoTest extends AbstractGremlinTest {
-
-    private Io.Builder<GraphMLIo> graphml;
-    private Io.Builder<GraphSONIo> graphson;
-    private Io.Builder<GryoIo> gryo;
-
-    @Before
-    public void setupBeforeEachTest() {
-        graphml = graphml();
-        graphson = graphson();
-        gryo = gryo();
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    public void shouldReadGraphML() throws IOException {
-        readGraphMLIntoGraph(graph, "tinkerpop-classic.xml");
-        assertClassicGraph(graph, false, true);
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    public void shouldReadGraphMLUnorderedElements() throws IOException {
-        readGraphMLIntoGraph(graph, "tinkerpop-classic-unordered.xml");
-        assertClassicGraph(graph, false, true);
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_BOOLEAN_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_LONG_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_DOUBLE_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    public void shouldReadGraphMLAnAllSupportedDataTypes() throws IOException {
-        final GraphReader reader = GraphMLReader.build().create();
-        try (final InputStream stream = IoTest.class.getResourceAsStream(TestHelper.convertPackageToResourcePath(GraphMLResourceAccess.class) + "graph-types.xml")) {
-            reader.readGraph(stream, graph);
-        }
-
-        final Vertex v = graph.vertices().next();
-        assertEquals(123.45d, v.value("d"), 0.000001d);
-        assertEquals("some-string", v.<String>value("s"));
-        assertEquals(29, v.<Integer>value("i").intValue());
-        assertEquals(true, v.<Boolean>value("b"));
-        assertEquals(123.54f, v.value("f"), 0.000001f);
-        assertEquals(10000000l, v.<Long>value("l").longValue());
-        assertEquals("junk", v.<String>value("n"));
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteClassicToGraphMLToFileWithHelpers() throws Exception {
-        final File f = TestHelper.generateTempFile(this.getClass(), name.getMethodName(), ".xml");
-        try {
-            graph.io(graphml).writeGraph(f.getAbsolutePath());
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.CLASSIC);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            g1.io(graphml).readGraph(f.getAbsolutePath());
-
+@RunWith(Enclosed.class)
+public class IoTest {
+
+    public static class GraphMLTest extends AbstractGremlinTest {
+        @Test
+        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
+        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
+        public void shouldReadGraphML() throws IOException {
+            readGraphMLIntoGraph(graph, "tinkerpop-classic.xml");
             assertClassicGraph(graph, false, true);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        } catch (Exception ex) {
-            f.delete();
-            throw ex;
-        }
-    }
-
-    /**
-     * Only need to execute this test with TinkerGraph or other graphs that support user supplied identifiers.
-     */
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_NUMERIC_IDS)
-    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
-    public void shouldWriteNormalizedGraphML() throws Exception {
-        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
-            final GraphMLWriter w = GraphMLWriter.build().normalize(true).create();
-            w.writeGraph(bos, graph);
-
-            final String expected = streamToString(IoTest.class.getResourceAsStream(TestHelper.convertPackageToResourcePath(GraphMLResourceAccess.class) + "tinkerpop-classic-normalized.xml"));
-            assertEquals(expected.replace("\n", "").replace("\r", ""), bos.toString().replace("\n", "").replace("\r", ""));
         }
-    }
-
-    /**
-     * Only need to execute this test with TinkerGraph or other graphs that support user supplied identifiers.
-     */
-    @Test
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_NUMERIC_IDS)
-    @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = Graph.Features.VertexPropertyFeatures.FEATURE_USER_SUPPLIED_IDS)
-    @FeatureRequirement(featureClass = Graph.Features.VariableFeatures.class, feature = FEATURE_VARIABLES)
-    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
-    public void shouldWriteNormalizedGraphSON() throws Exception {
-        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
-            final GraphSONMapper mapper = graph.io(graphson).mapper().normalize(true).create();
-            final GraphSONWriter w = graph.io(graphson).writer().mapper(mapper).create();
-            w.writeGraph(bos, graph);
-
-            final String expected = streamToString(IoTest.class.getResourceAsStream(TestHelper.convertPackageToResourcePath(GraphSONResourceAccess.class) + "tinkerpop-classic-normalized.json"));
-            assertEquals(expected.replace("\n", "").replace("\r", ""), bos.toString().replace("\n", "").replace("\r", ""));
-        }
-    }
-
-    /**
-     * Note: this is only a very lightweight test of writer/reader encoding. It is known that there are characters
-     * which, when written by GraphMLWriter, cause parse errors for GraphMLReader. However, this happens uncommonly
-     * enough that is not yet known which characters those are. Only need to execute this test with TinkerGraph
-     * or other graphs that support user supplied identifiers.
-     */
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_STRING_IDS)
-    public void shouldProperlyEncodeWithGraphML() throws Exception {
-        final Vertex v = graph.addVertex(T.id, "1");
-        v.property(VertexProperty.Cardinality.single, "text", "\u00E9");
-
-        final GraphMLWriter w = GraphMLWriter.build().create();
-
-        final File f = TestHelper.generateTempFile(this.getClass(), "test", ".txt");
-        try (final OutputStream out = new FileOutputStream(f)) {
-            w.writeGraph(out, graph);
-        }
-
-        validateXmlAgainstGraphMLXsd(f);
-
-        // reusing the same config used for creation of "g".
-        final Configuration configuration = graphProvider.newGraphConfiguration("g2", this.getClass(), name.getMethodName(), null);
-        graphProvider.clear(configuration);
-        final Graph g2 = graphProvider.openTestGraph(configuration);
-        final GraphMLReader r = GraphMLReader.build().create();
 
-        try (final InputStream in = new FileInputStream(f)) {
-            r.readGraph(in, g2);
+        @Test
+        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
+        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
+        public void shouldReadGraphMLUnorderedElements() throws IOException {
+            readGraphMLIntoGraph(graph, "tinkerpop-classic-unordered.xml");
+            assertClassicGraph(graph, false, true);
         }
 
-        final Vertex v2 = g2.vertices("1").next();
-        assertEquals("\u00E9", v2.property("text").value());
-
-        // need to manually close the "g2" instance
-        graphProvider.clear(g2, configuration);
-    }
-
-    /**
-     * This is just a serialization check.
-     */
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_ANY_IDS)
-    public void shouldProperlySerializeCustomIdWithGraphSON() throws Exception {
-        final UUID id = UUID.fromString("AF4B5965-B176-4552-B3C1-FBBE2F52C305");
-        graph.addVertex(T.id, new CustomId("vertex", id));
-
-        final SimpleModule module = new SimpleModule();
-        module.addSerializer(CustomId.class, new CustomId.CustomIdJacksonSerializer());
-        final GraphWriter writer = graph.io(graphson).writer().mapper(
-                graph.io(graphson).mapper().addCustomModule(module).embedTypes(true).create()).create();
-
-        try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
-            writer.writeGraph(baos, graph);
-
-            final JsonNode jsonGraph = new ObjectMapper().readTree(baos.toByteArray());
-            final JsonNode idValue = jsonGraph.get(GraphSONTokens.ID);
-            assertTrue(idValue.has("cluster"));
-            assertEquals("vertex", idValue.get("cluster").asText());
-            assertTrue(idValue.has("elementId"));
-            assertEquals("AF4B5965-B176-4552-B3C1-FBBE2F52C305".toLowerCase(), idValue.get("elementId").get(1).asText());
+        @Test
+        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_FLOAT_VALUES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_BOOLEAN_VALUES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_LONG_VALUES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_DOUBLE_VALUES)
+        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
+        public void shouldReadGraphMLAnAllSupportedDataTypes() throws IOException {
+            final GraphReader reader = GraphMLReader.build().create();
+            try (final InputStream stream = IoTest.class.getResourceAsStream(TestHelper.convertPackageToResourcePath(GraphMLResourceAccess.class) + "graph-types.xml")) {
+                reader.readGraph(stream, graph);
+            }
+
+            final Vertex v = graph.vertices().next();
+            assertEquals(123.45d, v.value("d"), 0.000001d);
+            assertEquals("some-string", v.<String>value("s"));
+            assertEquals(29, v.<Integer>value("i").intValue());
+            assertEquals(true, v.<Boolean>value("b"));
+            assertEquals(123.54f, v.value("f"), 0.000001f);
+            assertEquals(10000000l, v.<Long>value("l").longValue());
+            assertEquals("junk", v.<String>value("n"));
+        }
+
+        /**
+         * Only need to execute this test with TinkerGraph or other graphs that support user supplied identifiers.
+         */
+        @Test
+        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
+        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_NUMERIC_IDS)
+        @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
+        public void shouldWriteNormalizedGraphML() throws Exception {
+            try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
+                final GraphMLWriter w = GraphMLWriter.build().normalize(true).create();
+                w.writeGraph(bos, graph);
+
+                final String expected = streamToString(IoTest.class.getResourceAsStream(TestHelper.convertPackageToResourcePath(GraphMLResourceAccess.class) + "tinkerpop-classic-normalized.xml"));
+                assertEquals(expected.replace("\n", "").replace("\r", ""), bos.toString().replace("\n", "").replace("\r", ""));
+            }
+        }
+
+        /**
+         * Note: this is only a very lightweight test of writer/reader encoding. It is known that there are characters
+         * which, when written by GraphMLWriter, cause parse errors for GraphMLReader. However, this happens uncommonly
+         * enough that is not yet known which characters those are. Only need to execute this test with TinkerGraph
+         * or other graphs that support user supplied identifiers.
+         */
+        @Test
+        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
+        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_STRING_IDS)
+        public void shouldProperlyEncodeWithGraphML() throws Exception {
+            final Vertex v = graph.addVertex(T.id, "1");
+            v.property(VertexProperty.Cardinality.single, "text", "\u00E9");
+
+            final GraphMLWriter w = GraphMLWriter.build().create();
+
+            final File f = TestHelper.generateTempFile(this.getClass(), "test", ".txt");
+            try (final OutputStream out = new FileOutputStream(f)) {
+                w.writeGraph(out, graph);
+            }
+
+            validateXmlAgainstGraphMLXsd(f);
 
             // reusing the same config used for creation of "g".
             final Configuration configuration = graphProvider.newGraphConfiguration("g2", this.getClass(), name.getMethodName(), null);
             graphProvider.clear(configuration);
             final Graph g2 = graphProvider.openTestGraph(configuration);
+            final GraphMLReader r = GraphMLReader.build().create();
 
-            try (final InputStream is = new ByteArrayInputStream(baos.toByteArray())) {
-                final GraphReader reader = graph.io(graphson).reader()
-                        .mapper(graph.io(graphson).mapper().embedTypes(true).addCustomModule(module).create()).create();
-                reader.readGraph(is, g2);
+            try (final InputStream in = new FileInputStream(f)) {
+                r.readGraph(in, g2);
             }
 
-            final Vertex v2 = g2.vertices().next();
-            final CustomId customId = (CustomId) v2.id();
-            assertEquals(id, customId.getElementId());
-            assertEquals("vertex", customId.getCluster());
+            final Vertex v2 = g2.vertices("1").next();
+            assertEquals("\u00E9", v2.property("text").value());
 
             // need to manually close the "g2" instance
             graphProvider.clear(g2, configuration);
         }
     }
 
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_ANY_IDS)
-    public void shouldProperlySerializeCustomIdWithGryo() throws Exception {
-        graph.addVertex(T.id, new CustomId("vertex", UUID.fromString("AF4B5965-B176-4552-B3C1-FBBE2F52C305")));
-        final GryoMapper gryo = GryoMapper.build().addCustom(CustomId.class).create();
-
-        final GryoWriter writer = GryoWriter.build().mapper(gryo).create();
-        final GryoReader reader = GryoReader.build().mapper(gryo).create();
-
-        final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), null);
-        graphProvider.clear(configuration);
-        final Graph g1 = graphProvider.openTestGraph(configuration);
-
-        GraphMigrator.migrateGraph(graph, g1, reader, writer);
-
-        final Vertex onlyVertex = g1.traversal().V().next();
-        final CustomId id = (CustomId) onlyVertex.id();
-        assertEquals("vertex", id.getCluster());
-        assertEquals(UUID.fromString("AF4B5965-B176-4552-B3C1-FBBE2F52C305"), id.getElementId());
-
-        // need to manually close the "g1" instance
-        graphProvider.clear(g1, configuration);
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldMigrateGraphWithFloat() throws Exception {
-        final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), null);
-        graphProvider.clear(configuration);
-        final Graph g1 = graphProvider.openTestGraph(configuration);
-
-        final GryoReader reader = graph.io(gryo).reader().create();
-        final GryoWriter writer = graph.io(gryo).writer().create();
-
-        GraphMigrator.migrateGraph(graph, g1, reader, writer);
-
-        assertClassicGraph(g1, false, false);
-
-        // need to manually close the "g1" instance
-        graphProvider.clear(g1, configuration);
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldMigrateGraph() throws Exception {
-        final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
-        graphProvider.clear(configuration);
-        final Graph g1 = graphProvider.openTestGraph(configuration);
-
-        final GryoReader reader = graph.io(gryo).reader().create();
-        final GryoWriter writer = graph.io(gryo).writer().create();
-
-        GraphMigrator.migrateGraph(graph, g1, reader, writer);
-
-        // by making this lossy for float it will assert floats for doubles
-        assertModernGraph(g1, true, false);
-
-        // need to manually close the "g1" instance
-        graphProvider.clear(g1, configuration);
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteModernToGryo() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeGraph(os, graph);
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
-            graphProvider.clear(configuration);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            final byte[] x = os.toByteArray();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(x)) {
-                reader.readGraph(bais, g1);
-            }
-
-            // by making this lossy for float it will assert floats for doubles
-            assertModernGraph(g1, true, false);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteModernToGryoToFileWithHelpers() throws Exception {
-        final File f = TestHelper.generateTempFile(this.getClass(), name.getMethodName(), ".kryo");
-        try {
-            graph.io(gryo).writeGraph(f.getAbsolutePath());
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            g1.io(gryo).readGraph(f.getAbsolutePath());
-
-            // by making this lossy for float it will assert floats for doubles
-            assertModernGraph(g1, true, false);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        } catch (Exception ex) {
-            f.delete();
-            throw ex;
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.CREW)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteCrewToGryo() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeGraph(os, graph);
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.CREW);
-            graphProvider.clear(configuration);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            final GryoReader reader = GryoReader.build()
-                    .mapper(graph.io(gryo).mapper().create()).create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readGraph(bais, g1);
-            }
-
-            // by making this lossy for float it will assert floats for doubles
-            assertCrewGraph(g1, false);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        }
-    }
-
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteClassicToGryo() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeGraph(os, graph);
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.CLASSIC);
-            graphProvider.clear(configuration);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readGraph(bais, g1);
-            }
-
-            assertClassicGraph(g1, false, false);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteClassicToGraphSON() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeGraph(os, graph);
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.CLASSIC);
-            graphProvider.clear(configuration);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            final GraphSONReader reader = graph.io(graphson).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readGraph(bais, g1);
-            }
-
-            assertClassicGraph(g1, true, false);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteModernToGraphSON() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeGraph(os, graph);
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
-            graphProvider.clear(configuration);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            final GraphSONReader reader = graph.io(graphson).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readGraph(bais, g1);
-            }
-
-            assertModernGraph(g1, true, false);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteModernToGraphSONWithHelpers() throws Exception {
-        final File f = TestHelper.generateTempFile(this.getClass(), name.getMethodName(), ".json");
-        try {
-            graph.io(graphson).writeGraph(f.getAbsolutePath());
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
-            graphProvider.clear(configuration);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            g1.io(graphson).readGraph(f.getAbsolutePath());
-
-            assertModernGraph(g1, true, false);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        } catch (Exception ex) {
-            f.delete();
-            throw ex;
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.CREW)
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    public void shouldReadWriteCrewToGraphSON() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeGraph(os, graph);
-
-            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.CREW);
-            graphProvider.clear(configuration);
-            final Graph g1 = graphProvider.openTestGraph(configuration);
-            final GraphSONReader reader = graph.io(graphson).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readGraph(bais, g1);
-            }
-
-            assertCrewGraph(g1, true);
-
-            // need to manually close the "g1" instance
-            graphProvider.clear(g1, configuration);
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    public void shouldReadWriteEdgeToGryoUsingFloatProperty() throws Exception {
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = v1.addEdge("friend", v2, "weight", 0.5f, "acl", "rw");
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    assertEquals(e.id(), detachedEdge.id());
-                    assertEquals(v1.id(), detachedEdge.outVertex().id());
-                    assertEquals(v2.id(), detachedEdge.inVertex().id());
-                    assertEquals(v1.label(), detachedEdge.outVertex().label());
-                    assertEquals(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(0.5f, detachedEdge.properties("weight").next().value());
-                    assertEquals("rw", detachedEdge.properties("acl").next().value());
-
-                    called.set(true);
-
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteEdgeToGryo() throws Exception {
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = v1.addEdge("friend", v2, "weight", 0.5d, "acl", "rw");
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    assertEquals(e.id(), detachedEdge.id());
-                    assertEquals(v1.id(), detachedEdge.outVertex().id());
-                    assertEquals(v2.id(), detachedEdge.inVertex().id());
-                    assertEquals(v1.label(), detachedEdge.outVertex().label());
-                    assertEquals(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(0.5d, e.properties("weight").next().value());
-                    assertEquals("rw", e.properties("acl").next().value());
-                    called.set(true);
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteDetachedEdgeAsReferenceToGryo() throws Exception {
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = DetachedFactory.detach(v1.addEdge("friend", v2, "weight", 0.5d, "acl", "rw"), false);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    assertEquals(e.id(), detachedEdge.id());
-                    assertEquals(v1.id(), detachedEdge.outVertex().id());
-                    assertEquals(v2.id(), detachedEdge.inVertex().id());
-                    assertEquals(v1.label(), detachedEdge.outVertex().label());
-                    assertEquals(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(e.keys().size(), IteratorUtils.count(detachedEdge.properties()));
-                    called.set(true);
-
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteDetachedEdgeToGryo() throws Exception {
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = DetachedFactory.detach(v1.addEdge("friend", v2, "weight", 0.5d, "acl", "rw"), true);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    assertEquals(e.id(), detachedEdge.id());
-                    assertEquals(v1.id(), detachedEdge.outVertex().id());
-                    assertEquals(v2.id(), detachedEdge.inVertex().id());
-                    assertEquals(v1.label(), detachedEdge.outVertex().label());
-                    assertEquals(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(0.5d, detachedEdge.properties("weight").next().value());
-                    assertEquals("rw", detachedEdge.properties("acl").next().value());
-                    called.set(true);
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteEdgeToGraphSON() throws Exception {
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = v1.addEdge("friend", v2, "weight", 0.5f, "acl", "rw");
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GraphSONReader reader = graph.io(graphson).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    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(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(0.5d, detachedEdge.properties("weight").next().value());
-                    assertEquals("rw", detachedEdge.properties("acl").next().value());
-                    called.set(true);
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteDetachedEdgeAsReferenceToGraphSON() throws Exception {
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = DetachedFactory.detach(v1.addEdge("friend", v2, "weight", 0.5f, "acl", "rw"), false);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GraphSONReader reader = graph.io(graphson).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    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(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(e.keys().size(), IteratorUtils.count(detachedEdge.properties()));
-                    called.set(true);
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteDetachedEdgeToGraphSON() throws Exception {
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = DetachedFactory.detach(v1.addEdge("friend", v2, "weight", 0.5f, "acl", "rw"), true);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GraphSONReader reader = graph.io(graphson).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    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(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(0.5d, detachedEdge.properties("weight").next().value());
-                    assertEquals("rw", detachedEdge.properties("acl").next().value());
-                    called.set(true);
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_NUMERIC_IDS)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
-    public void shouldReadWriteEdgeToGraphSONNonLossy() throws Exception {
-        final Vertex v1 = graph.addVertex(T.id, 1l, T.label, "person");
-        final Vertex v2 = graph.addVertex(T.id, 2l, T.label, "person");
-        final Edge e = v1.addEdge("friend", v2, "weight", 0.5f, "acl", "rw");
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().mapper(graph.io(graphson).mapper().embedTypes(true).create()).create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GraphSONReader reader = graph.io(graphson).reader().mapper(graph.io(graphson).mapper().embedTypes(true).create()).create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    assertEquals(e.id(), detachedEdge.id());
-                    assertEquals(v1.id(), detachedEdge.outVertex().id());
-                    assertEquals(v2.id(), detachedEdge.inVertex().id());
-                    assertEquals(v1.label(), detachedEdge.outVertex().label());
-                    assertEquals(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(0.5f, detachedEdge.properties("weight").next().value());
-                    assertEquals("rw", detachedEdge.properties("acl").next().value());
-                    called.set(true);
-
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_SERIALIZABLE_VALUES)
-    public void shouldSupportUUIDInGraphSON() throws Exception {
-        final UUID id = UUID.randomUUID();
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = v1.addEdge("friend", v2, "uuid", id);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().mapper(graph.io(graphson).mapper().embedTypes(true).create()).create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GraphSONReader reader = graph.io(graphson).reader().mapper(graph.io(graphson).mapper().embedTypes(true).create()).create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    // a quick reminder here that the purpose of these id assertions is to ensure that those with
-                    // complex ids that are not simply toString'd (i.e. are complex objects in JSON as well)
-                    // properly respond to filtering in Graph.edges/vertices
-                    assertEquals(e.id(), graph.edges(detachedEdge.id()).next().id());
-                    assertEquals(v1.id(), graph.vertices(detachedEdge.outVertex().id()).next().id());
-                    assertEquals(v2.id(), graph.vertices(detachedEdge.inVertex().id()).next().id());
-                    assertEquals(v1.label(), detachedEdge.outVertex().label());
-                    assertEquals(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(e.keys().size(), IteratorUtils.count(detachedEdge.properties()));
-                    assertEquals(id, detachedEdge.value("uuid"));
-
-                    called.set(true);
-
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_SERIALIZABLE_VALUES)
-    public void shouldSupportUUIDInGryo() throws Exception {
-        final UUID id = UUID.randomUUID();
-        final Vertex v1 = graph.addVertex(T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = v1.addEdge("friend", v2, "uuid", id);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeEdge(os, e);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readEdge(bais, edge -> {
-                    final Edge detachedEdge = (Edge) edge;
-                    assertEquals(e.id(), detachedEdge.id());
-                    assertEquals(v1.id(), detachedEdge.outVertex().id());
-                    assertEquals(v2.id(), detachedEdge.inVertex().id());
-                    assertEquals(v1.label(), detachedEdge.outVertex().label());
-                    assertEquals(v2.label(), detachedEdge.inVertex().label());
-                    assertEquals(e.label(), detachedEdge.label());
-                    assertEquals(e.keys().size(), IteratorUtils.count(detachedEdge.properties()));
-                    assertEquals(id, detachedEdge.value("uuid"));
-
-                    called.set(true);
-
-                    return null;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    public void shouldReadWriteVertexNoEdgesToGryoUsingFloatProperty() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
-
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5f);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeVertex(os, v1);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readVertex(bais, attachable -> {
-                    final Vertex detachedVertex = attachable.get();
-                    assertEquals(v1.id(), detachedVertex.id());
-                    assertEquals(v1.label(), detachedVertex.label());
-                    assertEquals(2, IteratorUtils.count(detachedVertex.properties()));
-                    assertEquals(v1.value("name"), detachedVertex.value("name").toString());
-                    assertEquals(v1.value("acl"), detachedVertex.value("acl").toString());
-                    called.set(true);
-                    return mock(Vertex.class);
-                });
-            }
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteVertexNoEdgesToGryo() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5d);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeVertex(os, v1);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readVertex(bais, attachable -> {
-                    final Vertex detachedVertex = attachable.get();
-                    assertEquals(v1.id(), detachedVertex.id());
-                    assertEquals(v1.label(), detachedVertex.label());
-                    assertEquals(2, IteratorUtils.count(detachedVertex.properties()));
-                    assertEquals(v1.value("name"), detachedVertex.value("name").toString());
-                    assertEquals(v1.value("acl"), detachedVertex.value("acl").toString());
-                    called.set(true);
-                    return mock(Vertex.class);
-                });
-            }
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteDetachedVertexNoEdgesToGryo() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5d);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            final DetachedVertex dv = DetachedFactory.detach(v1, true);
-            writer.writeVertex(os, dv);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readVertex(bais, attachable -> {
-                    final Vertex detachedVertex = attachable.get();
-                    assertEquals(v1.id(), detachedVertex.id());
-                    assertEquals(v1.label(), detachedVertex.label());
-                    assertEquals(2, IteratorUtils.count(detachedVertex.properties()));
-                    assertEquals("marko", detachedVertex.properties("name").next().value());
-                    assertEquals("rw", detachedVertex.properties("acl").next().value());
-                    called.set(true);
-                    return mock(Vertex.class);
-                });
-            }
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteDetachedVertexAsReferenceNoEdgesToGryo() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5d);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            final DetachedVertex dv = DetachedFactory.detach(v1, false);
-            writer.writeVertex(os, dv);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readVertex(bais, attachable -> {
-                    final Vertex detachedVertex = attachable.get();
-                    assertEquals(v1.id(), detachedVertex.id());
-                    assertEquals(v1.label(), detachedVertex.label());
-                    assertEquals(0, IteratorUtils.count(detachedVertex.properties()));
-                    called.set(true);
-                    return mock(Vertex.class);
-                });
-            }
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_MULTI_PROPERTIES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_META_PROPERTIES)
-    public void shouldReadWriteVertexMultiPropsNoEdgesToGryo() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "name", "mark", "acl", "rw");
-        v1.property(VertexProperty.Cardinality.single, "propsSquared", 123, "x", "a", "y", "b");
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5d);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeVertex(os, v1);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readVertex(bais, attachable -> {
-                    final Vertex detachedVertex = attachable.get();
-                    assertEquals(v1.id(), detachedVertex.id());
-                    assertEquals(v1.label(), detachedVertex.label());
-                    assertEquals(4, IteratorUtils.count(detachedVertex.properties()));
-                    assertEquals("a", detachedVertex.property("propsSquared").value("x"));
-                    assertEquals("b", detachedVertex.property("propsSquared").value("y"));
-                    assertEquals(2, IteratorUtils.count(detachedVertex.properties("name")));
-                    assertTrue(IteratorUtils.stream(detachedVertex.properties("name")).allMatch(p -> p.key().equals("name") && (p.value().equals("marko") || p.value().equals("mark"))));
-                    assertEquals(v1.value("acl"), detachedVertex.value("acl").toString());
-                    called.set(true);
-                    return mock(Vertex.class);
-                });
-            }
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteVertexNoEdgesToGraphSON() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5f);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeVertex(os, v1);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            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(2, IteratorUtils.count(detachedVertex.properties()));
-                    assertEquals("marko", detachedVertex.properties("name").next().value());
-                    assertEquals("rw", detachedVertex.properties("acl").next().value());
-                    called.set(true);
-                    return detachedVertex;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteDetachedVertexNoEdgesToGraphSON() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5f);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            final DetachedVertex dv = DetachedFactory.detach(v1, true);
-            writer.writeVertex(os, dv);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            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(2, IteratorUtils.count(detachedVertex.properties()));
-                    assertEquals("marko", detachedVertex.properties("name").next().value());
-                    assertEquals("rw", detachedVertex.properties("acl").next().value());
-                    called.set(true);
-                    return detachedVertex;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteDetachedVertexAsReferenceNoEdgesToGraphSON() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "acl", "rw");
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5f);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            final DetachedVertex dv = DetachedFactory.detach(v1, false);
-            writer.writeVertex(os, dv);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            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(0, IteratorUtils.count(detachedVertex.properties()));
-
-                    called.set(true);
-                    return detachedVertex;
-                });
-            }
-
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_MULTI_PROPERTIES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_META_PROPERTIES)
-    public void shouldReadWriteVertexMultiPropsNoEdgesToGraphSON() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", "name", "mark", "acl", "rw");
-        v1.property(VertexProperty.Cardinality.single, "propsSquared", 123, "x", "a", "y", "b");
-        final Vertex v2 = graph.addVertex();
-        v1.addEdge("friends", v2, "weight", 0.5d);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeVertex(os, v1);
-
-            final AtomicBoolean called = new AtomicBoolean(false);
-            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(4, IteratorUtils.count(detachedVertex.properties()));
-                    assertEquals("a", detachedVertex.property("propsSquared").value("x"));
-                    assertEquals("b", detachedVertex.property("propsSquared").value("y"));
-                    assertEquals(2, IteratorUtils.count(detachedVertex.properties("name")));
-                    assertTrue(IteratorUtils.stream(detachedVertex.properties("name")).allMatch(p -> p.key().equals("name") && (p.value().equals("marko") || p.value().equals("mark"))));
-                    assertEquals(v1.value("acl"), detachedVertex.value("acl").toString());
-                    called.set(true);
-                    return mock(Vertex.class);
-                });
-            }
-            assertTrue(called.get());
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
-    public void shouldReadWriteVerticesNoEdgesToGryoManual() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeVertices(os, g.V().has("age", P.gt(30)));
-
-            final AtomicInteger called = new AtomicInteger(0);
-            final GryoReader reader = graph.io(gryo).reader().create();
-            try (final VertexByteArrayInputStream vbais = new VertexByteArrayInputStream(new ByteArrayInputStream(os.toByteArray()))) {
-                final byte[] y = vbais.readVertexBytes().toByteArray();
-                reader.readVertex(new ByteArrayInputStream(y),
-                        attachable -> {
-                            final Vertex detachedVertex = attachable.get();
-                            called.incrementAndGet();
-                            return detachedVertex;
-                        });
-
-                final byte[] z = vbais.readVertexBytes().toByteArray();
-                reader.readVertex(new ByteArrayInputStream(z),
-                        attachable -> {
-                            final Vertex detachedVertex = attachable.get();
-                            called.incrementAndGet();
-                            return detachedVertex;
-                        });
-            }
-
-            assertEquals(2, called.get());
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
-    public void shouldReadWriteVerticesNoEdgesToGryo() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeVertices(os, g.V().has("age", P.gt(30)));
-
-            final AtomicInteger called = new AtomicInteger(0);
-            final GryoReader reader = graph.io(gryo).reader().create();
-
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                final Iterator<Vertex> itty = reader.readVertices(bais,
-                        attachable -> {
-                            final Vertex detachedVertex = attachable.get();
-                            called.incrementAndGet();
-                            return detachedVertex;
-                        }, null, null);
-
-                assertNotNull(itty.next());
-                assertNotNull(itty.next());
-                assertFalse(itty.hasNext());
-            }
-
-            assertEquals(2, called.get());
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
-    public void shouldReadWriteVerticesNoEdgesToGraphSON() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeVertices(os, g.V().has("age", P.gt(30)));
-
-            final AtomicInteger called = new AtomicInteger(0);
-            final GraphSONReader reader = graph.io(graphson).reader().create();
-
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                final Iterator<Vertex> itty = reader.readVertices(bais,
-                        attachable -> {
-                            final Vertex detachedVertex = attachable.get();
-                            called.incrementAndGet();
-                            return detachedVertex;
-                        }, null, null);
-
-                assertNotNull(itty.next());
-                assertNotNull(itty.next());
-                assertFalse(itty.hasNext());
-            }
-
-            assertEquals(2, called.get());
-        }
-    }
-
-    @Test
-    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
-    public void shouldReadWriteVerticesNoEdgesToGraphSONManual() throws Exception {
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GraphSONWriter writer = graph.io(graphson).writer().create();
-            writer.writeVertices(os, g.V().has("age", P.gt(30)));
-
-            final AtomicInteger called = new AtomicInteger(0);
-            final GraphSONReader reader = graph.io(graphson).reader().create();
-            final BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(os.toByteArray())));
-            String line = br.readLine();
-            reader.readVertex(new ByteArrayInputStream(line.getBytes()),
-                    attachable -> {
-                        called.incrementAndGet();
-                        return mock(Vertex.class);
-                    });
-
-            line = br.readLine();
-            reader.readVertex(new ByteArrayInputStream(line.getBytes()),
-                    detachedVertex -> {
-                        called.incrementAndGet();
-                        return mock(Vertex.class);
-                    });
-
-            assertEquals(2, called.get());
-        }
-    }
-
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteVertexWithOUTEdgesToGryo() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", T.label, "person");
-
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = v1.addEdge("friends", v2, "weight", 0.5d);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final GryoWriter writer = graph.io(gryo).writer().create();
-            writer.writeVertex(os, v1, Direction.OUT);
-
-            final AtomicBoolean calledVertex = new AtomicBoolean(false);
-            final AtomicBoolean calledEdge = new AtomicBoolean(false);
-            final GryoReader reader = graph.io(gryo).reader().create();
-
-            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
-                reader.readVertex(bais, attachable -> {
-                            final Vertex detachedVertex = attachable.get();
-                            TestHelper.validateVertexEquality(v1, detachedVertex, true);
-                            calledVertex.set(true);
-                            return detachedVertex;
-                        },
-                        attachable -> {
-                            final Edge detachedEdge = attachable.get();
-                            TestHelper.validateEdgeEquality(e, detachedEdge);
-                            calledEdge.set(true);
-
-                            return detachedEdge;
-                        }, Direction.OUT);
-            }
-
-            assertTrue(calledVertex.get());
-            assertTrue(calledEdge.get());
-        }
-    }
-
-    @Test
-    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
-    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
-    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_FLOAT_VALUES)
-    @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
-    public void shouldReadWriteVertexWithOUTEdgesToGraphSON() throws Exception {
-        final Vertex v1 = graph.addVertex("name", "marko", T.label, "person");
-        final Vertex v2 = graph.addVertex(T.label, "person");
-        final Edge e = v1.addEdge("friends", v2, "weight", 0.5f);
-
-        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
-            final Graph

<TRUNCATED>

[8/8] incubator-tinkerpop git commit: Merge branch 'xmatch' into xmatch-lost

Posted by ok...@apache.org.
Merge branch 'xmatch' into xmatch-lost


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

Branch: refs/heads/xmatch-lost
Commit: d4847b816f46e976e280f8843066e3bebbec7b85
Parents: bf3fe79 a4f5267
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Fri Jun 12 14:29:50 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Fri Jun 12 14:29:50 2015 -0600

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |    2 +
 .../tinkerpop/gremlin/server/GremlinServer.java |    8 +-
 .../traversal/step/sideEffect/ProfileTest.java  |   10 +-
 .../tinkerpop/gremlin/structure/GraphTest.java  |    3 +-
 .../structure/StructureStandardSuite.java       |   10 +
 .../tinkerpop/gremlin/structure/VertexTest.java |    3 +-
 .../gremlin/structure/io/IoCustomTest.java      |  143 ++
 .../gremlin/structure/io/IoEdgeTest.java        |  149 ++
 .../gremlin/structure/io/IoGraphTest.java       |  226 ++
 .../gremlin/structure/io/IoPropertyTest.java    |  150 ++
 .../tinkerpop/gremlin/structure/io/IoTest.java  | 2048 ++----------------
 .../gremlin/structure/io/IoVertexTest.java      |  485 +++++
 .../gremlin/structure/io/util/CustomId.java     |   92 +
 .../tinkergraph/TinkerGraphProvider.java        |   30 +-
 14 files changed, 1487 insertions(+), 1872 deletions(-)
----------------------------------------------------------------------



[4/8] incubator-tinkerpop git commit: Restructure the IoTest into smaller test groups.

Posted by ok...@apache.org.
Restructure the IoTest into smaller test groups.

Improved coverage in the process by parameterizing tests.  Should be easier now to add additional tests for IO as gaps are found.


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

Branch: refs/heads/xmatch-lost
Commit: 3ca54a629f27b38ddda1140cd1d12d4620e700c5
Parents: 89d0ac5
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 12 14:15:44 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jun 12 14:15:44 2015 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/structure/GraphTest.java  |    3 +-
 .../structure/StructureStandardSuite.java       |   10 +
 .../tinkerpop/gremlin/structure/VertexTest.java |    3 +-
 .../gremlin/structure/io/IoCustomTest.java      |  143 ++
 .../gremlin/structure/io/IoEdgeTest.java        |  149 ++
 .../gremlin/structure/io/IoGraphTest.java       |  226 ++
 .../gremlin/structure/io/IoPropertyTest.java    |  150 ++
 .../tinkerpop/gremlin/structure/io/IoTest.java  | 2048 ++----------------
 .../gremlin/structure/io/IoVertexTest.java      |  485 +++++
 .../gremlin/structure/io/util/CustomId.java     |   92 +
 .../tinkergraph/TinkerGraphProvider.java        |   30 +-
 11 files changed, 1476 insertions(+), 1863 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/GraphTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/GraphTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/GraphTest.java
index ea5b9a3..b65ca4d 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/GraphTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/GraphTest.java
@@ -25,6 +25,7 @@ import org.apache.tinkerpop.gremlin.FeatureRequirementSet;
 import org.apache.tinkerpop.gremlin.GraphManager;
 import org.apache.tinkerpop.gremlin.GraphProvider;
 import org.apache.tinkerpop.gremlin.structure.io.IoTest;
+import org.apache.tinkerpop.gremlin.structure.io.util.CustomId;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.junit.Test;
 
@@ -199,7 +200,7 @@ public class GraphTest extends AbstractGremlinTest {
 
         // this is different from "FEATURE_CUSTOM_IDS" as TinkerGraph does not define a specific id class
         // (i.e. TinkerId) for the identifier.
-        final IoTest.CustomId customId = new IoTest.CustomId("test", uuid);
+        final CustomId customId = new CustomId("test", uuid);
         graph.addVertex(T.id, customId);
         graph.addVertex();
         tryCommit(graph, graph -> {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/StructureStandardSuite.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/StructureStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/StructureStandardSuite.java
index 2f452a0..b2e3494 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/StructureStandardSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/StructureStandardSuite.java
@@ -23,7 +23,12 @@ import org.apache.tinkerpop.gremlin.GraphProvider;
 import org.apache.tinkerpop.gremlin.algorithm.generator.CommunityGeneratorTest;
 import org.apache.tinkerpop.gremlin.algorithm.generator.DistributionGeneratorTest;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
+import org.apache.tinkerpop.gremlin.structure.io.IoCustomTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoEdgeTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoGraphTest;
 import org.apache.tinkerpop.gremlin.structure.io.IoTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoPropertyTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoVertexTest;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdgeTest;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedGraphTest;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedPropertyTest;
@@ -81,6 +86,11 @@ public class StructureStandardSuite extends AbstractGremlinSuite {
             DistributionGeneratorTest.class,
             EdgeTest.class,
             FeatureSupportTest.class,
+            IoCustomTest.class,
+            IoEdgeTest.class,
+            IoGraphTest.class,
+            IoVertexTest.class,
+            IoPropertyTest.class,
             GraphTest.class,
             GraphConstructionTest.class,
             IoTest.class,

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexTest.java
index 6e7b02b..a958b07 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexTest.java
@@ -26,6 +26,7 @@ import org.apache.tinkerpop.gremlin.GraphManager;
 import org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexFeatures;
 import org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures;
 import org.apache.tinkerpop.gremlin.structure.io.IoTest;
+import org.apache.tinkerpop.gremlin.structure.io.util.CustomId;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.function.FunctionUtils;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -137,7 +138,7 @@ public class VertexTest {
 
             // this is different from "FEATURE_CUSTOM_IDS" as TinkerGraph does not define a specific id class
             // (i.e. TinkerId) for the identifier.
-            final IoTest.CustomId customId = new IoTest.CustomId("test", uuid);
+            final CustomId customId = new CustomId("test", uuid);
             final Vertex v = graph.addVertex();
             v.addEdge("self", v, T.id, customId);
             tryCommit(graph, graph -> {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java
new file mode 100644
index 0000000..5f9bc3b
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoCustomTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import org.apache.commons.configuration.Configuration;
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.FeatureRequirement;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.io.util.CustomId;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+
+import static org.apache.tinkerpop.gremlin.structure.Graph.Features.ElementFeatures.FEATURE_ANY_IDS;
+import static org.apache.tinkerpop.gremlin.structure.Graph.Features.ElementFeatures.FEATURE_USER_SUPPLIED_IDS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class IoCustomTest extends AbstractGremlinTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        final SimpleModule module = new SimpleModule();
+        module.addSerializer(CustomId.class, new CustomId.CustomIdJacksonSerializer());
+
+        return Arrays.asList(new Object[][]{
+                {"graphson-embedded", true,
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.graphson()).reader().mapper(g.io(IoCore.graphson()).mapper().addCustomModule(module).embedTypes(true).create()).create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().mapper(g.io(IoCore.graphson()).mapper().addCustomModule(module).embedTypes(true).create()).create()},
+                {"gryo", true,
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.gryo()).reader().mapper(g.io(IoCore.gryo()).mapper().addCustom(CustomId.class).create()).create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.gryo()).writer().mapper(g.io(IoCore.gryo()).mapper().addCustom(CustomId.class).create()).create()}
+        });
+    }
+
+    @Parameterized.Parameter(value = 0)
+    public String ioType;
+
+    @Parameterized.Parameter(value = 1)
+    public boolean assertIdDirectly;
+
+    @Parameterized.Parameter(value = 2)
+    public Function<Graph, GraphReader> readerMaker;
+
+    @Parameterized.Parameter(value = 3)
+    public Function<Graph, GraphWriter> writerMaker;
+
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_SERIALIZABLE_VALUES)
+    public void shouldSupportUUID() throws Exception {
+        final UUID id = UUID.randomUUID();
+        final Vertex v1 = graph.addVertex(T.label, "person");
+        final Vertex v2 = graph.addVertex(T.label, "person");
+        final Edge e = v1.addEdge("friend", v2, "uuid", id);
+
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeEdge(os, e);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphReader reader = readerMaker.apply(graph);
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readEdge(bais, edge -> {
+                    final Edge detachedEdge = (Edge) edge;
+                    assertEquals(e.id(), assertIdDirectly ? detachedEdge.id() : graph.edges(detachedEdge.id().toString()).next().id());
+                    assertEquals(v1.id(), assertIdDirectly ? detachedEdge.outVertex().id() : graph.vertices(detachedEdge.outVertex().id().toString()).next().id());
+                    assertEquals(v2.id(), assertIdDirectly ? detachedEdge.inVertex().id() : graph.vertices(detachedEdge.inVertex().id().toString()).next().id());
+                    assertEquals(v1.label(), detachedEdge.outVertex().label());
+                    assertEquals(v2.label(), detachedEdge.inVertex().label());
+                    assertEquals(e.label(), detachedEdge.label());
+                    assertEquals(e.keys().size(), IteratorUtils.count(detachedEdge.properties()));
+                    assertEquals(id, detachedEdge.value("uuid"));
+
+                    called.set(true);
+
+                    return null;
+                });
+            }
+
+            assertTrue(called.get());
+        }
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = FEATURE_ANY_IDS)
+    public void shouldProperlySerializeCustomId() throws Exception {
+        graph.addVertex(T.id, new CustomId("vertex", UUID.fromString("AF4B5965-B176-4552-B3C1-FBBE2F52C305")));
+
+        final GraphWriter writer = writerMaker.apply(graph);
+        final GraphReader reader = readerMaker.apply(graph);
+
+        final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), null);
+        graphProvider.clear(configuration);
+        final Graph g1 = graphProvider.openTestGraph(configuration);
+
+        GraphMigrator.migrateGraph(graph, g1, reader, writer);
+
+        final Vertex onlyVertex = g1.traversal().V().next();
+        final CustomId id = (CustomId) onlyVertex.id();
+        assertEquals("vertex", id.getCluster());
+        assertEquals(UUID.fromString("AF4B5965-B176-4552-B3C1-FBBE2F52C305"), id.getElementId());
+
+        // need to manually close the "g1" instance
+        graphProvider.clear(g1, configuration);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoEdgeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoEdgeTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoEdgeTest.java
new file mode 100644
index 0000000..e8db127
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoEdgeTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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;
+
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.FeatureRequirement;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for all IO implementations that are specific to reading and writing of a {@link Edge}.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class IoEdgeTest extends AbstractGremlinTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"graphson", false, false,
+                        (Function<Graph,GraphReader>) g -> g.io(IoCore.graphson()).reader().create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().create()},
+                {"graphson-embedded", true, true,
+                        (Function<Graph,GraphReader>) g -> g.io(IoCore.graphson()).reader().mapper(g.io(IoCore.graphson()).mapper().embedTypes(true).create()).create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().mapper(g.io(IoCore.graphson()).mapper().embedTypes(true).create()).create()},
+                {"gryo", true, true,
+                        (Function<Graph,GraphReader>) g -> g.io(IoCore.gryo()).reader().create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.gryo()).writer().create()}
+        });
+    }
+
+    @Parameterized.Parameter(value = 0)
+    public String ioType;
+
+    @Parameterized.Parameter(value = 1)
+    public boolean assertIdDirectly;
+
+    @Parameterized.Parameter(value = 2)
+    public boolean assertDouble;
+
+    @Parameterized.Parameter(value = 3)
+    public Function<Graph, GraphReader> readerMaker;
+
+    @Parameterized.Parameter(value = 4)
+    public Function<Graph, GraphWriter> writerMaker;
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteEdge() throws Exception {
+        final Vertex v1 = graph.addVertex(T.label, "person");
+        final Vertex v2 = graph.addVertex(T.label, "person");
+        final Edge e = v1.addEdge("friend", v2, "weight", 0.5d, "acl", "rw");
+
+        assertEdge(v1, v2, e, true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteDetachedEdge() throws Exception {
+        final Vertex v1 = graph.addVertex(T.label, "person");
+        final Vertex v2 = graph.addVertex(T.label, "person");
+        final Edge e = DetachedFactory.detach(v1.addEdge("friend", v2, "weight", 0.5d, "acl", "rw"), true);
+
+        assertEdge(v1, v2, e, true);
+    }
+
+    @Test
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = Graph.Features.EdgePropertyFeatures.FEATURE_DOUBLE_VALUES)
+    public void shouldReadWriteDetachedEdgeAsReference() throws Exception {
+        final Vertex v1 = graph.addVertex(T.label, "person");
+        final Vertex v2 = graph.addVertex(T.label, "person");
+        final Edge e = DetachedFactory.detach(v1.addEdge("friend", v2, "weight", 0.5d, "acl", "rw"), false);
+
+        assertEdge(v1, v2, e, false);
+    }
+
+    private void assertEdge(final Vertex v1, final Vertex v2, final Edge e, final boolean assertProperties) throws IOException {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            writer.writeEdge(os, e);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphReader reader = readerMaker.apply(graph);
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readEdge(bais, edge -> {
+                    final Edge detachedEdge = (Edge) edge;
+                    assertEquals(e.id(), assertIdDirectly ? detachedEdge.id() : graph.edges(detachedEdge.id().toString()).next().id());
+                    assertEquals(v1.id(), assertIdDirectly ? detachedEdge.outVertex().id() : graph.vertices(detachedEdge.outVertex().id().toString()).next().id());
+                    assertEquals(v2.id(), assertIdDirectly ? detachedEdge.inVertex().id() : graph.vertices(detachedEdge.inVertex().id().toString()).next().id());
+                    assertEquals(v1.label(), detachedEdge.outVertex().label());
+                    assertEquals(v2.label(), detachedEdge.inVertex().label());
+                    assertEquals(e.label(), detachedEdge.label());
+
+                    if (assertProperties) {
+                        assertEquals(assertDouble ? 0.5d : 0.5f, e.properties("weight").next().value());
+                        assertEquals("rw", e.properties("acl").next().value());
+                    } else {
+                        assertEquals(e.keys().size(), IteratorUtils.count(detachedEdge.properties()));
+                    }
+
+                    called.set(true);
+                    return null;
+                });
+            }
+
+            assertTrue(called.get());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoGraphTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoGraphTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoGraphTest.java
new file mode 100644
index 0000000..bc1296a
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoGraphTest.java
@@ -0,0 +1,226 @@
+/*
+ * 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;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.FeatureRequirement;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.TestHelper;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.util.Arrays;
+
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assume.assumeThat;
+
+/**
+ * Tests for all IO implementations that are specific to reading and writing of a {@link Graph}.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class IoGraphTest extends AbstractGremlinTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"graphml", IoCore.graphml(), false, true, ".xml"},
+                {"graphson", IoCore.graphson(), true, true, ".json"},
+                {"gryo", IoCore.gryo(), false, false, ".kryo"}
+        });
+    }
+
+    @Parameterized.Parameter(value = 0)
+    public String ioType;
+
+    @Parameterized.Parameter(value = 1)
+    public Io.Builder ioBuilderToTest;
+
+    @Parameterized.Parameter(value = 2)
+    public boolean assertDouble;
+
+    @Parameterized.Parameter(value = 3)
+    public boolean lossyForId;
+
+    @Parameterized.Parameter(value = 4)
+    public String fileExtension;
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    public void shouldReadWriteClassic() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = graph.io(ioBuilderToTest).writer().create();
+            writer.writeGraph(os, graph);
+
+            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.CLASSIC);
+            graphProvider.clear(configuration);
+            final Graph g1 = graphProvider.openTestGraph(configuration);
+            final GraphReader reader = graph.io(ioBuilderToTest).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readGraph(bais, g1);
+            }
+
+            IoTest.assertClassicGraph(g1, assertDouble, lossyForId);
+
+            graphProvider.clear(g1, configuration);
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    public void shouldReadWriteClassicToFileWithHelpers() throws Exception {
+        final File f = TestHelper.generateTempFile(this.getClass(), name.getMethodName(), fileExtension);
+        try {
+            graph.io(ioBuilderToTest).writeGraph(f.getAbsolutePath());
+
+            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
+            final Graph g1 = graphProvider.openTestGraph(configuration);
+            g1.io(ioBuilderToTest).readGraph(f.getAbsolutePath());
+
+            IoTest.assertClassicGraph(g1, assertDouble, lossyForId);
+
+            graphProvider.clear(g1, configuration);
+        } catch (Exception ex) {
+            f.delete();
+            throw ex;
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CLASSIC)
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    public void shouldMigrateClassicGraph() throws Exception {
+        final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), null);
+        graphProvider.clear(configuration);
+        final Graph g1 = graphProvider.openTestGraph(configuration);
+
+        final GraphReader reader = graph.io(ioBuilderToTest).reader().create();
+        final GraphWriter writer = graph.io(ioBuilderToTest).writer().create();
+
+        GraphMigrator.migrateGraph(graph, g1, reader, writer);
+
+        IoTest.assertClassicGraph(g1, assertDouble, lossyForId);
+
+        graphProvider.clear(g1, configuration);
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    public void shouldReadWriteModern() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = graph.io(ioBuilderToTest).writer().create();
+            writer.writeGraph(os, graph);
+
+            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
+            graphProvider.clear(configuration);
+            final Graph g1 = graphProvider.openTestGraph(configuration);
+            final GraphReader reader = graph.io(ioBuilderToTest).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readGraph(bais, g1);
+            }
+
+            // modern uses double natively so always assert as such
+            IoTest.assertModernGraph(g1, true, lossyForId);
+
+            graphProvider.clear(g1, configuration);
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    public void shouldReadWriteModernToFileWithHelpers() throws Exception {
+        final File f = TestHelper.generateTempFile(this.getClass(), name.getMethodName(), fileExtension);
+        try {
+            graph.io(ioBuilderToTest).writeGraph(f.getAbsolutePath());
+
+            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
+            final Graph g1 = graphProvider.openTestGraph(configuration);
+            g1.io(ioBuilderToTest).readGraph(f.getAbsolutePath());
+
+            // modern uses double natively so always assert as such
+            IoTest.assertModernGraph(g1, true, lossyForId);
+
+            graphProvider.clear(g1, configuration);
+        } catch (Exception ex) {
+            f.delete();
+            throw ex;
+        }
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    public void shouldMigrateModernGraph() throws Exception {
+        final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.MODERN);
+        graphProvider.clear(configuration);
+        final Graph g1 = graphProvider.openTestGraph(configuration);
+
+        final GraphReader reader = graph.io(ioBuilderToTest).reader().create();
+        final GraphWriter writer = graph.io(ioBuilderToTest).writer().create();
+
+        GraphMigrator.migrateGraph(graph, g1, reader, writer);
+
+        IoTest.assertModernGraph(g1, true, lossyForId);
+
+        graphProvider.clear(g1, configuration);
+    }
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CREW)
+    @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
+    @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
+    public void shouldReadWriteCrewToGryo() throws Exception {
+        assumeThat("GraphML does not suppport multi/metaproperties", ioType, not("graphml"));
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+
+            final GraphWriter writer = graph.io(ioBuilderToTest).writer().create();
+            writer.writeGraph(os, graph);
+
+            final Configuration configuration = graphProvider.newGraphConfiguration("readGraph", this.getClass(), name.getMethodName(), LoadGraphWith.GraphData.CREW);
+            graphProvider.clear(configuration);
+            final Graph g1 = graphProvider.openTestGraph(configuration);
+
+            final GraphReader reader = graph.io(ioBuilderToTest).reader().create();
+            try (final ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray())) {
+                reader.readGraph(bais, g1);
+            }
+
+            IoTest.assertCrewGraph(g1, lossyForId);
+
+            graphProvider.clear(g1, configuration);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/3ca54a62/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoPropertyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoPropertyTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoPropertyTest.java
new file mode 100644
index 0000000..4077f23
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoPropertyTest.java
@@ -0,0 +1,150 @@
+/*
+ * 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;
+
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class IoPropertyTest extends AbstractGremlinTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"graphson", false, false,
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.graphson()).reader().create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().create()},
+                {"graphson-embedded", true, true,
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.graphson()).reader().mapper(g.io(IoCore.graphson()).mapper().embedTypes(true).create()).create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.graphson()).writer().mapper(g.io(IoCore.graphson()).mapper().embedTypes(true).create()).create()},
+                {"gryo", true, true,
+                        (Function<Graph, GraphReader>) g -> g.io(IoCore.gryo()).reader().create(),
+                        (Function<Graph, GraphWriter>) g -> g.io(IoCore.gryo()).writer().create()}
+        });
+    }
+
+    @Parameterized.Parameter(value = 0)
+    public String ioType;
+
+    @Parameterized.Parameter(value = 1)
+    public boolean assertIdDirectly;
+
+    @Parameterized.Parameter(value = 2)
+    public boolean assertDouble;
+
+    @Parameterized.Parameter(value = 3)
+    public Function<Graph, GraphReader> readerMaker;
+
+    @Parameterized.Parameter(value = 4)
+    public Function<Graph, GraphWriter> writerMaker;
+
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.CREW)
+    public void shouldReadWriteVertexPropertyWithMetaProperties() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+
+            // select any vertexproperty that has both start/end time
+            final VertexProperty p = (VertexProperty) g.V(convertToVertexId("marko")).properties("location").as("p").has("endTime").select("p").next();
+            writer.writeVertexProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphReader reader = readerMaker.apply(graph);
+            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 shouldReadWriteVertexPropertyNoMetaProperties() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            final VertexProperty p = g.V(convertToVertexId("marko")).next().property("name");
+            writer.writeVertexProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphReader reader = readerMaker.apply(graph);
+            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.MODERN)
+    public void shouldReadWritePropertyGraphSON() throws Exception {
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            final GraphWriter writer = writerMaker.apply(graph);
+            final Property p = g.E(convertToEdgeId("marko", "knows", "vadas")).next().property("weight");
+            writer.writeProperty(os, p);
+
+            final AtomicBoolean called = new AtomicBoolean(false);
+            final GraphReader reader = readerMaker.apply(graph);
+            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());
+        }
+    }
+}