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

import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
import org.apache.tinkerpop.gremlin.ExceptionCoverage;
import org.apache.tinkerpop.gremlin.FeatureRequirement;
import org.apache.tinkerpop.gremlin.FeatureRequirementSet;
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.util.CustomId;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import static org.apache.tinkerpop.gremlin.structure.Graph.Features.DataTypeFeatures.FEATURE_BOOLEAN_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.DataTypeFeatures.FEATURE_DOUBLE_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.DataTypeFeatures.FEATURE_FLOAT_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.DataTypeFeatures.FEATURE_INTEGER_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.DataTypeFeatures.FEATURE_LONG_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.DataTypeFeatures.FEATURE_STRING_VALUES;
import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexFeatures.FEATURE_USER_SUPPLIED_IDS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
@RunWith(Enclosed.class)
public class VertexTest {

    public static class AddEdgeTest extends AbstractGremlinTest {
        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_NUMERIC_IDS)
        public void shouldAddEdgeWithUserSuppliedNumericId() {
            final Vertex v = graph.addVertex();
            v.addEdge("self", v, T.id, 1000L);
            tryCommit(graph, graph -> {
                final Edge e = graph.edges(1000L).next();
                assertEquals(1000L, e.id());
            });
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_STRING_IDS)
        public void shouldAddEdgeWithUserSuppliedStringId() {
            final Vertex v = graph.addVertex();
            v.addEdge("self", v, T.id, "1000");
            tryCommit(graph, graph -> {
                final Edge e = graph.edges("1000").next();
                assertEquals("1000", e.id());
            });
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_UUID_IDS)
        public void shouldAddEdgeWithUserSuppliedUuidId() {
            final UUID uuid = UUID.randomUUID();
            final Vertex v = graph.addVertex();
            v.addEdge("self", v, T.id, uuid);
            tryCommit(graph, graph -> {
                final Edge e = graph.edges(uuid).next();
                assertEquals(uuid, e.id());
            });
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ANY_IDS)
        public void shouldAddEdgeWithUserSuppliedAnyIdUsingUuid() {
            final UUID uuid = UUID.randomUUID();
            final Vertex v = graph.addVertex();
            v.addEdge("self", v, T.id, uuid);
            tryCommit(graph, graph -> {
                final Edge e = graph.edges(uuid).next();
                assertEquals(uuid, e.id());
            });
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ANY_IDS)
        public void shouldAddEdgeWithUserSuppliedAnyIdUsingString() {
            final UUID uuid = UUID.randomUUID();
            final Vertex v = graph.addVertex();
            v.addEdge("self", v, T.id, uuid.toString());
            tryCommit(graph, graph -> {
                final Edge e = graph.edges(uuid.toString()).next();
                assertEquals(uuid.toString(), e.id());
            });
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ANY_IDS)
        public void shouldAddEdgeWithUserSuppliedAnyIdUsingAnyObject() {
            final UUID uuid = UUID.randomUUID();

            // this is different from "FEATURE_CUSTOM_IDS" as TinkerGraph does not define a specific id class
            // (i.e. TinkerId) for the identifier.
            final CustomId customId = new CustomId("test", uuid);
            final Vertex v = graph.addVertex();
            v.addEdge("self", v, T.id, customId);
            tryCommit(graph, graph -> {
                final Edge e = graph.edges(customId).next();
                assertEquals(customId, e.id());
            });
        }
    }

    @ExceptionCoverage(exceptionClass = Edge.Exceptions.class, methods = {
            "userSuppliedIdsNotSupported"
    })
    @ExceptionCoverage(exceptionClass = Graph.Exceptions.class, methods = {
            "edgeWithIdAlreadyExists"
    })
    @ExceptionCoverage(exceptionClass = Element.Exceptions.class, methods = {
            "labelCanNotBeNull",
            "labelCanNotBeEmpty",
            "labelCanNotBeAHiddenKey"
    })
    public static class BasicVertexTest extends AbstractGremlinTest {
        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldValidateEquality() {
            final Vertex v1 = graph.addVertex();
            final Vertex v2 = graph.addVertex();

            assertEquals(v1, v1);
            assertEquals(v2, v2);
            assertNotEquals(v1, v2);
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldValidateIdEquality() {
            final Vertex v1 = graph.addVertex();
            final Vertex v2 = graph.addVertex();

            assertEquals(v1.id(), v1.id());
            assertEquals(v2.id(), v2.id());
            assertEquals(v1.id().toString(), v1.id().toString());
            assertEquals(v2.id().toString(), v2.id().toString());
            assertNotEquals(v1.id(), v2.id());
            assertNotEquals(v1.id().toString(), v2.id().toString());
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldHaveExceptionConsistencyWhenUsingNullVertexLabel() {
            try {
                graph.addVertex(T.label, null);
                fail("Call to Graph.addVertex() should throw an exception when label is null");
            } catch (Exception ex) {
                validateException(Element.Exceptions.labelCanNotBeNull(), ex);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldHaveExceptionConsistencyWhenUsingNullVertexLabelOnOverload() {
            try {
                graph.addVertex((String) null);
                fail("Call to Graph.addVertex() should throw an exception when label is null");
            } catch (Exception ex) {
                validateException(Element.Exceptions.labelCanNotBeNull(), ex);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldHaveExceptionConsistencyWhenUsingEmptyVertexLabel() {
            try {
                graph.addVertex(T.label, "");
                fail("Call to Graph.addVertex() should throw an exception when label is empty");
            } catch (Exception ex) {
                validateException(Element.Exceptions.labelCanNotBeEmpty(), ex);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldHaveExceptionConsistencyWhenUsingEmptyVertexLabelOnOverload() {
            try {
                graph.addVertex("");
                fail("Call to Graph.addVertex() should throw an exception when label is empty");
            } catch (Exception ex) {
                validateException(Element.Exceptions.labelCanNotBeEmpty(), ex);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldHaveExceptionConsistencyWhenUsingSystemVertexLabel() {
            final String label = Graph.Hidden.hide("systemLabel");
            try {
                graph.addVertex(T.label, label);
                fail("Call to Graph.addVertex() should throw an exception when label is a system key");
            } catch (Exception ex) {
                validateException(Element.Exceptions.labelCanNotBeAHiddenKey(label), ex);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldHaveExceptionConsistencyWhenUsingSystemVertexLabelOnOverload() {
            final String label = Graph.Hidden.hide("systemLabel");
            try {
                graph.addVertex(label);
                fail("Call to Graph.addVertex() should throw an exception when label is a system key");
            } catch (Exception ex) {
                validateException(Element.Exceptions.labelCanNotBeAHiddenKey(label), ex);
            }
        }

        @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.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_UPSERT, supported = false)
        public void shouldHaveExceptionConsistencyWhenAssigningSameIdOnEdge() {
            final Vertex v = graph.addVertex();
            final Object o = graphProvider.convertId("1", Edge.class);
            v.addEdge("self", v, T.id, o, "weight", 1);

            try {
                v.addEdge("self", v, T.id, o, "weight", 1);
                fail("Assigning the same ID to an Element should throw an exception");
            } catch (Exception ex) {
                validateException(Graph.Exceptions.edgeWithIdAlreadyExists(o), ex);
            }
        }

        @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.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_UPSERT)
        public void shouldUpsertWhenAssigningSameIdOnEdge() {
            final Vertex v = graph.addVertex();
            final Object o = graphProvider.convertId("1", Edge.class);
            v.addEdge("self", v, T.id, o, "weight", 1);
            tryCommit(graph, graph -> {
                final Edge e = graph.edges(o).next();
                assertEquals(o, e.id());
                assertEquals(1, (int) e.value("weight"));
                assertVertexEdgeCounts(graph, 1, 1);
            });

            v.addEdge("self", v, T.id, o, "weight", 2);
            tryCommit(graph, graph -> {
                final Edge e = graph.edges(o).next();
                assertEquals(o, e.id());
                assertEquals(2, (int) e.value("weight"));
                assertVertexEdgeCounts(graph, 1, 1);
            });
        }

        @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.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_USER_SUPPLIED_IDS, supported = false)
        public void shouldHaveExceptionConsistencyWhenIdNotSupportedForAddEdge() throws Exception {
            try {
                final Vertex v = this.graph.addVertex();
                v.addEdge("self", v, T.id, "");
                fail("Call to addEdge should have thrown an exception when ID was specified as it is not supported");
            } catch (Exception ex) {
                validateException(Edge.Exceptions.userSuppliedIdsNotSupported(), ex);
            }
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldHaveStandardStringRepresentation() {
            final Vertex v = graph.addVertex();
            assertEquals(StringFactory.vertexString(v), v.toString());
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY)
        @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
        public void shouldHaveStandardStringRepresentationWithProperties() {
            final Vertex v = graph.addVertex("name", "marko", "age", 34);
            assertEquals(StringFactory.vertexString(v), v.toString());
        }

        @Test
        @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
        public void shouldUseDefaultLabelIfNotSpecified() {
            final Vertex v = graph.addVertex("name", "marko");
            assertEquals(Vertex.DEFAULT_LABEL, v.label());
        }

        @Test
        @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
        public void shouldAddVertexWithLabel() {
            final Vertex v = graph.addVertex("person");
            this.tryCommit(graph, graph -> assertEquals("person", v.label()));
        }

        @Test
        @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_REMOVE_PROPERTY)
        public void shouldSupportBasicVertexManipulation() {
            // test property mutation behaviors
            final Vertex v = graph.addVertex("name", "marko", "age", 34);
            assertEquals(34, (int) v.value("age"));
            assertEquals("marko", v.<String>value("name"));
            assertEquals(34, (int) v.property("age").value());
            assertEquals("marko", v.<String>property("name").value());
            assertEquals(2, IteratorUtils.count(v.properties()));
            assertEquals(2, v.keys().size());
            assertTrue(v.keys().contains("name"));
            assertTrue(v.keys().contains("age"));
            assertFalse(v.keys().contains("location"));
            assertVertexEdgeCounts(graph, 1, 0);

            v.properties("name").forEachRemaining(Property::remove);
            v.property(VertexProperty.Cardinality.single, "name", "marko rodriguez");
            assertEquals(34, (int) v.value("age"));
            assertEquals("marko rodriguez", v.<String>value("name"));
            assertEquals(34, (int) v.property("age").value());
            assertEquals("marko rodriguez", v.<String>property("name").value());
            assertEquals(2, IteratorUtils.count(v.properties()));
            assertEquals(2, v.keys().size());
            assertTrue(v.keys().contains("name"));
            assertTrue(v.keys().contains("age"));
            assertFalse(v.keys().contains("location"));
            assertVertexEdgeCounts(graph, 1, 0);

            v.property(VertexProperty.Cardinality.single, "location", "santa fe");
            assertEquals(3, IteratorUtils.count(v.properties()));
            assertEquals(3, v.keys().size());
            assertEquals("santa fe", v.property("location").value());
            assertEquals(v.property("location"), v.property("location"));
            assertNotEquals(v.property("location"), v.property("name"));
            assertTrue(v.keys().contains("name"));
            assertTrue(v.keys().contains("age"));
            assertTrue(v.keys().contains("location"));
            v.property("location").remove();
            assertVertexEdgeCounts(graph, 1, 0);
            assertEquals(2, IteratorUtils.count(v.properties()));
            v.properties().forEachRemaining(Property::remove);
            assertEquals(0, IteratorUtils.count(v.properties()));
            assertVertexEdgeCounts(graph, 1, 0);
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
        public void shouldEvaluateVerticesEquivalentWithSuppliedIdsViaTraversal() {
            final Vertex v = graph.addVertex(T.id, graphProvider.convertId("1", Vertex.class));
            final Vertex u = graph.vertices(graphProvider.convertId("1", Vertex.class)).next();
            assertEquals(v, u);
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
        public void shouldEvaluateVerticesEquivalentWithSuppliedIdsViaIterators() {
            final Vertex v = graph.addVertex(T.id, graphProvider.convertId("1", Vertex.class));
            final Vertex u = graph.vertices(graphProvider.convertId("1", Vertex.class)).next();
            assertEquals(v, u);
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldEvaluateEquivalentVerticesWithNoSuppliedIds() {
            final Vertex v = graph.addVertex();
            assertNotNull(v);

            final Vertex u = graph.vertices(v.id()).next();
            assertNotNull(u);
            assertEquals(v, u);

            assertEquals(graph.vertices(u.id()).next(), graph.vertices(u.id()).next());
            assertEquals(graph.vertices(v.id()).next(), graph.vertices(u.id()).next());
            assertEquals(graph.vertices(v.id()).next(), graph.vertices(v.id()).next());
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
        public void shouldEvaluateEquivalentVertexHashCodeWithSuppliedIds() {
            final Vertex v = graph.addVertex(T.id, graphProvider.convertId("1", Vertex.class));
            final Vertex u = graph.vertices(graphProvider.convertId("1", Vertex.class)).next();
            assertEquals(v, u);

            final Set<Vertex> set = new HashSet<>();
            set.add(v);
            set.add(v);
            set.add(u);
            set.add(u);
            set.add(graph.vertices(graphProvider.convertId("1", Vertex.class)).next());
            set.add(graph.vertices(graphProvider.convertId("1", Vertex.class)).next());

            assertEquals(1, set.size());
            assertEquals(v.hashCode(), u.hashCode());
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY)
        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_VALUES)
        public void shouldAutotypeStringProperties() {
            final Vertex v = graph.addVertex();
            v.property(VertexProperty.Cardinality.single, "string", "marko");
            final String name = v.value("string");
            assertEquals(name, "marko");

        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY)
        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
        public void shouldAutotypeIntegerProperties() {
            final Vertex v = graph.addVertex();
            v.property(VertexProperty.Cardinality.single, "integer", 33);
            final Integer age = v.value("integer");
            assertEquals(Integer.valueOf(33), age);
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY)
        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_BOOLEAN_VALUES)
        public void shouldAutotypeBooleanProperties() {
            final Vertex v = graph.addVertex();
            v.property(VertexProperty.Cardinality.single, "boolean", true);
            final Boolean best = v.value("boolean");
            assertEquals(best, true);
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY)
        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_DOUBLE_VALUES)
        public void shouldAutotypeDoubleProperties() {
            final Vertex v = graph.addVertex();
            v.property(VertexProperty.Cardinality.single, "double", 0.1d);
            final Double best = v.value("double");
            assertEquals(best, Double.valueOf(0.1d));
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY)
        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_LONG_VALUES)
        public void shouldAutotypeLongProperties() {
            final Vertex v = graph.addVertex();
            v.property(VertexProperty.Cardinality.single, "long", 1L);
            final Long best = v.value("long");
            assertEquals(best, Long.valueOf(1L));
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY)
        @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_FLOAT_VALUES)
        public void shouldAutotypeFloatProperties() {
            final Vertex v = graph.addVertex();
            v.property(VertexProperty.Cardinality.single, "float", 0.1f);
            final Float best = v.value("float");
            assertEquals(best, Float.valueOf(0.1f));
        }

        @Test
        @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_REMOVE_PROPERTY)
        public void shouldGetPropertyKeysOnVertex() {
            final Vertex v = graph.addVertex("name", "marko", "location", "desert", "status", "dope");
            Set<String> keys = v.keys();
            assertEquals(3, keys.size());

            assertTrue(keys.contains("name"));
            assertTrue(keys.contains("location"));
            assertTrue(keys.contains("status"));

            final List<VertexProperty<Object>> m = IteratorUtils.list(v.properties());
            assertEquals(3, m.size());
            assertTrue(m.stream().anyMatch(p -> p.key().equals("name")));
            assertTrue(m.stream().anyMatch(p -> p.key().equals("location")));
            assertTrue(m.stream().anyMatch(p -> p.key().equals("status")));
            assertEquals("marko", m.stream().filter(p -> p.key().equals("name")).map(Property::value).findAny().orElse(null));
            assertEquals("desert", m.stream().filter(p -> p.key().equals("location")).map(Property::value).findAny().orElse(null));
            assertEquals("dope", m.stream().filter(p -> p.key().equals("status")).map(Property::value).findAny().orElse(null));

            v.property("status").remove();

            keys = v.keys();
            assertEquals(2, keys.size());
            assertTrue(keys.contains("name"));
            assertTrue(keys.contains("location"));

            v.properties().forEachRemaining(Property::remove);

            keys = v.keys();
            assertEquals(0, keys.size());
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        @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_PROPERTY)
        @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_PROPERTY)
        @FeatureRequirement(featureClass = Graph.Features.EdgePropertyFeatures.class, feature = FEATURE_INTEGER_VALUES)
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_REMOVE_VERTICES)
        public void shouldNotGetConcurrentModificationException() {
            for (int i = 0; i < 25; i++) {
                graph.addVertex("myId", i);
            }
            graph.vertices().forEachRemaining(v -> graph.vertices().forEachRemaining(u -> v.addEdge("knows", u, "myEdgeId", 12)));

            tryCommit(graph, getAssertVertexEdgeCounts(25, 625));

            final List<Vertex> vertices = new ArrayList<>();
            IteratorUtils.fill(graph.vertices(), vertices);
            for (Vertex v : vertices) {
                v.remove();
                tryCommit(graph);
            }

            tryCommit(graph, getAssertVertexEdgeCounts(0, 0));
        }

        @Test
        @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
        public void shouldReturnEmptyIteratorIfNoProperties() {
            final Vertex v = graph.addVertex();
            assertEquals(0, IteratorUtils.count(v.properties()));
        }
    }
}
