/*
 * 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.Direction;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Graph.Features.EdgePropertyFeatures;
import org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures;
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.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.GraphSONResourceAccess;
import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion;
import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONWriter;
import org.apache.tinkerpop.gremlin.structure.io.graphson.LegacyGraphSONReader;
import org.apache.tinkerpop.gremlin.structure.io.graphson.TypeInfo;
import org.apache.tinkerpop.gremlin.structure.io.util.CustomId;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.List;
import java.util.UUID;

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.FEATURE_BOOLEAN_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures.FEATURE_DOUBLE_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures.FEATURE_FLOAT_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures.FEATURE_INTEGER_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures.FEATURE_LONG_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures.FEATURE_STRING_VALUES;
import static org.apache.tinkerpop.gremlin.structure.io.IoCore.graphson;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeThat;

/**
 * @author Joshua Shinavier (http://fortytwo.net)
 * @author Stephen Mallette (http://stephen.genoprime.com)
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 */
@RunWith(Enclosed.class)
public class IoTest {
    private static final Logger logger = LoggerFactory.getLogger(IoTest.class);

    private static final String CLASSIC_GRAPH_WITH_COLOR = "<?xml version=\"1.0\" ?>\n" +
            "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.1/graphml.xsd\">\n" +
            "    <key id=\"age\" for=\"node\" attr.name=\"age\" attr.type=\"int\"></key>\n" +
            "    <key id=\"colorV\" for=\"node\" attr.name=\"color\" attr.type=\"string\"></key>\n" +
            "    <key id=\"labelV\" for=\"node\" attr.name=\"labelV\" attr.type=\"string\"></key>\n" +
            "    <key id=\"lang\" for=\"node\" attr.name=\"lang\" attr.type=\"string\"></key>\n" +
            "    <key id=\"name\" for=\"node\" attr.name=\"name\" attr.type=\"string\"></key>\n" +
            "    <key id=\"colorE\" for=\"edge\" attr.name=\"color\" attr.type=\"string\"></key>\n" +
            "    <key id=\"labelE\" for=\"edge\" attr.name=\"labelE\" attr.type=\"string\"></key>\n" +
            "    <key id=\"weight\" for=\"edge\" attr.name=\"weight\" attr.type=\"float\"></key>\n" +
            "    <graph id=\"G\" edgedefault=\"directed\">\n" +
            "        <node id=\"1\">\n" +
            "            <data key=\"labelV\">vertex</data>\n" +
            "            <data key=\"age\">29</data>\n" +
            "            <data key=\"colorV\">#6495ed</data>\n" +
            "            <data key=\"name\">marko</data>\n" +
            "        </node>\n" +
            "        <node id=\"2\">\n" +
            "            <data key=\"labelV\">vertex</data>\n" +
            "            <data key=\"age\">27</data>\n" +
            "            <data key=\"colorV\">#6495ed</data>\n" +
            "            <data key=\"name\">vadas</data>\n" +
            "        </node>\n" +
            "        <node id=\"3\">\n" +
            "            <data key=\"labelV\">vertex</data>\n" +
            "            <data key=\"lang\">java</data>\n" +
            "            <data key=\"colorV\">#6495ed</data>\n" +
            "            <data key=\"name\">lop</data>\n" +
            "        </node>\n" +
            "        <node id=\"4\">\n" +
            "            <data key=\"labelV\">vertex</data>\n" +
            "            <data key=\"age\">32</data>\n" +
            "            <data key=\"colorV\">#6495ed</data>\n" +
            "            <data key=\"name\">josh</data>\n" +
            "        </node>\n" +
            "        <node id=\"5\">\n" +
            "            <data key=\"labelV\">vertex</data>\n" +
            "            <data key=\"lang\">java</data>\n" +
            "            <data key=\"colorV\">#6495ed</data>\n" +
            "            <data key=\"name\">ripple</data>\n" +
            "        </node>\n" +
            "        <node id=\"6\">\n" +
            "            <data key=\"labelV\">vertex</data>\n" +
            "            <data key=\"age\">35</data>\n" +
            "            <data key=\"colorV\">#6495ed</data>\n" +
            "            <data key=\"name\">peter</data>\n" +
            "        </node>\n" +
            "        <edge id=\"10\" source=\"4\" target=\"5\">\n" +
            "            <data key=\"labelE\">created</data>\n" +
            "            <data key=\"colorE\">#ee0000</data>\n" +
            "            <data key=\"weight\">1.0</data>\n" +
            "        </edge>\n" +
            "        <edge id=\"11\" source=\"4\" target=\"3\">\n" +
            "            <data key=\"labelE\">created</data>\n" +
            "            <data key=\"colorE\">#ee0000</data>\n" +
            "            <data key=\"weight\">0.4</data>\n" +
            "        </edge>\n" +
            "        <edge id=\"12\" source=\"6\" target=\"3\">\n" +
            "            <data key=\"labelE\">created</data>\n" +
            "            <data key=\"colorE\">#ee0000</data>\n" +
            "            <data key=\"weight\">0.2</data>\n" +
            "        </edge>\n" +
            "        <edge id=\"7\" source=\"1\" target=\"2\">\n" +
            "            <data key=\"labelE\">knows</data>\n" +
            "            <data key=\"colorE\">#ee0000</data>\n" +
            "            <data key=\"weight\">0.5</data>\n" +
            "        </edge>\n" +
            "        <edge id=\"8\" source=\"1\" target=\"4\">\n" +
            "            <data key=\"labelE\">knows</data>\n" +
            "            <data key=\"colorE\">#ee0000</data>\n" +
            "            <data key=\"weight\">1.0</data>\n" +
            "        </edge>\n" +
            "        <edge id=\"9\" source=\"1\" target=\"3\">\n" +
            "            <data key=\"labelE\">created</data>\n" +
            "            <data key=\"colorE\">#ee0000</data>\n" +
            "            <data key=\"weight\">0.4</data>\n" +
            "        </edge>\n" +
            "    </graph>\n" +
            "</graphml>";

    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);
        }

        @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 shouldReadGraphMLWithNoEdgeLabels() throws IOException {
            readGraphMLIntoGraph(graph, "tinkerpop-no-edge-labels.xml");
            assertNoEdgeGraph(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 shouldReadGraphMLWithAllSupportedDataTypes() throws IOException {
            final GraphReader reader = GraphMLReader.build().create();
            try (final InputStream stream = getResourceAsStream(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
        @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 shouldReadGraphMLWithoutStrictOption() throws IOException {
            final GraphReader reader = GraphMLReader.build().strict(false).create();
            try (final InputStream stream = getResourceAsStream(GraphMLResourceAccess.class, "graph-types-bad.xml")) {
                reader.readGraph(stream, graph);
            }

            final Vertex v = graph.vertices().next();
            assertFalse(v.values("d").hasNext());
            assertEquals("some-string", v.<String>value("s"));
            assertFalse(v.values("i").hasNext());
            assertEquals(false, v.<Boolean>value("b"));
            assertFalse(v.values("f").hasNext());
            assertFalse(v.values("l").hasNext());
            assertEquals("junk", v.<String>value("n"));
        }

        @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)
        public void shouldReadGraphMLWithoutEdgeIds() throws IOException {
            final GraphReader reader = GraphMLReader.build().strict(false).create();
            try (final InputStream stream = getResourceAsStream(GraphMLResourceAccess.class, "graph-no-edge-ids.xml")) {
                reader.readGraph(stream, graph);
            }
            assertEquals(1, IteratorUtils.count(graph.edges()));
            assertEquals(2, IteratorUtils.count(graph.vertices()));
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_REMOVE_EDGES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_REMOVE_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 = EdgePropertyFeatures.class, feature = EdgePropertyFeatures.FEATURE_STRING_VALUES)
        public void shouldReadGraphMLWithCommonVertexAndEdgePropertyNames() throws IOException {
            final GraphReader reader = GraphMLReader.build().create();
            try (final InputStream stream = new ByteArrayInputStream(CLASSIC_GRAPH_WITH_COLOR.getBytes("UTF-8"))) {
                reader.readGraph(stream, graph);
            }

            // there is also a "color" property on this dataset that is on both edges and vertices
            graph.vertices().forEachRemaining(v -> assertEquals("#6495ed", v.value("color")));
            graph.edges().forEachRemaining(e -> assertEquals("#ee0000", e.value("color")));

            final GraphWriter writer = GraphMLWriter.build().create();
            try (final OutputStream out = new ByteArrayOutputStream()) {
                writer.writeGraph(out, graph);

                graph.vertices().forEachRemaining(Element::remove);
                try (final InputStream stream = new ByteArrayInputStream(((ByteArrayOutputStream) out).toByteArray())) {
                    reader.readGraph(stream, graph);
                }

                // there is also a "color" property on this dataset that is on both edges and vertices
                graph.vertices().forEachRemaining(v -> assertEquals("#6495ed", v.value("color")));
                graph.edges().forEachRemaining(e -> assertEquals("#ee0000", e.value("color")));
            }
        }

        @Test(expected = NumberFormatException.class)
        @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 shouldReadGraphMLWithStrictOption() throws IOException {
            final GraphReader reader = GraphMLReader.build().strict(true).create();
            try (final InputStream stream = getResourceAsStream(GraphMLResourceAccess.class, "graph-types-bad.xml")) {
                reader.readGraph(stream, graph);
            }
        }

        /**
         * 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(getResourceAsStream(GraphMLResourceAccess.class, "tinkerpop-classic-normalized.xml"));
                assertEquals(expected.replace("\n", "").replace("\r", ""), bos.toString().replace("\n", "").replace("\r", ""));
            }
        }

        @Test
        @LoadGraphWith(LoadGraphWith.GraphData.CREW)
        public void shouldNotWriteGraphMLFromGraphWithMultiProperties() throws Exception {
            try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
                final GraphMLWriter w = GraphMLWriter.build().create();
                w.writeGraph(bos, graph);
                fail("Should not be able to write multi-properties to GraphML");
            } catch (IllegalStateException iae) {
                assertThat(iae.getMessage(), containsString("multi-properties are not directly supported by GraphML format"));
            }
        }

        /**
         * 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 {
            assumeThat("GraphML web site is down so XSD cannot be retrieved", is(isGraphMLXSDPresent()));

            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);
            }

            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.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = FEATURE_STRING_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldReadWriteSelfLoopingEdges() throws Exception {
            final Graph source = graph;
            final Vertex v1 = source.addVertex();
            final Vertex v2 = source.addVertex();
            v1.addEdge("CONTROL", v2);
            v1.addEdge("SELFLOOP", v1);

            final Configuration targetConf = graphProvider.newGraphConfiguration("target", this.getClass(), name.getMethodName(), null);
            final Graph target = graphProvider.openTestGraph(targetConf);
            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                source.io(IoCore.graphml()).writer().create().writeGraph(os, source);
                try (ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray())) {
                    target.io(IoCore.graphml()).reader().create().readGraph(is, target);
                }
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }

            assertEquals(IteratorUtils.count(source.vertices()), IteratorUtils.count(target.vertices()));
            assertEquals(IteratorUtils.count(source.edges()), IteratorUtils.count(target.edges()));
        }

        @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 shouldTransformGraphMLV2ToV3ViaXSLT() throws Exception {
            final InputStream stylesheet = Thread.currentThread().getContextClassLoader().getResourceAsStream("tp2-to-tp3-graphml.xslt");
            final InputStream datafile = getResourceAsStream(GraphMLResourceAccess.class, "tinkerpop-classic-tp2.xml");
            final ByteArrayOutputStream output = new ByteArrayOutputStream();

            final TransformerFactory tFactory = TransformerFactory.newInstance();
            final StreamSource stylesource = new StreamSource(stylesheet);
            final Transformer transformer = tFactory.newTransformer(stylesource);

            final StreamSource source = new StreamSource(datafile);
            final StreamResult result = new StreamResult(output);
            transformer.transform(source, result);

            final GraphReader reader = GraphMLReader.build().create();
            reader.readGraph(new ByteArrayInputStream(output.toByteArray()), graph);
            assertClassicGraph(graph, false, true);
        }

        private boolean isGraphMLXSDPresent() {
            // when the graphml website goes down then tests won't pass - this allows the tests that rely on this
            // resource to conditionally run
            try {
                new URL("http://graphml.graphdrawing.org/xmlns/1.1/graphml-structure.xsd").openConnection().connect();
                return true;
            } catch (Exception ex) {
                return false;
            }
        }
    }

    public static final class GryoTest extends AbstractGremlinTest {

        @Test
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = FEATURE_STRING_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldReadWriteSelfLoopingEdges() {
            final Graph source = graph;
            final Vertex v1 = source.addVertex();
            final Vertex v2 = source.addVertex();
            v1.addEdge("CONTROL", v2);
            v1.addEdge("SELFLOOP", v1);

            final Configuration targetConf = graphProvider.newGraphConfiguration("target", this.getClass(), name.getMethodName(), null);
            final Graph target = graphProvider.openTestGraph(targetConf);
            ;
            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                source.io(IoCore.gryo()).writer().create().writeGraph(os, source);
                try (ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray())) {
                    target.io(IoCore.gryo()).reader().create().readGraph(is, target);
                }
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }

            assertEquals(IteratorUtils.count(source.vertices()), IteratorUtils.count(target.vertices()));
            assertEquals(IteratorUtils.count(source.edges()), IteratorUtils.count(target.edges()));
        }
    }

    public static final class GraphSONTest extends AbstractGremlinTest {
        private Io.Builder<GraphSONIo> graphson;

        @Before
        public void setupBeforeEachTest() {
            graphson = graphson();
        }

        /**
         * 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().version(GraphSONVersion.V1_0).normalize(true).create();
                final GraphSONWriter w = graph.io(graphson).writer().mapper(mapper).create();
                w.writeGraph(bos, graph);

                final String expected = streamToString(getResourceAsStream(GraphSONResourceAccess.class, "tinkerpop-classic-normalized-v1d0.json"));
                assertEquals(expected.replace("\n", "").replace("\r", ""), bos.toString().replace("\n", "").replace("\r", ""));
            }
        }

        @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 shouldReadWriteModernWrappedInJsonObject() throws Exception {
            final GraphSONMapper mapper = graph.io(graphson).mapper().version(GraphSONVersion.V1_0).create();
            try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                final GraphWriter writer = graph.io(graphson()).writer().wrapAdjacencyList(true).mapper(mapper).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(graphson()).reader().mapper(mapper).unwrapAdjacencyList(true).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, true);

                graphProvider.clear(g1, configuration);
            }
        }

        /**
         * This is just a serialization check for JSON.
         */
        @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.CustomIdJacksonSerializerV1d0());
            final GraphWriter writer = graph.io(graphson).writer().mapper(
                    graph.io(graphson).mapper().version(GraphSONVersion.V1_0).addCustomModule(module).typeInfo(TypeInfo.PARTIAL_TYPES).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());

                // 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);

                try (final InputStream is = new ByteArrayInputStream(baos.toByteArray())) {
                    final GraphReader reader = graph.io(graphson).reader()
                            .mapper(graph.io(graphson).mapper().version(GraphSONVersion.V1_0).typeInfo(TypeInfo.PARTIAL_TYPES).addCustomModule(module).create()).create();
                    reader.readGraph(is, g2);
                }

                final Vertex v2 = g2.vertices().next();
                final CustomId customId = (CustomId) v2.id();
                assertEquals(id, customId.getElementId());
                assertEquals("vertex", customId.getCluster());

                // need to manually close the "g2" instance
                graphProvider.clear(g2, configuration);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = FEATURE_STRING_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldReadWriteSelfLoopingEdges() throws Exception {
            final GraphSONMapper mapper = graph.io(graphson).mapper().version(GraphSONVersion.V1_0).create();
            final Graph source = graph;
            final Vertex v1 = source.addVertex();
            final Vertex v2 = source.addVertex();
            v1.addEdge("CONTROL", v2);
            v1.addEdge("SELFLOOP", v1);

            final Configuration targetConf = graphProvider.newGraphConfiguration("target", this.getClass(), name.getMethodName(), null);
            final Graph target = graphProvider.openTestGraph(targetConf);
            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                source.io(IoCore.graphson()).writer().mapper(mapper).create().writeGraph(os, source);
                try (ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray())) {
                    target.io(IoCore.graphson()).reader().mapper(mapper).create().readGraph(is, target);
                }
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }

            assertEquals(IteratorUtils.count(source.vertices()), IteratorUtils.count(target.vertices()));
            assertEquals(IteratorUtils.count(source.edges()), IteratorUtils.count(target.edges()));
        }
    }

    public static final class GraphSONLegacyTest 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 shouldReadLegacyGraphSON() throws IOException {
            final GraphReader reader = LegacyGraphSONReader.build().create();
            try (final InputStream stream = getResourceAsStream(GraphSONResourceAccess.class, "tinkerpop-classic-legacy.json")) {
                reader.readGraph(stream, graph);
            }

            // the id is lossy in migration because TP2 treated ID as String
            assertClassicGraph(graph, false, true);
        }
    }

    public static final class GraphSONV2D0Test extends AbstractGremlinTest {
        private Io.Builder<GraphSONIo> graphson;

        @Before
        public void setupBeforeEachTest() {
            graphson = graphson();
        }

        /**
         * 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().version(GraphSONVersion.V2_0).typeInfo(TypeInfo.NO_TYPES).normalize(true).create();
                final GraphSONWriter w = graph.io(graphson).writer().mapper(mapper).create();
                w.writeGraph(bos, graph);

                final String expected = streamToString(getResourceAsStream(GraphSONResourceAccess.class, "tinkerpop-classic-normalized-v2d0.json"));
                assertEquals(expected.replace("\n", "").replace("\r", ""), bos.toString().replace("\n", "").replace("\r", ""));
            }
        }

        @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 shouldReadWriteModernWrappedInJsonObject() throws Exception {
            final GraphSONMapper mapper = graph.io(graphson).mapper().version(GraphSONVersion.V2_0).create();
            try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                final GraphWriter writer = graph.io(graphson()).writer().wrapAdjacencyList(true).mapper(mapper).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(graphson()).reader().mapper(mapper).unwrapAdjacencyList(true).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, true);

                graphProvider.clear(g1, configuration);
            }
        }

        /**
         * This is just a serialization check for JSON.
         */
        @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 CustomId.CustomIdTinkerPopJacksonModuleV2d0();
            final GraphWriter writer = graph.io(graphson).writer().mapper(
                    graph.io(graphson).mapper().version(GraphSONVersion.V2_0).addCustomModule(module).create()).create();

            try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                writer.writeGraph(baos, graph);

                // 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);

                try (final InputStream is = new ByteArrayInputStream(baos.toByteArray())) {
                    final GraphReader reader = graph.io(graphson).reader()
                            .mapper(graph.io(graphson).mapper().version(GraphSONVersion.V2_0).addCustomModule(module).create()).create();
                    reader.readGraph(is, g2);
                }

                final Vertex v2 = g2.vertices().next();
                final CustomId customId = (CustomId) v2.id();
                assertEquals(id, customId.getElementId());
                assertEquals("vertex", customId.getCluster());

                // need to manually close the "g2" instance
                graphProvider.clear(g2, configuration);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = FEATURE_STRING_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldReadWriteSelfLoopingEdges() throws Exception {
            final GraphSONMapper mapper = graph.io(graphson).mapper().version(GraphSONVersion.V2_0).create();
            final Graph source = graph;
            final Vertex v1 = source.addVertex();
            final Vertex v2 = source.addVertex();
            v1.addEdge("CONTROL", v2);
            v1.addEdge("SELFLOOP", v1);

            final Configuration targetConf = graphProvider.newGraphConfiguration("target", this.getClass(), name.getMethodName(), null);
            final Graph target = graphProvider.openTestGraph(targetConf);
            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                source.io(IoCore.graphson()).writer().mapper(mapper).create().writeGraph(os, source);
                try (ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray())) {
                    target.io(IoCore.graphson()).reader().mapper(mapper).create().readGraph(is, target);
                }
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }

            assertEquals(IteratorUtils.count(source.vertices()), IteratorUtils.count(target.vertices()));
            assertEquals(IteratorUtils.count(source.edges()), IteratorUtils.count(target.edges()));
        }
    }

    public static final class GraphSONV3D0Test extends AbstractGremlinTest {
        private Io.Builder<GraphSONIo> graphson;

        @Before
        public void setupBeforeEachTest() {
            graphson = graphson();
        }

        /**
         * 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().version(GraphSONVersion.V3_0).normalize(true).create();
                final GraphSONWriter w = graph.io(graphson).writer().mapper(mapper).create();
                w.writeGraph(bos, graph);

                final String expected = streamToString(getResourceAsStream(GraphSONResourceAccess.class, "tinkerpop-classic-normalized-v3d0.json"));
                assertEquals(expected.replace("\n", "").replace("\r", ""), bos.toString().replace("\n", "").replace("\r", ""));
            }
        }

        @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 shouldReadWriteModernWrappedInJsonObject() throws Exception {
            final GraphSONMapper mapper = graph.io(graphson).mapper().version(GraphSONVersion.V3_0).create();
            try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                final GraphWriter writer = graph.io(graphson()).writer().wrapAdjacencyList(true).mapper(mapper).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(graphson()).reader().mapper(mapper).unwrapAdjacencyList(true).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, true);

                graphProvider.clear(g1, configuration);
            }
        }

        /**
         * This is just a serialization check for JSON.
         */
        @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 CustomId.CustomIdTinkerPopJacksonModuleV3d0();
            final GraphWriter writer = graph.io(graphson).writer().mapper(
                    graph.io(graphson).mapper().version(GraphSONVersion.V3_0).addCustomModule(module).create()).create();

            try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                writer.writeGraph(baos, graph);

                // 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);

                try (final InputStream is = new ByteArrayInputStream(baos.toByteArray())) {
                    final GraphReader reader = graph.io(graphson).reader()
                            .mapper(graph.io(graphson).mapper().version(GraphSONVersion.V3_0).addCustomModule(module).create()).create();
                    reader.readGraph(is, g2);
                }

                final Vertex v2 = g2.vertices().next();
                final CustomId customId = (CustomId) v2.id();
                assertEquals(id, customId.getElementId());
                assertEquals("vertex", customId.getCluster());

                // need to manually close the "g2" instance
                graphProvider.clear(g2, configuration);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = EdgePropertyFeatures.class, feature = FEATURE_STRING_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldReadWriteSelfLoopingEdges() throws Exception {
            final GraphSONMapper mapper = graph.io(graphson).mapper().version(GraphSONVersion.V3_0).create();
            final Graph source = graph;
            final Vertex v1 = source.addVertex();
            final Vertex v2 = source.addVertex();
            v1.addEdge("CONTROL", v2);
            v1.addEdge("SELFLOOP", v1);

            final Configuration targetConf = graphProvider.newGraphConfiguration("target", this.getClass(), name.getMethodName(), null);
            final Graph target = graphProvider.openTestGraph(targetConf);
            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                source.io(IoCore.graphson()).writer().mapper(mapper).create().writeGraph(os, source);
                try (ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray())) {
                    target.io(IoCore.graphson()).reader().mapper(mapper).create().readGraph(is, target);
                }
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }

            assertEquals(IteratorUtils.count(source.vertices()), IteratorUtils.count(target.vertices()));
            assertEquals(IteratorUtils.count(source.edges()), IteratorUtils.count(target.edges()));
        }
    }

    public static void assertCrewGraph(final Graph g1, final boolean lossyForId) {
        assertEquals(new Long(6), g1.traversal().V().count().next());
        assertEquals(new Long(14), g1.traversal().E().count().next());

        final Vertex v1 = (Vertex) g1.traversal().V().has("name", "marko").next();
        assertEquals("person", v1.label());
        assertEquals(2, v1.keys().size());
        assertEquals(4, (int) IteratorUtils.count(v1.properties("location")));
        v1.properties("location").forEachRemaining(vp -> {
            if (vp.value().equals("san diego")) {
                assertEquals(1997, (int) vp.value("startTime"));
                assertEquals(2001, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("santa cruz")) {
                assertEquals(2001, (int) vp.value("startTime"));
                assertEquals(2004, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("brussels")) {
                assertEquals(2004, (int) vp.value("startTime"));
                assertEquals(2005, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("santa fe")) {
                assertEquals(2005, (int) vp.value("startTime"));
                assertEquals(1, (int) IteratorUtils.count(vp.properties()));
            } else {
                fail("Found a value that should be there");
            }
        });
        assertId(g1, lossyForId, v1, 1);

        final List<Edge> v1Edges = IteratorUtils.list(v1.edges(Direction.BOTH));
        assertEquals(4, v1Edges.size());
        v1Edges.forEach(e -> {
            if (e.inVertex().value("name").equals("gremlin") && e.label().equals("develops")) {
                assertEquals(2009, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 13);
            } else if (e.inVertex().value("name").equals("tinkergraph") && e.label().equals("develops")) {
                assertEquals(2010, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 14);
            } else if (e.inVertex().value("name").equals("gremlin") && e.label().equals("uses")) {
                assertEquals(4, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 15);
            } else if (e.inVertex().value("name").equals("tinkergraph") && e.label().equals("uses")) {
                assertEquals(5, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 16);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v7 = (Vertex) g1.traversal().V().has("name", "stephen").next();
        assertEquals("person", v7.label());
        assertEquals(2, v7.keys().size());
        assertEquals(3, (int) IteratorUtils.count(v7.properties("location")));
        v7.properties("location").forEachRemaining(vp -> {
            if (vp.value().equals("centreville")) {
                assertEquals(1990, (int) vp.value("startTime"));
                assertEquals(2000, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("dulles")) {
                assertEquals(2000, (int) vp.value("startTime"));
                assertEquals(2006, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("purcellville")) {
                assertEquals(2006, (int) vp.value("startTime"));
                assertEquals(1, (int) IteratorUtils.count(vp.properties()));
            } else {
                fail("Found a value that should be there");
            }
        });
        assertId(g1, lossyForId, v7, 7);

        final List<Edge> v7Edges = IteratorUtils.list(v7.edges(Direction.BOTH));
        assertEquals(4, v7Edges.size());
        v7Edges.forEach(e -> {
            if (e.inVertex().value("name").equals("gremlin") && e.label().equals("develops")) {
                assertEquals(2010, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 17);
            } else if (e.inVertex().value("name").equals("tinkergraph") && e.label().equals("develops")) {
                assertEquals(2011, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 18);
            } else if (e.inVertex().value("name").equals("gremlin") && e.label().equals("uses")) {
                assertEquals(5, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 19);
            } else if (e.inVertex().value("name").equals("tinkergraph") && e.label().equals("uses")) {
                assertEquals(4, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 20);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v8 = (Vertex) g1.traversal().V().has("name", "matthias").next();
        assertEquals("person", v8.label());
        assertEquals(2, v8.keys().size());
        assertEquals(4, (int) IteratorUtils.count(v8.properties("location")));
        v8.properties("location").forEachRemaining(vp -> {
            if (vp.value().equals("bremen")) {
                assertEquals(2004, (int) vp.value("startTime"));
                assertEquals(2007, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("baltimore")) {
                assertEquals(2007, (int) vp.value("startTime"));
                assertEquals(2011, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("oakland")) {
                assertEquals(2011, (int) vp.value("startTime"));
                assertEquals(2014, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("seattle")) {
                assertEquals(2014, (int) vp.value("startTime"));
                assertEquals(1, (int) IteratorUtils.count(vp.properties()));
            } else {
                fail("Found a value that should be there");
            }
        });
        assertId(g1, lossyForId, v8, 8);

        final List<Edge> v8Edges = IteratorUtils.list(v8.edges(Direction.BOTH));
        assertEquals(3, v8Edges.size());
        v8Edges.forEach(e -> {
            if (e.inVertex().value("name").equals("gremlin") && e.label().equals("develops")) {
                assertEquals(2012, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 21);
            } else if (e.inVertex().value("name").equals("gremlin") && e.label().equals("uses")) {
                assertEquals(3, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 22);
            } else if (e.inVertex().value("name").equals("tinkergraph") && e.label().equals("uses")) {
                assertEquals(3, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 23);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v9 = (Vertex) g1.traversal().V().has("name", "daniel").next();
        assertEquals("person", v9.label());
        assertEquals(2, v9.keys().size());
        assertEquals(3, (int) IteratorUtils.count(v9.properties("location")));
        v9.properties("location").forEachRemaining(vp -> {
            if (vp.value().equals("spremberg")) {
                assertEquals(1982, (int) vp.value("startTime"));
                assertEquals(2005, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("kaiserslautern")) {
                assertEquals(2005, (int) vp.value("startTime"));
                assertEquals(2009, (int) vp.value("endTime"));
                assertEquals(2, (int) IteratorUtils.count(vp.properties()));
            } else if (vp.value().equals("aachen")) {
                assertEquals(2009, (int) vp.value("startTime"));
                assertEquals(1, (int) IteratorUtils.count(vp.properties()));
            } else {
                fail("Found a value that should be there");
            }
        });
        assertId(g1, lossyForId, v9, 9);

        final List<Edge> v9Edges = IteratorUtils.list(v9.edges(Direction.BOTH));
        assertEquals(2, v9Edges.size());
        v9Edges.forEach(e -> {
            if (e.inVertex().value("name").equals("gremlin") && e.label().equals("uses")) {
                assertEquals(5, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 24);
            } else if (e.inVertex().value("name").equals("tinkergraph") && e.label().equals("uses")) {
                assertEquals(3, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 25);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v10 = (Vertex) g1.traversal().V().has("name", "gremlin").next();
        assertEquals("software", v10.label());
        assertEquals(1, v10.keys().size());
        assertId(g1, lossyForId, v10, 10);

        final List<Edge> v10Edges = IteratorUtils.list(v10.edges(Direction.BOTH));
        assertEquals(8, v10Edges.size());
        v10Edges.forEach(e -> {
            if (e.outVertex().value("name").equals("marko") && e.label().equals("develops")) {
                assertEquals(2009, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 13);
            } else if (e.outVertex().value("name").equals("marko") && e.label().equals("uses")) {
                assertEquals(4, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 15);
            } else if (e.outVertex().value("name").equals("stephen") && e.label().equals("develops")) {
                assertEquals(2010, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 17);
            } else if (e.outVertex().value("name").equals("stephen") && e.label().equals("uses")) {
                assertEquals(5, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 19);
            } else if (e.outVertex().value("name").equals("matthias") && e.label().equals("develops")) {
                assertEquals(2012, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 21);
            } else if (e.outVertex().value("name").equals("matthias") && e.label().equals("uses")) {
                assertEquals(3, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 22);
            } else if (e.outVertex().value("name").equals("daniel") && e.label().equals("uses")) {
                assertEquals(5, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 24);
            } else if (e.inVertex().value("name").equals("tinkergraph") && e.label().equals("traverses")) {
                assertEquals(0, e.keys().size());
                assertId(g1, lossyForId, e, 26);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v11 = (Vertex) g1.traversal().V().has("name", "tinkergraph").next();
        assertEquals("software", v11.label());
        assertEquals(1, v11.keys().size());
        assertId(g1, lossyForId, v11, 11);

        final List<Edge> v11Edges = IteratorUtils.list(v11.edges(Direction.BOTH));
        assertEquals(7, v11Edges.size());
        v11Edges.forEach(e -> {
            if (e.outVertex().value("name").equals("marko") && e.label().equals("develops")) {
                assertEquals(2010, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 14);
            } else if (e.outVertex().value("name").equals("marko") && e.label().equals("uses")) {
                assertEquals(5, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 16);
            } else if (e.outVertex().value("name").equals("stephen") && e.label().equals("develops")) {
                assertEquals(2011, (int) e.value("since"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 18);
            } else if (e.outVertex().value("name").equals("stephen") && e.label().equals("uses")) {
                assertEquals(4, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 20);
            } else if (e.outVertex().value("name").equals("matthias") && e.label().equals("uses")) {
                assertEquals(3, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 23);
            } else if (e.outVertex().value("name").equals("daniel") && e.label().equals("uses")) {
                assertEquals(3, (int) e.value("skill"));
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 25);
            } else if (e.outVertex().value("name").equals("gremlin") && e.label().equals("traverses")) {
                assertEquals(0, e.keys().size());
                assertId(g1, lossyForId, e, 26);
            } else {
                fail("Edge not expected");
            }
        });
    }

    public static void assertClassicGraph(final Graph g1, final boolean assertDouble, final boolean lossyForId) {
        assertToyGraph(g1, assertDouble, lossyForId, false);
    }

    public static void assertNoEdgeGraph(final Graph g1, final boolean assertDouble, final boolean lossyForId) {
        assertEquals(2, IteratorUtils.count(g1.vertices()));
        assertEquals(1, IteratorUtils.count(g1.edges()));

        final Vertex v1 = g1.traversal().V().has("name", "marko").next();
        assertEquals(29, v1.<Integer>value("age").intValue());
        assertEquals(2, v1.keys().size());
        assertEquals(Vertex.DEFAULT_LABEL, v1.label());
        assertId(g1, lossyForId, v1, 1);

        final List<Edge> v1Edges = IteratorUtils.list(v1.edges(Direction.BOTH));
        assertEquals(1, v1Edges.size());
        v1Edges.forEach(e -> {
            if (e.inVertex().value("name").equals("vadas")) {
                assertEquals(Edge.DEFAULT_LABEL, e.label());
                if (assertDouble)
                    assertWeightLoosely(0.5d, e);
                else
                    assertWeightLoosely(0.5f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 7);
            } else {
                fail("Edge not expected");
            }
        });
    }

    public static void assertModernGraph(final Graph g1, final boolean assertDouble, final boolean lossyForId) {
        assertToyGraph(g1, assertDouble, lossyForId, true);
    }

    private static void assertToyGraph(final Graph g1, final boolean assertDouble, final boolean lossyForId, final boolean assertSpecificLabel) {
        assertEquals(6, IteratorUtils.count(g1.vertices()));
        assertEquals(6, IteratorUtils.count(g1.edges()));

        final Vertex v1 = g1.traversal().V().has("name", "marko").next();
        assertEquals(29, v1.<Integer>value("age").intValue());
        assertEquals(2, v1.keys().size());
        assertEquals(assertSpecificLabel ? "person" : Vertex.DEFAULT_LABEL, v1.label());
        assertId(g1, lossyForId, v1, 1);

        final List<Edge> v1Edges = IteratorUtils.list(v1.edges(Direction.BOTH));
        assertEquals(3, v1Edges.size());
        v1Edges.forEach(e -> {
            if (e.inVertex().value("name").equals("vadas")) {
                assertEquals("knows", e.label());
                if (assertDouble)
                    assertWeightLoosely(0.5d, e);
                else
                    assertWeightLoosely(0.5f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 7);
            } else if (e.inVertex().value("name").equals("josh")) {
                assertEquals("knows", e.label());
                if (assertDouble)
                    assertWeightLoosely(1.0, e);
                else
                    assertWeightLoosely(1.0f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 8);
            } else if (e.inVertex().value("name").equals("lop")) {
                assertEquals("created", e.label());
                if (assertDouble)
                    assertWeightLoosely(0.4d, e);
                else
                    assertWeightLoosely(0.4f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 9);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v2 = g1.traversal().V().has("name", "vadas").next();
        assertEquals(27, v2.<Integer>value("age").intValue());
        assertEquals(2, v2.keys().size());
        assertEquals(assertSpecificLabel ? "person" : Vertex.DEFAULT_LABEL, v2.label());
        assertId(g1, lossyForId, v2, 2);

        final List<Edge> v2Edges = IteratorUtils.list(v2.edges(Direction.BOTH));
        assertEquals(1, v2Edges.size());
        v2Edges.forEach(e -> {
            if (e.outVertex().value("name").equals("marko")) {
                assertEquals("knows", e.label());
                if (assertDouble)
                    assertWeightLoosely(0.5d, e);
                else
                    assertWeightLoosely(0.5f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 7);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v3 = g1.traversal().V().has("name", "lop").next();
        assertEquals("java", v3.<String>value("lang"));
        assertEquals(2, v2.keys().size());
        assertEquals(assertSpecificLabel ? "software" : Vertex.DEFAULT_LABEL, v3.label());
        assertId(g1, lossyForId, v3, 3);

        final List<Edge> v3Edges = IteratorUtils.list(v3.edges(Direction.BOTH));
        assertEquals(3, v3Edges.size());
        v3Edges.forEach(e -> {
            if (e.outVertex().value("name").equals("peter")) {
                assertEquals("created", e.label());
                if (assertDouble)
                    assertWeightLoosely(0.2d, e);
                else
                    assertWeightLoosely(0.2f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 12);
            } else if (e.outVertex().value("name").equals("josh")) {
                assertEquals("created", e.label());
                if (assertDouble)
                    assertWeightLoosely(0.4d, e);
                else
                    assertWeightLoosely(0.4f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 11);
            } else if (e.outVertex().value("name").equals("marko")) {
                assertEquals("created", e.label());
                if (assertDouble)
                    assertWeightLoosely(0.4d, e);
                else
                    assertWeightLoosely(0.4f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 9);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v4 = g1.traversal().V().has("name", "josh").next();
        assertEquals(32, v4.<Integer>value("age").intValue());
        assertEquals(2, v4.keys().size());
        assertEquals(assertSpecificLabel ? "person" : Vertex.DEFAULT_LABEL, v4.label());
        assertId(g1, lossyForId, v4, 4);

        final List<Edge> v4Edges = IteratorUtils.list(v4.edges(Direction.BOTH));
        assertEquals(3, v4Edges.size());
        v4Edges.forEach(e -> {
            if (e.inVertex().value("name").equals("ripple")) {
                assertEquals("created", e.label());
                if (assertDouble)
                    assertWeightLoosely(1.0d, e);
                else
                    assertWeightLoosely(1.0f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 10);
            } else if (e.inVertex().value("name").equals("lop")) {
                assertEquals("created", e.label());
                if (assertDouble)
                    assertWeightLoosely(0.4d, e);
                else
                    assertWeightLoosely(0.4f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 11);
            } else if (e.outVertex().value("name").equals("marko")) {
                assertEquals("knows", e.label());
                if (assertDouble)
                    assertWeightLoosely(1.0d, e);
                else
                    assertWeightLoosely(1.0f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 8);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v5 = g1.traversal().V().has("name", "ripple").next();
        assertEquals("java", v5.<String>value("lang"));
        assertEquals(2, v5.keys().size());
        assertEquals(assertSpecificLabel ? "software" : Vertex.DEFAULT_LABEL, v5.label());
        assertId(g1, lossyForId, v5, 5);

        final List<Edge> v5Edges = IteratorUtils.list(v5.edges(Direction.BOTH));
        assertEquals(1, v5Edges.size());
        v5Edges.forEach(e -> {
            if (e.outVertex().value("name").equals("josh")) {
                assertEquals("created", e.label());
                if (assertDouble)
                    assertWeightLoosely(1.0d, e);
                else
                    assertWeightLoosely(1.0f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 10);
            } else {
                fail("Edge not expected");
            }
        });

        final Vertex v6 = g1.traversal().V().has("name", "peter").next();
        assertEquals(35, v6.<Integer>value("age").intValue());
        assertEquals(2, v6.keys().size());
        assertEquals(assertSpecificLabel ? "person" : Vertex.DEFAULT_LABEL, v6.label());
        assertId(g1, lossyForId, v6, 6);

        final List<Edge> v6Edges = IteratorUtils.list(v6.edges(Direction.BOTH));
        assertEquals(1, v6Edges.size());
        v6Edges.forEach(e -> {
            if (e.inVertex().value("name").equals("lop")) {
                assertEquals("created", e.label());
                if (assertDouble)
                    assertWeightLoosely(0.2d, e);
                else
                    assertWeightLoosely(0.2f, e);
                assertEquals(1, e.keys().size());
                assertId(g1, lossyForId, e, 12);
            } else {
                fail("Edge not expected");
            }
        });
    }

    private static void assertWeightLoosely(final double expected, final Edge e) {
        try {
            assertEquals(expected, e.value("weight"), 0.0001d);
        } catch (Exception ex) {
            // for graphs that have strong typing via schema it is possible that a value that came across as graphson
            // with lossiness will end up having a value expected to double to be coerced to float by the underlying
            // graph.
            logger.warn("Attempting to assert weight as float for {} - if your graph is strongly typed from schema this is likely expected", e);
            assertEquals(new Double(expected).floatValue(), e.value("weight"), 0.0001f);
        }
    }

    private static void assertWeightLoosely(final float expected, final Edge e) {
        try {
            assertEquals(expected, e.value("weight"), 0.0001f);
        } catch (Exception ex) {
            // for graphs that have strong typing via schema it is possible that a value that came across as graphson
            // with lossiness will end up having a value expected to float to be coerced to double by the underlying
            // graph.
            logger.warn("Attempting to assert weight as double for {} - if your graph is strongly typed from schema this is likely expected", e);
            assertEquals(new Float(expected).doubleValue(), e.value("weight"), 0.0001d);
        }
    }

    private static void assertId(final Graph g, final boolean lossyForId, final Element e, final Object expected) {
        // it is possible that a Graph (e.g. elastic-gremlin) can supportUserSuppliedIds but internally
        // represent them as a value other than Numeric (which is what's in all of the test/toy data).
        // as we feature check for userSuppliedIds when asserting the identifier, we also ensure that
        // the id can be properly asserted for that Element before attempting to do so.  By asserting
        // at this level in this way, graphs can enjoy greater test coverage in IO.
        if ((e instanceof Vertex && g.features().vertex().supportsUserSuppliedIds() && g.features().vertex().supportsNumericIds())
                || (e instanceof Edge && g.features().edge().supportsUserSuppliedIds() && g.features().edge().supportsNumericIds())
                || (e instanceof VertexProperty && g.features().vertex().properties().supportsUserSuppliedIds()) && g.features().vertex().properties().supportsNumericIds()) {
            if (lossyForId)
                assertEquals(expected.toString(), e.id().toString());
            else
                assertEquals(expected, e.id());
        }
    }

    private static void validateXmlAgainstGraphMLXsd(final File file) throws Exception {
        final Source xmlFile = new StreamSource(file);
        final SchemaFactory schemaFactory = SchemaFactory
                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        final Schema schema = schemaFactory.newSchema(new StreamSource(getResourceAsStream(GraphMLResourceAccess.class, "graphml-1.1.xsd")));
        final Validator validator = schema.newValidator();
        validator.validate(xmlFile);
    }

    private static void readGraphMLIntoGraph(final Graph g, final String file) throws IOException {
        final GraphReader reader = GraphMLReader.build().create();
        try (final InputStream stream = getResourceAsStream( GraphMLResourceAccess.class, file )) {
            reader.readGraph(stream, g);
        }
    }

    public static InputStream getResourceAsStream(Class<?> resourceClass, final String file) {
      return IoTest.class.getResourceAsStream( "/"
                                               + resourceClass.getPackage().getName().replaceAll("\\.", "/")
                                               + "/"
                                               + file);
    }

    private static String streamToString(final InputStream in) throws IOException {
        final Writer writer = new StringWriter();
        final char[] buffer = new char[1024];
        try (final Reader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"))) {
            int n;
            while ((n = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, n);
            }
        }

        return writer.toString();
    }

}
