You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2017/05/18 16:56:00 UTC

[1/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1552 [created] 72553d680


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
new file mode 100644
index 0000000..747a94e
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
@@ -0,0 +1,308 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Gremlin.Net.Structure;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Moq;
+using Newtonsoft.Json.Linq;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+    public class GraphSONReaderTests
+    {
+        private GraphSONReader CreateStandardGraphSONReader()
+        {
+            return new GraphSONReader();
+        }
+
+        [Fact]
+        public void ShouldDeserializeWithCustomDeserializerForNewType()
+        {
+            var deserializerByGraphSONType = new Dictionary<string, IGraphSONDeserializer>
+            {
+                {"NS:TestClass", new TestGraphSONDeserializer()}
+            };
+            var reader = new GraphSONReader(deserializerByGraphSONType);
+            var graphSON = "{\"@type\":\"NS:TestClass\",\"@value\":\"test\"}";
+
+            var jObject = JObject.Parse(graphSON);
+            var readObj = reader.ToObject(jObject);
+
+            Assert.Equal("test", readObj.Value);
+        }
+
+        [Fact]
+        public void ShouldDeserializeWithCustomDeserializerForCommonType()
+        {
+            var customSerializerMock = new Mock<IGraphSONDeserializer>();
+            var overrideTypeString = "g:Int64";
+            var customSerializerByType = new Dictionary<string, IGraphSONDeserializer>
+            {
+                {overrideTypeString, customSerializerMock.Object}
+            };
+            var reader = new GraphSONReader(customSerializerByType);
+
+
+            reader.ToObject(JObject.Parse($"{{\"@type\":\"{overrideTypeString}\",\"@value\":12}}"));
+
+            customSerializerMock.Verify(m => m.Objectify(It.IsAny<JToken>(), It.IsAny<GraphSONReader>()));
+        }
+
+        [Fact]
+        public void ShouldDeserializeDateToDateTime()
+        {
+            var graphSon = "{\"@type\":\"g:Date\",\"@value\":1475583442552}";
+            var reader = CreateStandardGraphSONReader();
+
+            DateTime readDateTime = reader.ToObject(JObject.Parse(graphSon));
+
+            var expectedDateTime = TestUtils.FromJavaTime(1475583442552);
+            Assert.Equal(expectedDateTime, readDateTime);
+        }
+
+        [Fact]
+        public void ShouldDeserializeDictionary()
+        {
+            var serializedDict = "{\"age\":[{\"@type\":\"g:Int32\",\"@value\":29}],\"name\":[\"marko\"]}";
+            var reader = CreateStandardGraphSONReader();
+
+            var jObject = JObject.Parse(serializedDict);
+            var deserializedDict = reader.ToObject(jObject);
+
+            var expectedDict = new Dictionary<string, dynamic>
+            {
+                {"age", new List<object> {29}},
+                {"name", new List<object> {"marko"}}
+            };
+            Assert.Equal(expectedDict, deserializedDict);
+        }
+
+        [Fact]
+        public void ShouldDeserializeEdge()
+        {
+            var graphSon =
+                "{\"@type\":\"g:Edge\", \"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":17},\"label\":\"knows\",\"inV\":\"x\",\"outV\":\"y\",\"inVLabel\":\"xLab\",\"properties\":{\"aKey\":\"aValue\",\"bKey\":true}}}";
+            var reader = CreateStandardGraphSONReader();
+
+            Edge readEdge = reader.ToObject(JObject.Parse(graphSon));
+
+            Assert.Equal((long) 17, readEdge.Id);
+            Assert.Equal("knows", readEdge.Label);
+            Assert.Equal(new Vertex("x", "xLabel"), readEdge.InV);
+            Assert.Equal(new Vertex("y"), readEdge.OutV);
+        }
+
+        [Fact]
+        public void ShouldDeserializeInt()
+        {
+            var serializedValue = "{\"@type\":\"g:Int32\",\"@value\":5}";
+            var reader = CreateStandardGraphSONReader();
+
+            var jObject = JObject.Parse(serializedValue);
+            var deserializedValue = reader.ToObject(jObject);
+
+            Assert.Equal(5, deserializedValue);
+        }
+
+        [Fact]
+        public void ShouldDeserializeLong()
+        {
+            var serializedValue = "{\"@type\":\"g:Int64\",\"@value\":5}";
+            var reader = CreateStandardGraphSONReader();
+
+            var jObject = JObject.Parse(serializedValue);
+            var deserializedValue = reader.ToObject(jObject);
+
+            Assert.Equal((long) 5, deserializedValue);
+        }
+
+        [Fact]
+        public void ShouldDeserializeFloat()
+        {
+            var serializedValue = "{\"@type\":\"g:Float\",\"@value\":31.3}";
+            var reader = CreateStandardGraphSONReader();
+
+            var jObject = JObject.Parse(serializedValue);
+            var deserializedValue = reader.ToObject(jObject);
+
+            Assert.Equal((float) 31.3, deserializedValue);
+        }
+
+        [Fact]
+        public void ShouldDeserializeDouble()
+        {
+            var serializedValue = "{\"@type\":\"g:Double\",\"@value\":31.2}";
+            var reader = CreateStandardGraphSONReader();
+
+            var jObject = JObject.Parse(serializedValue);
+            var deserializedValue = reader.ToObject(jObject);
+
+            Assert.Equal(31.2, deserializedValue);
+        }
+
+        [Fact]
+        public void ShouldDeserializeList()
+        {
+            var serializedValue = "[{\"@type\":\"g:Int32\",\"@value\":5},{\"@type\":\"g:Int32\",\"@value\":6}]";
+            var reader = CreateStandardGraphSONReader();
+
+            var jObject = JArray.Parse(serializedValue);
+            var deserializedValue = reader.ToObject(jObject);
+
+            Assert.Equal(new List<object> {5, 6}, deserializedValue);
+        }
+
+        [Fact]
+        public void ShouldDeserializePath()
+        {
+            var graphSon =
+                "{\"@type\":\"g:Path\",\"@value\":{\"labels\":[[\"a\"],[\"b\",\"c\"],[]],\"objects\":[{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"person\",\"properties\":{\"name\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":0},\"value\":\"marko\",\"label\":\"name\"}}],\"age\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":1},\"value\":{\"@type\":\"g:Int32\",\"@value\":29},\"label\":\"age\"}}]}}},{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":3},\"label\":\"software\",\"properties\":{\"name\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":4},\"value\":\"lop\",\"label\":\"name\"}}],\"lang\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":5},\"value\":\"java\",\"label\":\"lang\"}}]}}},\"lop\"]}}";
+            var reader = CreateStandardGraphSONReader();
+
+            Path readPath = reader.ToObject(JObject.Parse(graphSon));
+
+            Assert.Equal("[v[1], v[3], lop]", readPath.ToString());
+            Assert.Equal(new Vertex(1), readPath[0]);
+            Assert.Equal(new Vertex(1), readPath["a"]);
+            Assert.Equal("lop", readPath[2]);
+            Assert.Equal(3, readPath.Count);
+        }
+
+        [Fact]
+        public void ShouldDeserializePropertyWithEdgeElement()
+        {
+            var graphSon =
+                "{\"@type\":\"g:Property\",\"@value\":{\"key\":\"aKey\",\"value\":{\"@type\":\"g:Int64\",\"@value\":17},\"element\":{\"@type\":\"g:Edge\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":122},\"label\":\"knows\",\"inV\":\"x\",\"outV\":\"y\",\"inVLabel\":\"xLab\"}}}}";
+            var reader = CreateStandardGraphSONReader();
+
+            Property readProperty = reader.ToObject(JObject.Parse(graphSon));
+
+            Assert.Equal("aKey", readProperty.Key);
+            Assert.Equal((long) 17, readProperty.Value);
+            Assert.Equal(typeof(Edge), readProperty.Element.GetType());
+            var edge = readProperty.Element as Edge;
+            Assert.Equal((long) 122, edge.Id);
+            Assert.Equal("knows", edge.Label);
+            Assert.Equal("x", edge.InV.Id);
+            Assert.Equal("y", edge.OutV.Id);
+        }
+
+        [Fact]
+        public void ShouldDeserializeTimestampToDateTime()
+        {
+            var graphSon = "{\"@type\":\"g:Timestamp\",\"@value\":1475583442558}";
+            var reader = CreateStandardGraphSONReader();
+
+            DateTime readDateTime = reader.ToObject(JObject.Parse(graphSon));
+
+            var expectedDateTime = TestUtils.FromJavaTime(1475583442558);
+            Assert.Equal(expectedDateTime, readDateTime);
+        }
+
+        [Fact]
+        public void ShouldDeserializeGuid()
+        {
+            var graphSon = "{\"@type\":\"g:UUID\",\"@value\":\"41d2e28a-20a4-4ab0-b379-d810dede3786\"}";
+            var reader = CreateStandardGraphSONReader();
+
+            Guid readGuid = reader.ToObject(JObject.Parse(graphSon));
+
+            Assert.Equal(Guid.Parse("41d2e28a-20a4-4ab0-b379-d810dede3786"), readGuid);
+        }
+
+        [Fact]
+        public void ShouldDeserializeVertexProperty()
+        {
+            var graphSon =
+                "{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":\"anId\",\"label\":\"aKey\",\"value\":true,\"vertex\":{\"@type\":\"g:Int32\",\"@value\":9}}}";
+            var reader = CreateStandardGraphSONReader();
+
+            VertexProperty readVertexProperty = reader.ToObject(JObject.Parse(graphSon));
+
+            Assert.Equal("anId", readVertexProperty.Id);
+            Assert.Equal("aKey", readVertexProperty.Label);
+            Assert.True(readVertexProperty.Value);
+            Assert.NotNull(readVertexProperty.Vertex);
+        }
+
+        [Fact]
+        public void ShouldDeserializeVertexPropertyWithLabel()
+        {
+            var graphSon =
+                "{\"@type\":\"g:VertexProperty\", \"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"name\",\"value\":\"marko\"}}";
+            var reader = CreateStandardGraphSONReader();
+
+            VertexProperty readVertexProperty = reader.ToObject(JObject.Parse(graphSon));
+
+            Assert.Equal(1, readVertexProperty.Id);
+            Assert.Equal("name", readVertexProperty.Label);
+            Assert.Equal("marko", readVertexProperty.Value);
+            Assert.Null(readVertexProperty.Vertex);
+        }
+
+        [Fact]
+        public void ShouldDeserializeVertex()
+        {
+            var graphSon = "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Float\",\"@value\":45.23}}}";
+            var reader = CreateStandardGraphSONReader();
+
+            var readVertex = reader.ToObject(JObject.Parse(graphSon));
+
+            Assert.Equal(new Vertex(45.23f), readVertex);
+        }
+
+        [Fact]
+        public void ShouldDeserializeVertexWithEdges()
+        {
+            var graphSon =
+                "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"person\",\"outE\":{\"created\":[{\"id\":{\"@type\":\"g:Int32\",\"@value\":9},\"inV\":{\"@type\":\"g:Int32\",\"@value\":3},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":0.4}}}],\"knows\":[{\"id\":{\"@type\":\"g:Int32\",\"@value\":7},\"inV\":{\"@type\":\"g:Int32\",\"@value\":2},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":0.5}}},{\"id\":{\"@type\":\"g:Int32\",\"@value\":8},\"inV\":{\"@type\":\"g:Int32\",\"@value\":4},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":1.0}}}]},\"properties\":{\"name\":[{\"id\":{\"@type\":\"g:Int64\",\"@value\":0},\"value\":\"marko\"}],\"age\":[{\"id\":{\"@type\":\"g:Int64\",\"@value\":1},\"value\":{\"@type\":\"g:Int32\",\"@value\":29}}]}}}";
+            var reader = CreateStandardGraphSONReader();
+
+            var readVertex = reader.ToObject(JObject.Parse(graphSon));
+
+            Assert.Equal(new Vertex(1), readVertex);
+            Assert.Equal("person", readVertex.Label);
+            Assert.Equal(typeof(int), readVertex.Id.GetType());
+        }
+
+        [Fact]
+        public void ShouldDeserializeTraverser()
+        {
+            dynamic d = JObject.Parse("{\"@type\":\"g:Traverser\",\"@value\":1}");
+
+            Assert.NotNull(d);
+            Assert.Equal("g:Traverser", (string)d["@type"]);
+        }
+    }
+
+    internal class TestGraphSONDeserializer : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            return new TestClass {Value = graphsonObject.ToString()};
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
new file mode 100644
index 0000000..49786d7
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
@@ -0,0 +1,329 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Structure;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Moq;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+    public class GraphSONWriterTests
+    {
+        private GraphSONWriter CreateStandardGraphSONWriter()
+        {
+            return new GraphSONWriter();
+        }
+
+        [Fact]
+        public void ShouldSerializeInt()
+        {
+            var writer = CreateStandardGraphSONWriter();
+
+            var graphSon = writer.WriteObject(1);
+
+            Assert.Equal("{\"@type\":\"g:Int32\",\"@value\":1}", graphSon);
+        }
+
+        [Fact]
+        public void ShouldSerializeLong()
+        {
+            var writer = CreateStandardGraphSONWriter();
+
+            var graphSon = writer.WriteObject((long) 2);
+
+            Assert.Equal("{\"@type\":\"g:Int64\",\"@value\":2}", graphSon);
+        }
+
+        [Fact]
+        public void ShouldSerializeFloat()
+        {
+            var writer = CreateStandardGraphSONWriter();
+
+            var graphSon = writer.WriteObject((float) 3.2);
+
+            Assert.Equal("{\"@type\":\"g:Float\",\"@value\":3.2}", graphSon);
+        }
+
+        [Fact]
+        public void ShouldSerializeDouble()
+        {
+            var writer = CreateStandardGraphSONWriter();
+
+            var graphSon = writer.WriteObject(3.2);
+
+            Assert.Equal("{\"@type\":\"g:Double\",\"@value\":3.2}", graphSon);
+        }
+
+        [Fact]
+        public void ShouldSerializeBoolean()
+        {
+            var writer = CreateStandardGraphSONWriter();
+
+            var graphSon = writer.WriteObject(true);
+
+            Assert.Equal("true", graphSon);
+        }
+
+        [Fact]
+        public void ShouldSerializeArray()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var array = new[] {5, 6};
+
+            var serializedGraphSON = writer.WriteObject(array);
+
+            var expectedGraphSON = "[{\"@type\":\"g:Int32\",\"@value\":5},{\"@type\":\"g:Int32\",\"@value\":6}]";
+            Assert.Equal(expectedGraphSON, serializedGraphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializeBinding()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var binding = new Binding("theKey", 123);
+
+            var graphSon = writer.WriteObject(binding);
+
+            const string expected =
+                "{\"@type\":\"g:Binding\",\"@value\":{\"value\":{\"@type\":\"g:Int32\",\"@value\":123},\"key\":\"theKey\"}}";
+            Assert.Equal(expected, graphSon);
+        }
+
+        [Fact]
+        public void ShouldSerializeWithCustomSerializerForNewType()
+        {
+            var customSerializerByType = new Dictionary<Type, IGraphSONSerializer>
+            {
+                {typeof(TestClass), new TestGraphSONSerializer {TestNamespace = "NS"}}
+            };
+            var writer = new GraphSONWriter(customSerializerByType);
+            var testObj = new TestClass {Value = "test"};
+
+            var serialized = writer.WriteObject(testObj);
+
+            Assert.Equal("{\"@type\":\"NS:TestClass\",\"@value\":\"test\"}", serialized);
+        }
+
+        [Fact]
+        public void ShouldSerializeWithCustomSerializerForCommonType()
+        {
+            var customSerializerMock = new Mock<IGraphSONSerializer>();
+            var customSerializerByType = new Dictionary<Type, IGraphSONSerializer>
+            {
+                {typeof(int), customSerializerMock.Object}
+            };
+            var writer = new GraphSONWriter(customSerializerByType);
+
+            writer.WriteObject(12);
+
+            customSerializerMock.Verify(m => m.Dictify(It.Is<int>(v => v == 12), It.IsAny<GraphSONWriter>()));
+        }
+
+        [Fact]
+        public void ShouldSerializeDateTime()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var dateTime = TestUtils.FromJavaTime(1475583442552);
+
+            var graphSon = writer.WriteObject(dateTime);
+
+            const string expected = "{\"@type\":\"g:Date\",\"@value\":1475583442552}";
+            Assert.Equal(expected, graphSon);
+        }
+
+        [Fact]
+        public void ShouldSerializeDictionary()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var dictionary = new Dictionary<string, dynamic>
+            {
+                {"age", new List<int> {29}},
+                {"name", new List<string> {"marko"}}
+            };
+
+            var serializedDict = writer.WriteObject(dictionary);
+
+            var expectedGraphSON = "{\"age\":[{\"@type\":\"g:Int32\",\"@value\":29}],\"name\":[\"marko\"]}";
+            Assert.Equal(expectedGraphSON, serializedDict);
+        }
+
+        [Fact]
+        public void ShouldSerializeEdge()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var edge = new Edge(7, new Vertex(0, "person"), "knows", new Vertex(1, "dog"));
+
+            var graphSON = writer.WriteObject(edge);
+
+            const string expected =
+                "{\"@type\":\"g:Edge\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":7},\"outV\":{\"@type\":\"g:Int32\",\"@value\":0},\"outVLabel\":\"person\",\"label\":\"knows\",\"inV\":{\"@type\":\"g:Int32\",\"@value\":1},\"inVLabel\":\"dog\"}}";
+            Assert.Equal(expected, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializeEnum()
+        {
+            var writer = CreateStandardGraphSONWriter();
+
+            var serializedEnum = writer.WriteObject(T.label);
+
+            var expectedGraphSON = "{\"@type\":\"g:T\",\"@value\":\"label\"}";
+            Assert.Equal(expectedGraphSON, serializedEnum);
+        }
+
+        [Fact]
+        public void ShouldSerializeList()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var list = new List<int> {5, 6};
+
+            var serializedGraphSON = writer.WriteObject(list.ToArray());
+
+            var expectedGraphSON = "[{\"@type\":\"g:Int32\",\"@value\":5},{\"@type\":\"g:Int32\",\"@value\":6}]";
+            Assert.Equal(expectedGraphSON, serializedGraphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializePredicateWithTwoValues()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var predicate = new TraversalPredicate("within", new List<int> {1, 2});
+
+            var serializedPredicate = writer.WriteObject(predicate);
+
+            var expectedGraphSON =
+                "{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"within\",\"value\":[{\"@type\":\"g:Int32\",\"@value\":1},{\"@type\":\"g:Int32\",\"@value\":2}]}}";
+            Assert.Equal(expectedGraphSON, serializedPredicate);
+        }
+
+        [Fact]
+        public void ShouldSerializePredicateWithSingleValue()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var predicate = new TraversalPredicate("lt", 5);
+
+            var serializedPredicate = writer.WriteObject(predicate);
+
+            var expectedGraphSON =
+                "{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"lt\",\"value\":{\"@type\":\"g:Int32\",\"@value\":5}}}";
+            Assert.Equal(expectedGraphSON, serializedPredicate);
+        }
+
+        [Fact]
+        public void ShouldSerializePropertyWithEdgeElement()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var property = new Property("aKey", "aValue", new Edge("anId", new Vertex(1), "edgeLabel", new Vertex(2)));
+
+            var graphSON = writer.WriteObject(property);
+
+            const string expected =
+                "{\"@type\":\"g:Property\",\"@value\":{\"key\":\"aKey\",\"value\":\"aValue\",\"element\":{\"@type\":\"g:Edge\",\"@value\":{\"id\":\"anId\",\"outV\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"edgeLabel\",\"inV\":{\"@type\":\"g:Int32\",\"@value\":2}}}}}";
+            Assert.Equal(expected, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializePropertyWithVertexPropertyElement()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var property = new Property("name", "marko",
+                new VertexProperty("anId", "aKey", 21345, new Vertex("vertexId")));
+
+            var graphSON = writer.WriteObject(property);
+
+            const string expected =
+                "{\"@type\":\"g:Property\",\"@value\":{\"key\":\"name\",\"value\":\"marko\",\"element\":{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":\"anId\",\"label\":\"aKey\",\"vertex\":\"vertexId\"}}}}";
+            Assert.Equal(expected, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializeVertexProperty()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var vertexProperty = new VertexProperty("blah", "keyA", true, new Vertex("stephen"));
+
+            var graphSON = writer.WriteObject(vertexProperty);
+
+            const string expected =
+                "{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":\"blah\",\"label\":\"keyA\",\"value\":true,\"vertex\":\"stephen\"}}";
+            Assert.Equal(expected, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializeGuid()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var guid = Guid.Parse("41d2e28a-20a4-4ab0-b379-d810dede3786");
+
+            var graphSon = writer.WriteObject(guid);
+
+            const string expected = "{\"@type\":\"g:UUID\",\"@value\":\"41d2e28a-20a4-4ab0-b379-d810dede3786\"}";
+            Assert.Equal(expected, graphSon);
+        }
+
+        [Fact]
+        public void ShouldSerializeVertex()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var vertex = new Vertex(45.23f);
+
+            var graphSON = writer.WriteObject(vertex);
+
+            const string expected =
+                "{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Float\",\"@value\":45.23},\"label\":\"vertex\"}}";
+            Assert.Equal(expected, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializeVertexWithLabel()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var vertex = new Vertex((long) 123, "project");
+
+            var graphSON = writer.WriteObject(vertex);
+
+            const string expected =
+                "{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":123},\"label\":\"project\"}}";
+            Assert.Equal(expected, graphSON);
+        }
+    }
+
+    internal enum T
+    {
+        label
+    }
+
+    internal class TestGraphSONSerializer : IGraphSONSerializer
+    {
+        public string TestNamespace { get; set; }
+
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            return GraphSONUtil.ToTypedValue(nameof(TestClass), objectData.Value, TestNamespace);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/StrategyWriterTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/StrategyWriterTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/StrategyWriterTests.cs
new file mode 100644
index 0000000..4bdb141
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/StrategyWriterTests.cs
@@ -0,0 +1,66 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+    public class StrategyWriterTests
+    {
+        private GraphSONWriter CreateGraphSONWriter()
+        {
+            return new GraphSONWriter();
+        }
+
+        [Fact]
+        public void ShouldSerializeSubgraphStrategyWithoutValues()
+        {
+            var subgraphStrategy = new SubgraphStrategy();
+            var writer = CreateGraphSONWriter();
+
+            var graphSon = writer.WriteObject(subgraphStrategy);
+
+            const string expected = "{\"@type\":\"g:SubgraphStrategy\",\"@value\":{}}";
+            Assert.Equal(expected, graphSon);
+        }
+
+        [Fact]
+        public void ShouldDeserializeSubgraphStrategyWithVertexCriterion()
+        {
+            var vertexCriterionBytecode = new Bytecode();
+            vertexCriterionBytecode.AddStep("has", "name", "marko");
+            var vertexCriterion = new TestTraversal(vertexCriterionBytecode);
+            var subgraphStrategy = new SubgraphStrategy(vertexCriterion);
+            var writer = CreateGraphSONWriter();
+
+            var graphSon = writer.WriteObject(subgraphStrategy);
+
+            const string expected =
+                "{\"@type\":\"g:SubgraphStrategy\",\"@value\":{\"vertices\":{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"has\",\"name\",\"marko\"]]}}}}";
+            Assert.Equal(expected, graphSon);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestClass.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestClass.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestClass.cs
new file mode 100644
index 0000000..13d1bca
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestClass.cs
@@ -0,0 +1,30 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+    internal class TestClass
+    {
+        public dynamic Value { get; set; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestUtils.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestUtils.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestUtils.cs
new file mode 100644
index 0000000..7ed7542
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/TestUtils.cs
@@ -0,0 +1,36 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+    internal class TestUtils
+    {
+        public static DateTime FromJavaTime(long javaTimestamp)
+        {
+            var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+            return epoch.AddMilliseconds(javaTimestamp);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PathTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PathTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PathTests.cs
new file mode 100644
index 0000000..e4ffb6e
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PathTests.cs
@@ -0,0 +1,416 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+    public class PathTests
+    {
+        [Fact]
+        public void ShouldAssignPropertiesCorrectly()
+        {
+            var labels = new List<List<string>>
+            {
+                new List<string> {"a", "b"},
+                new List<string> {"c", "b"},
+                new List<string>()
+            };
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+
+            var path = new Path(labels, objects);
+
+            Assert.Equal(labels, path.Labels);
+            Assert.Equal(objects, path.Objects);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForContainsKeyWhenGivenKeyExists()
+        {
+            var labels = new List<List<string>>
+            {
+                new List<string> {"a", "b"},
+                new List<string> {"c", "b"},
+                new List<string>()
+            };
+            var path = new Path(labels, new List<object>());
+
+            var containsKey = path.ContainsKey("c");
+
+            Assert.True(containsKey);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForContainsKeyWhenGivenKeyDoesNotExist()
+        {
+            var labels = new List<List<string>>
+            {
+                new List<string> {"a", "b"},
+                new List<string> {"c", "b"},
+                new List<string>()
+            };
+            var path = new Path(labels, new List<object>());
+
+            var containsKey = path.ContainsKey("z");
+
+            Assert.False(containsKey);
+        }
+
+        [Fact]
+        public void ShouldReturnCountOfObjectsForCountProperty()
+        {
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(new List<List<string>>(), objects);
+
+            var count = path.Count;
+
+            Assert.Equal(3, count);
+        }
+
+        [Fact]
+        public void ShouldEnumeratorObjectsIntoListWhenToListIsCalled()
+        {
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(new List<List<string>>(), objects);
+
+            var enumeratedObj = path.ToList();
+
+            Assert.Equal(objects, enumeratedObj);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsOfTwoEqualPaths()
+        {
+            var firstPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> {1, new Vertex(1), "hello"});
+            var secondPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> {1, new Vertex(1), "hello"});
+
+            var equals = firstPath.Equals(secondPath);
+
+            Assert.True(equals);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsOfPathsWithDifferentLabels()
+        {
+            var firstPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> {1, new Vertex(1), "hello"});
+            var secondPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> {1, new Vertex(1), "hello"});
+
+            var equals = firstPath.Equals(secondPath);
+
+            Assert.False(equals);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsOfPathsWithDifferentObjects()
+        {
+            var firstPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> {1, new Vertex(1), "hello"});
+            var secondPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> {3, new Vertex(1), "hello"});
+
+            var equals = firstPath.Equals(secondPath);
+
+            Assert.False(equals);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsObjectOfTwoEqualPaths()
+        {
+            var firstPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> { 1, new Vertex(1), "hello" });
+            object secondPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> { 1, new Vertex(1), "hello" });
+
+            var equals = firstPath.Equals(secondPath);
+
+            Assert.True(equals);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsObjectOfPathsWithDifferentLabels()
+        {
+            var firstPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> { 1, new Vertex(1), "hello" });
+            object secondPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> { 1, new Vertex(1), "hello" });
+
+            var equals = firstPath.Equals(secondPath);
+
+            Assert.False(equals);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsObjectOfPathsWithDifferentObjects()
+        {
+            var firstPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> { 1, new Vertex(1), "hello" });
+            object secondPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> { 3, new Vertex(1), "hello" });
+
+            var equals = firstPath.Equals(secondPath);
+
+            Assert.False(equals);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsWhereOtherIsNull()
+        {
+            var path = new Path(new List<List<string>> {new List<string> {"a", "b"},}, new List<object> {1});
+
+            var equals = path.Equals(null);
+
+            Assert.False(equals);
+        }
+
+        [Fact]
+        public void ShouldReturnEqualHashcodesForEqualPaths()
+        {
+            var firstPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> { 1, new Vertex(1), "hello" });
+            var secondPath =
+                new Path(
+                    new List<List<string>>
+                    {
+                        new List<string> {"a", "b"},
+                        new List<string> {"c", "b"},
+                        new List<string>()
+                    }, new List<object> { 1, new Vertex(1), "hello" });
+
+            var firstHashCode = firstPath.GetHashCode();
+            var secondHashCode = secondPath.GetHashCode();
+
+            Assert.Equal(firstHashCode, secondHashCode);
+        }
+
+        [Fact]
+        public void ShouldThrowWhenInvalidIndexIsAccessed()
+        {
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(new List<List<string>>(), objects);
+
+            Assert.Throws<ArgumentOutOfRangeException>(() => path[3]);
+        }
+
+        [Fact]
+        public void ShouldReturnObjectsByTheirIndex()
+        {
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(new List<List<string>>(), objects);
+
+            Assert.Equal(1, path[0]);
+            Assert.Equal(new Vertex(1), path[1]);
+            Assert.Equal("hello", path[2]);
+        }
+
+        [Fact]
+        public void ShouldReturnAllObjectsWhenTheirKeyIsAccessed()
+        {
+            var labels = new List<List<string>>
+            {
+                new List<string> {"a", "b"},
+                new List<string> {"c", "b"},
+                new List<string>()
+            };
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(labels, objects);
+
+            var bObjects = path["b"];
+
+            Assert.Equal(new List<object> {1, new Vertex(1)}, bObjects);
+        }
+
+        [Fact]
+        public void ShouldReturnObjectsByTheirKey()
+        {
+            var labels = new List<List<string>>
+            {
+                new List<string> {"a"},
+                new List<string> {"c", "b"},
+                new List<string>()
+            };
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(labels, objects);
+
+            Assert.Equal(1, path["a"]);
+            Assert.Equal(new Vertex(1), path["c"]);
+            Assert.Equal(new Vertex(1), path["b"]);
+        }
+
+        [Fact]
+        public void ShouldThrowWhenUnknownKeyIsAccessed()
+        {
+            var path = new Path(new List<List<string>>(), new List<object>());
+
+            Assert.Throws<KeyNotFoundException>(() => path["unknownKey"]);
+        }
+
+        [Fact]
+        public void ShouldReturnCommonStringRepresentationForToString()
+        {
+            var labels = new List<List<string>>
+            {
+                new List<string> {"a", "b"},
+                new List<string> {"c", "b"},
+                new List<string>()
+            };
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(labels, objects);
+
+            var pathStr = path.ToString();
+
+            Assert.Equal("[1, v[1], hello]", pathStr);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueAndObjectsForTryGetWhenKeyWithMultipleObjectsIsProvided()
+        {
+            var labels = new List<List<string>>
+            {
+                new List<string> {"a", "b"},
+                new List<string> {"c", "b"},
+                new List<string>()
+            };
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(labels, objects);
+
+            var success = path.TryGetValue("b", out object actualObj);
+
+            Assert.True(success);
+            Assert.Equal(new List<object> {1, new Vertex(1)}, actualObj);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueAndCorrectObjectForTryGet()
+        {
+            var labels = new List<List<string>>
+            {
+                new List<string> {"a"},
+                new List<string> {"c", "b"},
+                new List<string>()
+            };
+            var objects = new List<object> {1, new Vertex(1), "hello"};
+            var path = new Path(labels, objects);
+
+            var success = path.TryGetValue("b", out object actualObj);
+
+            Assert.True(success);
+            Assert.Equal(new Vertex(1), actualObj);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForTryGetWhenUnknownKeyIsProvided()
+        {
+            var path = new Path(new List<List<string>>(), new List<object>());
+
+            var success = path.TryGetValue("unknownKey", out object _);
+
+            Assert.False(success);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PropertyTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PropertyTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PropertyTests.cs
new file mode 100644
index 0000000..e457dbd
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/PropertyTests.cs
@@ -0,0 +1,165 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+    public class PropertyTests
+    {
+        [Fact]
+        public void ShouldAssignPropertiesCorrectly()
+        {
+            const string key = "age";
+            const int value = 29;
+            var element = new Vertex(1);
+
+            var property = new Property(key, value, element);
+
+            Assert.Equal(key, property.Key);
+            Assert.Equal(value, property.Value);
+            Assert.Equal(element, property.Element);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsOfTwoEqualProperties()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            var secondProperty = new Property("age", 29, new Vertex(1));
+
+            var areEqual = firstProperty.Equals(secondProperty);
+
+            Assert.True(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsWhereOtherIsNull()
+        {
+            var property = new Property("age", 29, new Vertex(1));
+
+            var areEqual = property.Equals(null);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsOfPropertiesWithDifferentKeys()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            var secondProperty = new Property("aDifferentKey", 29, new Vertex(1));
+
+            var areEqual = firstProperty.Equals(secondProperty);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsOfPropertiesWithDifferentValues()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            var secondProperty = new Property("age", 12, new Vertex(1));
+
+            var areEqual = firstProperty.Equals(secondProperty);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsOfPropertiesWithDifferentElements()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            var secondProperty = new Property("age", 29, new Vertex(1234));
+
+            var areEqual = firstProperty.Equals(secondProperty);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsObjectOfTwoEqualProperties()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            object secondProperty = new Property("age", 29, new Vertex(1));
+
+            var areEqual = firstProperty.Equals(secondProperty);
+
+            Assert.True(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsObjectOfPropertiesWithDifferentKeys()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            object secondProperty = new Property("aDifferentKey", 29, new Vertex(1));
+
+            var areEqual = firstProperty.Equals(secondProperty);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsObjectOfPropertiesWithDifferentValues()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            object secondProperty = new Property("age", 12, new Vertex(1));
+
+            var areEqual = firstProperty.Equals(secondProperty);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsObjectOfPropertiesWithDifferentElements()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            object secondProperty = new Property("age", 29, new Vertex(1234));
+
+            var areEqual = firstProperty.Equals(secondProperty);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnEqualHashcodesForEqualProperties()
+        {
+            var firstProperty = new Property("age", 29, new Vertex(1));
+            var secondProperty = new Property("age", 29, new Vertex(1));
+
+            var firstHashCode = firstProperty.GetHashCode();
+            var secondHashCode = secondProperty.GetHashCode();
+
+            Assert.Equal(firstHashCode, secondHashCode);
+        }
+
+        [Fact]
+        public void ShouldReturnCommonStringRepresentationForToString()
+        {
+            var property = new Property("age", 29, new Vertex(1));
+
+            var stringRepresentation = property.ToString();
+
+            Assert.Equal("p[age->29]", stringRepresentation);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexPropertyTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexPropertyTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexPropertyTests.cs
new file mode 100644
index 0000000..9288940
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexPropertyTests.cs
@@ -0,0 +1,69 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+    public class VertexPropertyTests
+    {
+        [Fact]
+        public void ShouldAssignPropertiesCorrectly()
+        {
+            const long id = 24;
+            const string label = "name";
+            const string value = "marko";
+            var vertex = new Vertex(1);
+
+            var vertexProperty = new VertexProperty(id, label, value, vertex);
+
+            Assert.Equal(label, vertexProperty.Label);
+            Assert.Equal(label, vertexProperty.Key);
+            Assert.Equal(value, vertexProperty.Value);
+            Assert.Equal(id, vertexProperty.Id);
+            Assert.Equal(vertex, vertexProperty.Vertex);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsOfTwoEqualVertexProperties()
+        {
+            var firstVertexProperty = new VertexProperty((long) 24, "name", "marko", new Vertex(1));
+            var secondVertexProperty = new VertexProperty((long) 24, "name", "marko", new Vertex(1));
+
+            var areEqual = firstVertexProperty.Equals(secondVertexProperty);
+
+            Assert.True(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnCommonStringRepresentationForToString()
+        {
+            var vertexProperty = new VertexProperty((long) 24, "name", "marko", new Vertex(1));
+
+            var stringRepresentation = vertexProperty.ToString();
+
+            Assert.Equal("vp[name->marko]", stringRepresentation);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexTests.cs
new file mode 100644
index 0000000..8a93da5
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/VertexTests.cs
@@ -0,0 +1,80 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+    public class VertexTests
+    {
+        [Fact]
+        public void ShouldReturnCommonStringRepresentationForToString()
+        {
+            var vertex = new Vertex(12345);
+
+            var vertexString = vertex.ToString();
+
+            Assert.Equal("v[12345]", vertexString);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsOfTwoEqualVertices()
+        {
+            var firstVertex = new Vertex(1);
+            var secondVertex = new Vertex(1);
+
+            var areEqual = firstVertex.Equals(secondVertex);
+
+            Assert.True(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnFalseForEqualsWhereOtherIsNull()
+        {
+            var vertex = new Vertex(1);
+
+            var areEqual = vertex.Equals(null);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnSpecifiedLabelForLabelProperty()
+        {
+            const string specifiedLabel = "person";
+
+            var vertex = new Vertex(1, specifiedLabel);
+
+            Assert.Equal(specifiedLabel, vertex.Label);
+        }
+
+        [Fact]
+        public void ShouldReturnDefaultLabelForLabelPropertyWhenNoLabelSpecified()
+        {
+            var vertex = new Vertex(1);
+
+            Assert.Equal("vertex", vertex.Label);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/pom.xml b/gremlin-dotnet/test/pom.xml
new file mode 100644
index 0000000..e625d60
--- /dev/null
+++ b/gremlin-dotnet/test/pom.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.tinkerpop</groupId>
+        <artifactId>gremlin-dotnet</artifactId>
+        <version>3.2.5-SNAPSHOT</version>
+    </parent>
+    <artifactId>Gremlin-DotNet-Tests</artifactId>
+    <packaging>${packaging.type}</packaging>
+    <properties>
+        <!-- provides a way to convert maven.test.skip value to skipTests for use in skipping dotnet tests -->
+        <maven.test.skip>false</maven.test.skip>
+        <skipTests>${maven.test.skip}</skipTests>
+        <!-- this path only works when maven is started from the direct parent directory, this should be fixed -->
+        <gremlin.server.dir>${project.parent.parent.basedir}/gremlin-server</gremlin.server.dir>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>gremlin-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy</artifactId>
+            <version>${groovy.version}</version>
+            <classifier>indy</classifier>
+        </dependency>
+        <!-- TESTING -->
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>tinkergraph-gremlin</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>gremlin-test</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>gremlin-server</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <scope>test</scope>
+            <version>${slf4j.version}</version>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>gremlin-dotnet-standard</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <properties>
+                <packaging.type>pom</packaging.type>
+            </properties>
+        </profile>
+        <!-- activates the building of .NET components and requires that the .NET Core SDK be installed on the system -->
+        <profile>
+            <id>gremlin-dotnet</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <file>
+                    <exists>.glv</exists>
+                </file>
+            </activation>
+            <properties>
+                <packaging.type>dotnet-integration-test</packaging.type>
+            </properties>
+            <build>
+                <directory>${basedir}/target</directory>
+                <finalName>${project.artifactId}-${project.version}</finalName>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.eobjects.build</groupId>
+                        <artifactId>dotnet-maven-plugin</artifactId>
+                        <extensions>true</extensions>
+                        <configuration>
+                            <skip>${skipTests}</skip>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.gmavenplus</groupId>
+                        <artifactId>gmavenplus-plugin</artifactId>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.codehaus.groovy</groupId>
+                                <artifactId>groovy-all</artifactId>
+                                <version>${groovy.version}</version>
+                                <scope>runtime</scope>
+                            </dependency>
+                            <dependency>
+                                <groupId>log4j</groupId>
+                                <artifactId>log4j</artifactId>
+                                <version>1.2.17</version>
+                                <scope>runtime</scope>
+                            </dependency>
+                        </dependencies>
+                        <executions>
+                            <execution>
+                                <id>gremlin-server-start</id>
+                                <phase>pre-integration-test</phase>
+                                <goals>
+                                    <goal>execute</goal>
+                                </goals>
+                                <configuration>
+                                    <scripts>
+                                        <script>
+                                            <![CDATA[
+import org.apache.tinkerpop.gremlin.server.GremlinServer
+import org.apache.tinkerpop.gremlin.server.Settings
+import org.apache.tinkerpop.gremlin.server.Settings.ScriptEngineSettings
+
+if (${skipTests}) return
+
+log.info("Starting Gremlin Server instances for native testing of gremlin-dotnet")
+def settings = Settings.read("${gremlin.server.dir}/conf/gremlin-server-modern.yaml")
+settings.graphs.graph = "${gremlin.server.dir}/conf/tinkergraph-empty.properties"
+settings.scriptEngines["gremlin-groovy"].scripts = ["${gremlin.server.dir}/scripts/generate-modern.groovy"]
+settings.port = 45950
+
+def server = new GremlinServer(settings)
+server.start().join()
+
+project.setContextValue("gremlin.dotnet.server", server)
+log.info("Gremlin Server with no authentication started on port 45950")
+]]>
+                                        </script>
+                                    </scripts>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>gremlin-server-stop</id>
+                                <phase>post-integration-test</phase>
+                                <goals>
+                                    <goal>execute</goal>
+                                </goals>
+                                <configuration>
+                                    <scripts>
+                                        <script>
+                                            <![CDATA[
+import org.apache.tinkerpop.gremlin.server.GremlinServer
+
+if (${skipTests}) return
+
+log.info("Tests for native gremlin-dotnet complete")
+
+def server = project.getContextValue("gremlin.dotnet.server")
+log.info("Shutting down $server")
+server.stop().join()
+
+log.info("Gremlin Server instance shutdown for gremlin-dotnet")
+]]>
+                                        </script>
+                                    </scripts>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9d6192d..0c9c63b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,6 +118,8 @@ limitations under the License.
         <module>gremlin-groovy-test</module>
         <module>tinkergraph-gremlin</module>
         <module>gremlin-python</module>
+        <module>gremlin-csharp-generator</module>
+        <module>gremlin-dotnet</module>
         <module>hadoop-gremlin</module>
         <module>spark-gremlin</module>
         <module>giraph-gremlin</module>
@@ -308,6 +310,13 @@ limitations under the License.
                         <exclude>**/.glv</exclude>
                         <exclude>bin/gremlin.sh</exclude>
                         <exclude>gremlin-console/bin/gremlin.sh</exclude>
+                        <exclude>**/Debug/**</exclude>
+                        <exclude>**/Release/**</exclude>
+                        <exclude>**/obj/**</exclude>
+                        <exclude>**/*.sln</exclude>
+                        <exclude>**/*.user</exclude>
+                        <exclude>**/*.csproj</exclude>
+                        <exclude>**/.vs/**</exclude>
                     </excludes>
                     <licenses>
                         <license implementation="org.apache.rat.analysis.license.ApacheSoftwareLicense20"/>


[4/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet

Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs
new file mode 100644
index 0000000..8ce495d
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs
@@ -0,0 +1,126 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Driver.Remote
+{
+    internal class DriverRemoteTraversalSideEffects : ITraversalSideEffects
+    {
+        private readonly IGremlinClient _gremlinClient;
+        private readonly List<string> _keys = new List<string>();
+        private readonly Guid _serverSideEffectId;
+        private readonly Dictionary<string, object> _sideEffects = new Dictionary<string, object>();
+        private bool _closed;
+        private bool _retrievedAllKeys;
+
+        public DriverRemoteTraversalSideEffects(IGremlinClient gremlinClient, Guid serverSideEffectId)
+        {
+            _gremlinClient = gremlinClient;
+            _serverSideEffectId = serverSideEffectId;
+        }
+
+        public void Dispose()
+        {
+            Close();
+        }
+
+        public IReadOnlyCollection<string> Keys()
+        {
+            if (_closed && !_retrievedAllKeys)
+                throw new InvalidOperationException("Traversal has been closed - side-effect keys cannot be retrieved");
+            if (!_retrievedAllKeys)
+            {
+                _keys.AddRange(RetrieveKeys());
+                _retrievedAllKeys = true;
+            }
+            return _keys;
+        }
+
+        private IEnumerable<string> RetrieveKeys()
+        {
+            return _gremlinClient.SubmitAsync<string>(SideEffectKeysMessage()).Result;
+        }
+
+        private RequestMessage SideEffectKeysMessage()
+        {
+            return RequestMessage.Build(Tokens.OpsKeys)
+                .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId)
+                .Processor(Tokens.ProcessorTraversal)
+                .Create();
+        }
+
+        public object Get(string key)
+        {
+            if (!Keys().Contains(key))
+                throw new KeyNotFoundException($"Side effect key {key} does not exist");
+            if (!_sideEffects.ContainsKey(key))
+            {
+                if (_closed)
+                    throw new InvalidOperationException(
+                        "Traversal has been closed - no new side-effects can be retrieved");
+                _sideEffects.Add(key, RetrieveSideEffectsForKey(key));
+            }
+            return _sideEffects[key];
+        }
+
+        private object RetrieveSideEffectsForKey(string key)
+        {
+            return _gremlinClient.SubmitWithSingleResultAsync<object>(SideEffectGatherMessage(key)).Result;
+        }
+
+        private RequestMessage SideEffectGatherMessage(string key)
+        {
+            return RequestMessage.Build(Tokens.OpsGather)
+                .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId)
+                .AddArgument(Tokens.ArgsSideEffectKey, key)
+                .AddArgument(Tokens.ArgsAliases, new Dictionary<string, string> {{"g", "g"}})
+                .Processor(Tokens.ProcessorTraversal)
+                .Create();
+        }
+
+        public void Close()
+        {
+            if (_closed) return;
+            CloseSideEffects();
+            _closed = true;
+        }
+
+        private void CloseSideEffects()
+        {
+            _gremlinClient.SubmitAsync<object>(SideEffectCloseMessage()).Wait();
+        }
+
+        private RequestMessage SideEffectCloseMessage()
+        {
+            return RequestMessage.Build(Tokens.OpsClose)
+                .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId)
+                .Processor(Tokens.ProcessorTraversal)
+                .Create();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs
new file mode 100644
index 0000000..26efb5d
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+    internal class AggregatorFactory
+    {
+        private readonly Dictionary<string, IAggregator> _aggregatorByAggregateToType =
+            new Dictionary<string, IAggregator>
+            {
+                {Tokens.ValAggregateToMap, new DictionaryAggregator()},
+                {Tokens.ValAggregateToBulkSet, new TraverserAggregator()}
+            };
+
+        public IAggregator GetAggregatorFor(string aggregateTo)
+        {
+            if (_aggregatorByAggregateToType.ContainsKey(aggregateTo))
+                return _aggregatorByAggregateToType[aggregateTo];
+            return new DefaultAggregator();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs
new file mode 100644
index 0000000..82b247b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+    internal class DefaultAggregator : IAggregator
+    {
+        private readonly List<dynamic> _result = new List<dynamic>();
+
+        public void Add(object value)
+        {
+            _result.Add(value);
+        }
+
+        public object GetAggregatedResult()
+        {
+            return _result;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs
new file mode 100644
index 0000000..75764e3
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+    internal class DictionaryAggregator : IAggregator
+    {
+        private readonly Dictionary<string, dynamic> _result = new Dictionary<string, dynamic>();
+
+        public void Add(object value)
+        {
+            var newEntry = ((Dictionary<string, dynamic>) value).First();
+            _result.Add(newEntry.Key, newEntry.Value);
+        }
+
+        public object GetAggregatedResult()
+        {
+            return _result;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs
new file mode 100644
index 0000000..bcc036a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs
@@ -0,0 +1,31 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+    internal interface IAggregator
+    {
+        void Add(object value);
+        object GetAggregatedResult();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs
new file mode 100644
index 0000000..2d18804
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Driver.ResultsAggregation
+{
+    internal class TraverserAggregator : IAggregator
+    {
+        private readonly Dictionary<object, long> _result = new Dictionary<object, long>();
+
+        public void Add(object value)
+        {
+            var traverser = (Traverser) value;
+            _result.Add(traverser.Object, traverser.Bulk);
+        }
+
+        public object GetAggregatedResult()
+        {
+            return _result;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
new file mode 100644
index 0000000..5a940cd
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
@@ -0,0 +1,114 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+    /// <summary>
+    ///     String constants used to configure a <see cref="RequestMessage" />.
+    /// </summary>
+    public class Tokens
+    {
+        /// <summary>
+        ///     Operation used for a request that contains the Bytecode representation of a Traversal.
+        /// </summary>
+        public static string OpsBytecode = "bytecode";
+
+        /// <summary>
+        ///     Operation used to evaluate a Gremlin script provided as a string.
+        /// </summary>
+        public static string OpsEval = "eval";
+
+        /// <summary>
+        ///     Operation used to get a particular side-effect as produced by a previously executed Traversal.
+        /// </summary>
+        public static string OpsGather = "gather";
+
+        /// <summary>
+        ///     Operation used to get all the keys of all side-effects as produced by a previously executed Traversal.
+        /// </summary>
+        public static string OpsKeys = "keys";
+
+        /// <summary>
+        ///     Operation used to get all the keys of all side-effects as produced by a previously executed Traversal.
+        /// </summary>
+        public static string OpsClose = "close";
+
+        /// <summary>
+        ///     Default OpProcessor.
+        /// </summary>
+        public static string ProcessorTraversal = "traversal";
+
+        /// <summary>
+        ///     Argument name that allows to defines the number of iterations each ResponseMessage should contain - overrides the
+        ///     resultIterationBatchSize server setting.
+        /// </summary>
+        public static string ArgsBatchSize = "batchSize";
+
+        /// <summary>
+        ///     Argument name that allows to provide a map of key/value pairs to apply as variables in the context of the Gremlin
+        ///     script.
+        /// </summary>
+        public static string ArgsBindings = "bindings";
+
+        /// <summary>
+        ///     Argument name that allows to define aliases that represent globally bound Graph and TraversalSource objects.
+        /// </summary>
+        public static string ArgsAliases = "aliases";
+
+        /// <summary>
+        ///     Argument name that corresponds to the Traversal to evaluate.
+        /// </summary>
+        public static string ArgsGremlin = "gremlin";
+
+        /// <summary>
+        ///     Argument name that allows to specify the unique identifier for the request.
+        /// </summary>
+        public static string ArgsSideEffect = "sideEffect";
+
+        /// <summary>
+        ///     Argument name that allows to specify the key for a specific side-effect.
+        /// </summary>
+        public static string ArgsSideEffectKey = "sideEffectKey";
+
+        /// <summary>
+        ///     <see cref="ResponseMessage{T}" /> argument that describes how side-effect data should be treated.
+        /// </summary>
+        public static string ArgsAggregateTo = "aggregateTo";
+
+        /// <summary>
+        ///     Argument name that allows to change the flavor of Gremlin used (e.g. gremlin-groovy).
+        /// </summary>
+        public static string ArgsLanguage = "language";
+
+        /// <summary>
+        ///     Argument name that allows to override the server setting that determines the maximum time to wait for a script to
+        ///     execute on the server.
+        /// </summary>
+        public static string ArgsEvalTimeout = "scriptEvaluationTimeout";
+
+        internal static string ValAggregateToMap = "map";
+        internal static string ValAggregateToBulkSet = "bulkset";
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
new file mode 100644
index 0000000..5a20759
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
@@ -0,0 +1,96 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.IO;
+using System.Net.WebSockets;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Driver
+{
+    internal class WebSocketConnection : IDisposable
+    {
+        private const int ReceiveBufferSize = 1024;
+        private const WebSocketMessageType MessageType = WebSocketMessageType.Binary;
+        private ClientWebSocket _client;
+
+        public async Task ConnectAsync(Uri uri)
+        {
+            _client = new ClientWebSocket();
+            await _client.ConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
+        }
+
+        public async Task CloseAsync()
+        {
+            await
+                _client.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None)
+                    .ConfigureAwait(false);
+        }
+
+        public async Task SendMessageAsync(byte[] message)
+        {
+            await
+                _client.SendAsync(new ArraySegment<byte>(message), MessageType, true, CancellationToken.None)
+                    .ConfigureAwait(false);
+        }
+
+        public async Task<byte[]> ReceiveMessageAsync()
+        {
+            using (var ms = new MemoryStream())
+            {
+                WebSocketReceiveResult received;
+                do
+                {
+                    var receiveBuffer = new ArraySegment<byte>(new byte[ReceiveBufferSize]);
+                    received = await _client.ReceiveAsync(receiveBuffer, CancellationToken.None).ConfigureAwait(false);
+                    ms.Write(receiveBuffer.Array, receiveBuffer.Offset, received.Count);
+                } while (!received.EndOfMessage);
+
+                return ms.ToArray();
+            }
+        }
+
+        #region IDisposable Support
+
+        private bool _disposed;
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                    _client?.Dispose();
+                _disposed = true;
+            }
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
new file mode 100644
index 0000000..a909ad1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
@@ -0,0 +1,43 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  
+  <PropertyGroup>
+    <Description>Gremlin.Net is a cross-platform Gremlin Server driver for .NET that is written in C#. It uses WebSockets to communicate with Gremlin Server.</Description>
+    <AssemblyTitle>Gremlin.Net</AssemblyTitle>
+    <Authors>Apache TinkerPop</Authors>
+    <TargetFramework>netstandard1.3</TargetFramework>
+    <Version>3.2.5-SNAPSHOT</Version>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
+    <AssemblyName>Gremlin.Net</AssemblyName>
+    <PackageId>Gremlin.Net</PackageId>
+    <PackageTags>gremlin-dotnet;gremlin;tinkerpop;tinkerpop3</PackageTags>
+    <PackageProjectUrl>http://tinkerpop.apache.org</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/apache/tinkerpop/blob/master/LICENSE</PackageLicenseUrl>
+    <RepositoryUrl>https://github.com/apache/tinkerpop</RepositoryUrl>
+    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+    <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
+  </PropertyGroup>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DocumentationFile />
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="System.Collections" Version="4.3.0" />
+    <PackageReference Include="System.Linq" Version="4.3.0" />
+    <PackageReference Include="System.Runtime" Version="4.3.0" />
+    <PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
+    <PackageReference Include="System.Threading" Version="4.3.0" />
+    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
+    <PackageReference Include="System.Net.WebSockets" Version="4.3.0" />
+    <PackageReference Include="System.Net.WebSockets.Client" Version="4.3.0" />
+    <PackageReference Include="System.Collections.Concurrent" Version="4.3.0" />
+    <PackageReference Include="System.Reflection.TypeExtensions" Version="4.3.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+  </ItemGroup>
+
+</Project>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs b/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..433db19
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Gremlin.Net")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("6c1dd34d-e30f-4e37-aacc-beb8ad2320d8")]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs
new file mode 100644
index 0000000..fddbd69
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs
@@ -0,0 +1,61 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Structure
+{
+    /// <summary>
+    ///     Represents an edge between to vertices.
+    /// </summary>
+    public class Edge : Element
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Edge" /> class.
+        /// </summary>
+        /// <param name="id">The id of the edge.</param>
+        /// <param name="outV">The outgoing/tail vertex of the edge.</param>
+        /// <param name="label">The label of the edge.</param>
+        /// <param name="inV">The incoming/head vertex of the edge.</param>
+        public Edge(object id, Vertex outV, string label, Vertex inV)
+            : base(id, label)
+        {
+            OutV = outV;
+            InV = inV;
+        }
+
+        /// <summary>
+        ///     Gets or sets the incoming/head vertex of this edge.
+        /// </summary>
+        public Vertex InV { get; set; }
+
+        /// <summary>
+        ///     Gets or sets the outgoing/tail vertex of this edge.
+        /// </summary>
+        public Vertex OutV { get; set; }
+
+        /// <inheritdoc />
+        public override string ToString()
+        {
+            return $"e[{Id}][{OutV.Id}-{Label}->{InV.Id}]";
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs
new file mode 100644
index 0000000..f4fc847
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs
@@ -0,0 +1,77 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure
+{
+    /// <summary>
+    ///     A common base class for Graph elements.
+    /// </summary>
+    public abstract class Element : IEquatable<Element>
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Element" /> class.
+        /// </summary>
+        /// <param name="id">The id of the element.</param>
+        /// <param name="label">The label of the element.</param>
+        protected Element(object id, string label)
+        {
+            Id = id;
+            Label = label;
+        }
+
+        /// <summary>
+        ///     Gets the id of this <see cref="Element" />.
+        /// </summary>
+        public object Id { get; }
+
+        /// <summary>
+        ///     Gets the label of this <see cref="Element" />.
+        /// </summary>
+        public string Label { get; }
+
+        /// <inheritdoc />
+        public bool Equals(Element other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return Equals(Id, other.Id);
+        }
+
+        /// <inheritdoc />
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != GetType()) return false;
+            return Equals((Element) obj);
+        }
+
+        /// <inheritdoc />
+        public override int GetHashCode()
+        {
+            return Id.GetHashCode();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs
new file mode 100644
index 0000000..d183447
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class BindingSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            var binding = (Binding) objectData;
+            var valueDict = new Dictionary<string, object>
+            {
+                {"value", writer.ToDict(binding.Value)},
+                {"key", binding.Key}
+            };
+            return GraphSONUtil.ToTypedValue(nameof(Binding), valueDict);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs
new file mode 100644
index 0000000..28cfe0a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs
@@ -0,0 +1,58 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class BytecodeSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic bytecodeObj, GraphSONWriter writer)
+        {
+            Bytecode bytecode = bytecodeObj;
+
+            var valueDict = new Dictionary<string, IEnumerable<IEnumerable<dynamic>>>();
+            if (bytecode.SourceInstructions.Count > 0)
+                valueDict["source"] = DictifyInstructions(bytecode.SourceInstructions, writer);
+            if (bytecode.StepInstructions.Count > 0)
+                valueDict["step"] = DictifyInstructions(bytecode.StepInstructions, writer);
+
+            return GraphSONUtil.ToTypedValue(nameof(Bytecode), valueDict);
+        }
+
+        private IEnumerable<IEnumerable<dynamic>> DictifyInstructions(IEnumerable<Instruction> instructions,
+            GraphSONWriter writer)
+        {
+            return instructions.Select(instruction => DictifyInstruction(instruction, writer));
+        }
+
+        private IEnumerable<dynamic> DictifyInstruction(Instruction instruction, GraphSONWriter writer)
+        {
+            var result = new List<dynamic> {instruction.OperatorName};
+            result.AddRange(instruction.Arguments.Select(arg => writer.ToDict(arg)));
+            return result;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
new file mode 100644
index 0000000..d8879f8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class DateDeserializer : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            var javaTimestamp = graphsonObject.ToObject<long>();
+            return FromJavaTime(javaTimestamp);
+        }
+
+        private DateTime FromJavaTime(long javaTimestamp)
+        {
+            var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+            return epoch.AddMilliseconds(javaTimestamp);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs
new file mode 100644
index 0000000..1438e02
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class DateSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            DateTime dateTime = objectData;
+            return GraphSONUtil.ToTypedValue("Date", ToJavaTimestamp(dateTime));
+        }
+
+        private long ToJavaTimestamp(DateTime dateTime)
+        {
+            var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+            return Convert.ToInt64((dateTime - epoch).TotalMilliseconds);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
new file mode 100644
index 0000000..416423b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class DoubleConverter : NumberConverter
+    {
+        protected override string GraphSONTypeName => "Double";
+        protected override Type HandledType => typeof(double);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
new file mode 100644
index 0000000..6ec8694
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class EdgeDeserializer : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            var outVId = reader.ToObject(graphsonObject["outV"]);
+            var outVLabel = (string) (graphsonObject["outVLabel"] ?? Vertex.DefaultLabel);
+            var outV = new Vertex(outVId, outVLabel);
+            var inVId = reader.ToObject(graphsonObject["inV"]);
+            var inVLabel = (string) (graphsonObject["inVLabel"] ?? Vertex.DefaultLabel);
+            var inV = new Vertex(inVId, inVLabel);
+            var edgeId = reader.ToObject(graphsonObject["id"]);
+            var edgeLabel = (string) graphsonObject["label"] ?? "edge";
+            return new Edge(edgeId, outV, edgeLabel, inV);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs
new file mode 100644
index 0000000..fd9f496
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs
@@ -0,0 +1,45 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class EdgeSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            Edge edge = objectData;
+            var edgeDict = new Dictionary<string, dynamic>
+            {
+                {"id", writer.ToDict(edge.Id)},
+                {"outV", writer.ToDict(edge.OutV.Id)},
+                {"outVLabel", edge.OutV.Label},
+                {"label", edge.Label},
+                {"inV", writer.ToDict(edge.InV.Id)},
+                {"inVLabel", edge.InV.Label}
+            };
+            return GraphSONUtil.ToTypedValue(nameof(Edge), edgeDict);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs
new file mode 100644
index 0000000..6ed3cd4
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class EnumSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            var enumName = objectData.GetType().Name;
+            var enumValue = objectData.ToString();
+            return GraphSONUtil.ToTypedValue(enumName, enumValue);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
new file mode 100644
index 0000000..432aeab
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class FloatConverter : NumberConverter
+    {
+        protected override string GraphSONTypeName => "Float";
+        protected override Type HandledType => typeof(float);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
new file mode 100644
index 0000000..aa1fc48
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
@@ -0,0 +1,123 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    /// <summary>
+    ///     Allows to deserialize GraphSON to objects.
+    /// </summary>
+    public class GraphSONReader
+    {
+        private readonly Dictionary<string, IGraphSONDeserializer> _deserializerByGraphSONType = new Dictionary
+            <string, IGraphSONDeserializer>
+            {
+                {"g:Traverser", new TraverserReader()},
+                {"g:Int32", new Int32Converter()},
+                {"g:Int64", new Int64Converter()},
+                {"g:Float", new FloatConverter()},
+                {"g:Double", new DoubleConverter()},
+                {"g:UUID", new UuidDeserializer()},
+                {"g:Date", new DateDeserializer()},
+                {"g:Timestamp", new DateDeserializer()},
+                {"g:Vertex", new VertexDeserializer()},
+                {"g:Edge", new EdgeDeserializer()},
+                {"g:Property", new PropertyDeserializer()},
+                {"g:VertexProperty", new VertexPropertyDeserializer()},
+                {"g:Path", new PathDeserializer()}
+            };
+
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="GraphSONReader" /> class.
+        /// </summary>
+        public GraphSONReader()
+        {
+        }
+
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="GraphSONReader" /> class.
+        /// </summary>
+        /// <param name="deserializerByGraphSONType">
+        ///     <see cref="IGraphSONDeserializer" /> deserializers identified by their
+        ///     GraphSON type.
+        /// </param>
+        public GraphSONReader(IReadOnlyDictionary<string, IGraphSONDeserializer> deserializerByGraphSONType)
+        {
+            foreach (var deserializerAndGraphSONType in deserializerByGraphSONType)
+                _deserializerByGraphSONType[deserializerAndGraphSONType.Key] = deserializerAndGraphSONType.Value;
+        }
+
+        /// <summary>
+        ///     Deserializes a GraphSON collection to an object.
+        /// </summary>
+        /// <param name="graphSonData">The GraphSON collection to deserialize.</param>
+        /// <returns>The deserialized object.</returns>
+        public dynamic ToObject(IEnumerable<JToken> graphSonData)
+        {
+            return graphSonData.Select(graphson => ToObject(graphson));
+        }
+
+        /// <summary>
+        ///     Deserializes GraphSON to an object.
+        /// </summary>
+        /// <param name="jToken">The GraphSON to deserialize.</param>
+        /// <returns>The deserialized object.</returns>
+        public dynamic ToObject(JToken jToken)
+        {
+            if (jToken is JArray)
+                return jToken.Select(t => ToObject(t));
+            if (!jToken.HasValues) return ((JValue) jToken).Value;
+            if (!HasTypeKey(jToken)) return ReadDictionary(jToken);
+            return ReadTypedValue(jToken);
+        }
+
+        private bool HasTypeKey(JToken jToken)
+        {
+            var graphSONType = (string) jToken[GraphSONTokens.TypeKey];
+            return graphSONType != null;
+        }
+
+        private dynamic ReadTypedValue(JToken typedValue)
+        {
+            var graphSONType = (string) typedValue[GraphSONTokens.TypeKey];
+            return _deserializerByGraphSONType[graphSONType].Objectify(typedValue[GraphSONTokens.ValueKey], this);
+        }
+
+        private dynamic ReadDictionary(JToken jtokenDict)
+        {
+            var dict = new Dictionary<string, dynamic>();
+            foreach (var e in jtokenDict)
+            {
+                var property = e as JProperty;
+                if (property == null)
+                    throw new InvalidOperationException($"Cannot read graphson: {jtokenDict}");
+                dict.Add(property.Name, ToObject(property.Value));
+            }
+            return dict;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs
new file mode 100644
index 0000000..8beb850
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class GraphSONTokens
+    {
+        public static string TypeKey = "@type";
+        public static string ValueKey = "@value";
+        public static string GremlinTypeNamespace = "g";
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs
new file mode 100644
index 0000000..037839b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs
@@ -0,0 +1,62 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    /// <summary>
+    ///     Provides helper methods for GraphSON serialization.
+    /// </summary>
+    public static class GraphSONUtil
+    {
+        /// <summary>
+        ///     Transforms a value intos its GraphSON representation including type information.
+        /// </summary>
+        /// <param name="typename">The name of the type.</param>
+        /// <param name="value">The value to transform.</param>
+        /// <param name="prefix">A namespace prefix for the typename.</param>
+        /// <returns>The GraphSON representation including type information.</returns>
+        public static Dictionary<string, dynamic> ToTypedValue(string typename, dynamic value, string prefix = "g")
+        {
+            var typedValue = new Dictionary<string, dynamic>
+            {
+                {GraphSONTokens.TypeKey, FormatTypeName(prefix, typename)}
+            };
+            if (value != null)
+                typedValue[GraphSONTokens.ValueKey] = value;
+            return typedValue;
+        }
+
+        /// <summary>
+        ///     Formats a type name with its prefix to a GraphSON TypeID.
+        /// </summary>
+        /// <param name="namespacePrefix">The namespace prefix (default is "g").</param>
+        /// <param name="typeName">The name of the type.</param>
+        /// <returns>The formatted TypeID.</returns>
+        public static string FormatTypeName(string namespacePrefix, string typeName)
+        {
+            return $"{namespacePrefix}:{typeName}";
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
new file mode 100644
index 0000000..ba632b1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
@@ -0,0 +1,146 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Process.Traversal.Strategy;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    /// <summary>
+    ///     Allows to serialize objects to GraphSON.
+    /// </summary>
+    public class GraphSONWriter
+    {
+        private readonly Dictionary<Type, IGraphSONSerializer> _serializerByType = new Dictionary
+            <Type, IGraphSONSerializer>
+            {
+                {typeof(ITraversal), new TraversalSerializer()},
+                {typeof(Bytecode), new BytecodeSerializer()},
+                {typeof(Binding), new BindingSerializer()},
+                {typeof(RequestMessage), new RequestMessageSerializer()},
+                {typeof(int), new Int32Converter()},
+                {typeof(long), new Int64Converter()},
+                {typeof(float), new FloatConverter()},
+                {typeof(double), new DoubleConverter()},
+                {typeof(Guid), new UuidSerializer()},
+                {typeof(DateTime), new DateSerializer()},
+                {typeof(Enum), new EnumSerializer()},
+                {typeof(TraversalPredicate), new TraversalPredicateSerializer()},
+                {typeof(Vertex), new VertexSerializer()},
+                {typeof(Edge), new EdgeSerializer()},
+                {typeof(Property), new PropertySerializer()},
+                {typeof(VertexProperty), new VertexPropertySerializer()},
+                {typeof(AbstractTraversalStrategy), new TraversalStrategySerializer()}
+            };
+
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="GraphSONWriter" /> class.
+        /// </summary>
+        public GraphSONWriter()
+        {
+        }
+
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="GraphSONWriter" /> class.
+        /// </summary>
+        /// <param name="customSerializerByType">
+        ///     <see cref="IGraphSONSerializer" /> serializers identified by their
+        ///     <see cref="Type" />.
+        /// </param>
+        public GraphSONWriter(IReadOnlyDictionary<Type, IGraphSONSerializer> customSerializerByType)
+        {
+            foreach (var serializerAndType in customSerializerByType)
+                _serializerByType[serializerAndType.Key] = serializerAndType.Value;
+        }
+
+        /// <summary>
+        ///     Serializes an object to GraphSON.
+        /// </summary>
+        /// <param name="objectData">The object to serialize.</param>
+        /// <returns>The serialized GraphSON.</returns>
+        public string WriteObject(dynamic objectData)
+        {
+            return JsonConvert.SerializeObject(ToDict(objectData));
+        }
+
+        internal dynamic ToDict(dynamic objectData)
+        {
+            var type = objectData.GetType();
+            if (TryGetSerializerFor(out IGraphSONSerializer serializer, type))
+                return serializer.Dictify(objectData, this);
+            if (IsDictionaryType(type))
+                return DictToGraphSONDict(objectData);
+            if (IsCollectionType(type))
+                return CollectionToGraphSONCollection(objectData);
+            return objectData;
+        }
+
+        private bool TryGetSerializerFor(out IGraphSONSerializer serializer, Type type)
+        {
+            if (_serializerByType.ContainsKey(type))
+            {
+                serializer = _serializerByType[type];
+                return true;
+            }
+            foreach (var supportedType in _serializerByType.Keys)
+                if (supportedType.IsAssignableFrom(type))
+                {
+                    serializer = _serializerByType[supportedType];
+                    return true;
+                }
+            serializer = null;
+            return false;
+        }
+
+        private bool IsDictionaryType(Type type)
+        {
+            return type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>);
+        }
+
+        private Dictionary<string, dynamic> DictToGraphSONDict(dynamic dict)
+        {
+            var graphSONDict = new Dictionary<string, dynamic>();
+            foreach (var keyValue in dict)
+                graphSONDict.Add(ToDict(keyValue.Key), ToDict(keyValue.Value));
+            return graphSONDict;
+        }
+
+        private bool IsCollectionType(Type type)
+        {
+            return type.GetInterfaces().Contains(typeof(ICollection));
+        }
+
+        private IEnumerable<dynamic> CollectionToGraphSONCollection(dynamic collection)
+        {
+            foreach (var e in collection)
+                yield return ToDict(e);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
new file mode 100644
index 0000000..b15b169
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    /// <summary>
+    ///     Supports deserializing GraphSON into an object.
+    /// </summary>
+    public interface IGraphSONDeserializer
+    {
+        /// <summary>
+        ///     Deserializes GraphSON to an object.
+        /// </summary>
+        /// <param name="graphsonObject">The GraphSON object to objectify.</param>
+        /// <param name="reader">A <see cref="GraphSONReader" /> that can be used to objectify properties of the GraphSON object.</param>
+        /// <returns>The deserialized object.</returns>
+        dynamic Objectify(JToken graphsonObject, GraphSONReader reader);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs
new file mode 100644
index 0000000..f5faf84
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    /// <summary>
+    ///     Supports serializing of an object to GraphSON.
+    /// </summary>
+    public interface IGraphSONSerializer
+    {
+        /// <summary>
+        ///     Transforms an object into a dictionary that resembles its GraphSON representation.
+        /// </summary>
+        /// <param name="objectData">The object to dictify.</param>
+        /// <param name="writer">A <see cref="GraphSONWriter" /> that can be used to dictify properties of the object.</param>
+        /// <returns>The GraphSON representation.</returns>
+        Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
new file mode 100644
index 0000000..052f938
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class Int32Converter : NumberConverter
+    {
+        protected override string GraphSONTypeName => "Int32";
+        protected override Type HandledType => typeof(int);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
new file mode 100644
index 0000000..dd0160f
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class Int64Converter : NumberConverter
+    {
+        protected override string GraphSONTypeName => "Int64";
+        protected override Type HandledType => typeof(long);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
new file mode 100644
index 0000000..579d202
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
@@ -0,0 +1,45 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal abstract class NumberConverter : IGraphSONDeserializer, IGraphSONSerializer
+    {
+        protected abstract string GraphSONTypeName { get; }
+        protected abstract Type HandledType { get; }
+
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            return graphsonObject.ToObject(HandledType);
+        }
+
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            return GraphSONUtil.ToTypedValue(GraphSONTypeName, objectData);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
new file mode 100644
index 0000000..afdf07c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Linq;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class PathDeserializer : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            var labels =
+                graphsonObject["labels"]
+                    .Select(readObjLabels => readObjLabels.Select(l => (string) l).ToList())
+                    .ToList();
+            var objects = graphsonObject["objects"].Select(o => reader.ToObject(o)).ToList();
+            return new Path(labels, objects);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
new file mode 100644
index 0000000..11f160e
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
@@ -0,0 +1,38 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class PropertyDeserializer : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            var key = (string) graphsonObject["key"];
+            var value = reader.ToObject(graphsonObject["value"]);
+            var element = graphsonObject["element"] != null ? reader.ToObject(graphsonObject["element"]) : null;
+            return new Property(key, value, element);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs
new file mode 100644
index 0000000..0a7e6f8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs
@@ -0,0 +1,64 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class PropertySerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            Property property = objectData;
+            var elementDict = CreateElementDict(property.Element, writer);
+            var valueDict = new Dictionary<string, dynamic>
+            {
+                {"key", property.Key},
+                {"value", writer.ToDict(property.Value)},
+                {"element", elementDict}
+            };
+            return GraphSONUtil.ToTypedValue(nameof(Property), valueDict);
+        }
+
+        private dynamic CreateElementDict(Element element, GraphSONWriter writer)
+        {
+            if (element == null)
+                return null;
+            var serializedElement = writer.ToDict(element);
+            Dictionary<string, dynamic> elementDict = serializedElement;
+            if (elementDict.ContainsKey(GraphSONTokens.ValueKey))
+            {
+                var elementValueSerialized = elementDict[GraphSONTokens.ValueKey];
+                Dictionary<string, dynamic> elementValueDict = elementValueSerialized;
+                if (elementValueDict != null)
+                {
+                    elementValueDict.Remove("outVLabel");
+                    elementValueDict.Remove("inVLabel");
+                    elementValueDict.Remove("properties");
+                    elementValueDict.Remove("value");
+                }
+            }
+            return serializedElement;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs
new file mode 100644
index 0000000..b796423
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class RequestMessageSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            RequestMessage msg = objectData;
+            return new Dictionary<string, dynamic>
+            {
+                {"requestId", writer.ToDict(msg.RequestId)},
+                {"op", msg.Operation},
+                {"processor", msg.Processor},
+                {"args", writer.ToDict(msg.Arguments)}
+            };
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs
new file mode 100644
index 0000000..937cb90
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs
@@ -0,0 +1,45 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class TraversalPredicateSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic predicate, GraphSONWriter writer)
+        {
+            TraversalPredicate p = predicate;
+            var value = p.Other == null
+                ? writer.ToDict(p.Value)
+                : new List<dynamic> {writer.ToDict(p.Value), writer.ToDict(p.Other)};
+            var dict = new Dictionary<string, dynamic>
+            {
+                {"predicate", p.OperatorName},
+                {"value", value}
+            };
+            return GraphSONUtil.ToTypedValue("P", dict);
+        }
+    }
+}
\ No newline at end of file


[6/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet

Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversalSource.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversalSource.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversalSource.cs
new file mode 100644
index 0000000..e68fdee
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversalSource.cs
@@ -0,0 +1,143 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Remote;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+
+namespace Gremlin.CSharp.Process
+{
+    public class GraphTraversalSource
+    {
+        public ICollection<ITraversalStrategy> TraversalStrategies { get; set; }
+        public Bytecode Bytecode { get; set; }
+
+         public GraphTraversalSource()
+            : this(new List<ITraversalStrategy>(), new Bytecode())
+        {
+        }
+
+        public GraphTraversalSource(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode)
+        {
+            TraversalStrategies = traversalStrategies;
+            Bytecode = bytecode;
+        }
+
+        public GraphTraversalSource WithBulk(params object[] args)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withBulk", args);
+            return source;
+        }
+
+        public GraphTraversalSource WithPath(params object[] args)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withPath", args);
+            return source;
+        }
+
+        public GraphTraversalSource WithSack(params object[] args)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withSack", args);
+            return source;
+        }
+
+        public GraphTraversalSource WithSideEffect(params object[] args)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withSideEffect", args);
+            return source;
+        }
+
+        public GraphTraversalSource WithStrategies(params object[] args)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withStrategies", args);
+            return source;
+        }
+
+        public GraphTraversalSource WithoutStrategies(params object[] args)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withoutStrategies", args);
+            return source;
+        }
+
+        public GraphTraversalSource WithBindings(object bindings)
+        {
+            return this;
+        }
+
+        public GraphTraversalSource WithRemote(IRemoteConnection remoteConnection)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.TraversalStrategies.Add(new RemoteStrategy(remoteConnection));
+            return source;
+        }
+        
+        public GraphTraversalSource WithComputer(string graphComputer = null, int? workers = null, string persist = null,
+            string result = null, ITraversal vertices = null, ITraversal edges = null,
+            Dictionary<string, dynamic> configuration = null)
+        {
+            return WithStrategies(new VertexProgramStrategy(graphComputer, workers, persist, result, vertices, edges, configuration));
+        }
+
+        public GraphTraversal E(params object[] args)
+        {
+            var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+            traversal.Bytecode.AddStep("E", args);
+            return traversal;
+        }
+
+        public GraphTraversal V(params object[] args)
+        {
+            var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+            traversal.Bytecode.AddStep("V", args);
+            return traversal;
+        }
+
+        public GraphTraversal AddV(params object[] args)
+        {
+            var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+            traversal.Bytecode.AddStep("addV", args);
+            return traversal;
+        }
+
+        public GraphTraversal Inject(params object[] args)
+        {
+            var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+            traversal.Bytecode.AddStep("inject", args);
+            return traversal;
+        }
+	}
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Operator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Operator.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Operator.cs
new file mode 100644
index 0000000..5a9f805
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Operator.cs
@@ -0,0 +1,40 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Operator
+    {
+        addAll,
+        and,
+        assign,
+        div,
+        max,
+        min,
+        minus,
+        mult,
+        or,
+        sum,
+        sumLong
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Order.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Order.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Order.cs
new file mode 100644
index 0000000..1a30c7d
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Order.cs
@@ -0,0 +1,36 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Order
+    {
+        decr,
+        incr,
+        keyDecr,
+        keyIncr,
+        shuffle,
+        valueDecr,
+        valueIncr
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs
new file mode 100644
index 0000000..62282b7
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs
@@ -0,0 +1,108 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.CSharp.Process
+{
+    public class P
+    {
+        public static TraversalPredicate Between(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("between", value);
+        }
+
+        public static TraversalPredicate Eq(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("eq", value);
+        }
+
+        public static TraversalPredicate Gt(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("gt", value);
+        }
+
+        public static TraversalPredicate Gte(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("gte", value);
+        }
+
+        public static TraversalPredicate Inside(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("inside", value);
+        }
+
+        public static TraversalPredicate Lt(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("lt", value);
+        }
+
+        public static TraversalPredicate Lte(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("lte", value);
+        }
+
+        public static TraversalPredicate Neq(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("neq", value);
+        }
+
+        public static TraversalPredicate Not(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("not", value);
+        }
+
+        public static TraversalPredicate Outside(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("outside", value);
+        }
+
+        public static TraversalPredicate Test(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("test", value);
+        }
+
+        public static TraversalPredicate Within(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("within", value);
+        }
+
+        public static TraversalPredicate Without(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("without", value);
+        }
+	}
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Pick.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Pick.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Pick.cs
new file mode 100644
index 0000000..17c27d7
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Pick.cs
@@ -0,0 +1,31 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Pick
+    {
+        any,
+        none
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Pop.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Pop.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Pop.cs
new file mode 100644
index 0000000..4e14d94
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Pop.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Pop
+    {
+        all,
+        first,
+        last
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Scope.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Scope.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Scope.cs
new file mode 100644
index 0000000..a9578ee
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Scope.cs
@@ -0,0 +1,31 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Scope
+    {
+        global,
+        local
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs
new file mode 100644
index 0000000..4bf9062
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum T
+    {
+        id,
+        key,
+        label,
+        value
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs
new file mode 100644
index 0000000..2db0082
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs
@@ -0,0 +1,488 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public static class __
+    {
+        public static GraphTraversal Start()
+        {
+            return new GraphTraversal();
+        }
+
+        public static GraphTraversal V(params object[] args)
+        {
+            return new GraphTraversal().V(args);
+        }
+
+        public static GraphTraversal AddE(params object[] args)
+        {
+            return new GraphTraversal().AddE(args);
+        }
+
+        public static GraphTraversal AddInE(params object[] args)
+        {
+            return new GraphTraversal().AddInE(args);
+        }
+
+        public static GraphTraversal AddOutE(params object[] args)
+        {
+            return new GraphTraversal().AddOutE(args);
+        }
+
+        public static GraphTraversal AddV(params object[] args)
+        {
+            return new GraphTraversal().AddV(args);
+        }
+
+        public static GraphTraversal Aggregate(params object[] args)
+        {
+            return new GraphTraversal().Aggregate(args);
+        }
+
+        public static GraphTraversal And(params object[] args)
+        {
+            return new GraphTraversal().And(args);
+        }
+
+        public static GraphTraversal As(params object[] args)
+        {
+            return new GraphTraversal().As(args);
+        }
+
+        public static GraphTraversal Barrier(params object[] args)
+        {
+            return new GraphTraversal().Barrier(args);
+        }
+
+        public static GraphTraversal Both(params object[] args)
+        {
+            return new GraphTraversal().Both(args);
+        }
+
+        public static GraphTraversal BothE(params object[] args)
+        {
+            return new GraphTraversal().BothE(args);
+        }
+
+        public static GraphTraversal BothV(params object[] args)
+        {
+            return new GraphTraversal().BothV(args);
+        }
+
+        public static GraphTraversal Branch(params object[] args)
+        {
+            return new GraphTraversal().Branch(args);
+        }
+
+        public static GraphTraversal Cap(params object[] args)
+        {
+            return new GraphTraversal().Cap(args);
+        }
+
+        public static GraphTraversal Choose(params object[] args)
+        {
+            return new GraphTraversal().Choose(args);
+        }
+
+        public static GraphTraversal Coalesce(params object[] args)
+        {
+            return new GraphTraversal().Coalesce(args);
+        }
+
+        public static GraphTraversal Coin(params object[] args)
+        {
+            return new GraphTraversal().Coin(args);
+        }
+
+        public static GraphTraversal Constant(params object[] args)
+        {
+            return new GraphTraversal().Constant(args);
+        }
+
+        public static GraphTraversal Count(params object[] args)
+        {
+            return new GraphTraversal().Count(args);
+        }
+
+        public static GraphTraversal CyclicPath(params object[] args)
+        {
+            return new GraphTraversal().CyclicPath(args);
+        }
+
+        public static GraphTraversal Dedup(params object[] args)
+        {
+            return new GraphTraversal().Dedup(args);
+        }
+
+        public static GraphTraversal Drop(params object[] args)
+        {
+            return new GraphTraversal().Drop(args);
+        }
+
+        public static GraphTraversal Emit(params object[] args)
+        {
+            return new GraphTraversal().Emit(args);
+        }
+
+        public static GraphTraversal Filter(params object[] args)
+        {
+            return new GraphTraversal().Filter(args);
+        }
+
+        public static GraphTraversal FlatMap(params object[] args)
+        {
+            return new GraphTraversal().FlatMap(args);
+        }
+
+        public static GraphTraversal Fold(params object[] args)
+        {
+            return new GraphTraversal().Fold(args);
+        }
+
+        public static GraphTraversal Group(params object[] args)
+        {
+            return new GraphTraversal().Group(args);
+        }
+
+        public static GraphTraversal GroupCount(params object[] args)
+        {
+            return new GraphTraversal().GroupCount(args);
+        }
+
+        public static GraphTraversal GroupV3d0(params object[] args)
+        {
+            return new GraphTraversal().GroupV3d0(args);
+        }
+
+        public static GraphTraversal Has(params object[] args)
+        {
+            return new GraphTraversal().Has(args);
+        }
+
+        public static GraphTraversal HasId(params object[] args)
+        {
+            return new GraphTraversal().HasId(args);
+        }
+
+        public static GraphTraversal HasKey(params object[] args)
+        {
+            return new GraphTraversal().HasKey(args);
+        }
+
+        public static GraphTraversal HasLabel(params object[] args)
+        {
+            return new GraphTraversal().HasLabel(args);
+        }
+
+        public static GraphTraversal HasNot(params object[] args)
+        {
+            return new GraphTraversal().HasNot(args);
+        }
+
+        public static GraphTraversal HasValue(params object[] args)
+        {
+            return new GraphTraversal().HasValue(args);
+        }
+
+        public static GraphTraversal Id(params object[] args)
+        {
+            return new GraphTraversal().Id(args);
+        }
+
+        public static GraphTraversal Identity(params object[] args)
+        {
+            return new GraphTraversal().Identity(args);
+        }
+
+        public static GraphTraversal In(params object[] args)
+        {
+            return new GraphTraversal().In(args);
+        }
+
+        public static GraphTraversal InE(params object[] args)
+        {
+            return new GraphTraversal().InE(args);
+        }
+
+        public static GraphTraversal InV(params object[] args)
+        {
+            return new GraphTraversal().InV(args);
+        }
+
+        public static GraphTraversal Inject(params object[] args)
+        {
+            return new GraphTraversal().Inject(args);
+        }
+
+        public static GraphTraversal Is(params object[] args)
+        {
+            return new GraphTraversal().Is(args);
+        }
+
+        public static GraphTraversal Key(params object[] args)
+        {
+            return new GraphTraversal().Key(args);
+        }
+
+        public static GraphTraversal Label(params object[] args)
+        {
+            return new GraphTraversal().Label(args);
+        }
+
+        public static GraphTraversal Limit(params object[] args)
+        {
+            return new GraphTraversal().Limit(args);
+        }
+
+        public static GraphTraversal Local(params object[] args)
+        {
+            return new GraphTraversal().Local(args);
+        }
+
+        public static GraphTraversal Loops(params object[] args)
+        {
+            return new GraphTraversal().Loops(args);
+        }
+
+        public static GraphTraversal Map(params object[] args)
+        {
+            return new GraphTraversal().Map(args);
+        }
+
+        public static GraphTraversal MapKeys(params object[] args)
+        {
+            return new GraphTraversal().MapKeys(args);
+        }
+
+        public static GraphTraversal MapValues(params object[] args)
+        {
+            return new GraphTraversal().MapValues(args);
+        }
+
+        public static GraphTraversal Match(params object[] args)
+        {
+            return new GraphTraversal().Match(args);
+        }
+
+        public static GraphTraversal Max(params object[] args)
+        {
+            return new GraphTraversal().Max(args);
+        }
+
+        public static GraphTraversal Mean(params object[] args)
+        {
+            return new GraphTraversal().Mean(args);
+        }
+
+        public static GraphTraversal Min(params object[] args)
+        {
+            return new GraphTraversal().Min(args);
+        }
+
+        public static GraphTraversal Not(params object[] args)
+        {
+            return new GraphTraversal().Not(args);
+        }
+
+        public static GraphTraversal Optional(params object[] args)
+        {
+            return new GraphTraversal().Optional(args);
+        }
+
+        public static GraphTraversal Or(params object[] args)
+        {
+            return new GraphTraversal().Or(args);
+        }
+
+        public static GraphTraversal Order(params object[] args)
+        {
+            return new GraphTraversal().Order(args);
+        }
+
+        public static GraphTraversal OtherV(params object[] args)
+        {
+            return new GraphTraversal().OtherV(args);
+        }
+
+        public static GraphTraversal Out(params object[] args)
+        {
+            return new GraphTraversal().Out(args);
+        }
+
+        public static GraphTraversal OutE(params object[] args)
+        {
+            return new GraphTraversal().OutE(args);
+        }
+
+        public static GraphTraversal OutV(params object[] args)
+        {
+            return new GraphTraversal().OutV(args);
+        }
+
+        public static GraphTraversal Path(params object[] args)
+        {
+            return new GraphTraversal().Path(args);
+        }
+
+        public static GraphTraversal Project(params object[] args)
+        {
+            return new GraphTraversal().Project(args);
+        }
+
+        public static GraphTraversal Properties(params object[] args)
+        {
+            return new GraphTraversal().Properties(args);
+        }
+
+        public static GraphTraversal Property(params object[] args)
+        {
+            return new GraphTraversal().Property(args);
+        }
+
+        public static GraphTraversal PropertyMap(params object[] args)
+        {
+            return new GraphTraversal().PropertyMap(args);
+        }
+
+        public static GraphTraversal Range(params object[] args)
+        {
+            return new GraphTraversal().Range(args);
+        }
+
+        public static GraphTraversal Repeat(params object[] args)
+        {
+            return new GraphTraversal().Repeat(args);
+        }
+
+        public static GraphTraversal Sack(params object[] args)
+        {
+            return new GraphTraversal().Sack(args);
+        }
+
+        public static GraphTraversal Sample(params object[] args)
+        {
+            return new GraphTraversal().Sample(args);
+        }
+
+        public static GraphTraversal Select(params object[] args)
+        {
+            return new GraphTraversal().Select(args);
+        }
+
+        public static GraphTraversal SideEffect(params object[] args)
+        {
+            return new GraphTraversal().SideEffect(args);
+        }
+
+        public static GraphTraversal SimplePath(params object[] args)
+        {
+            return new GraphTraversal().SimplePath(args);
+        }
+
+        public static GraphTraversal Store(params object[] args)
+        {
+            return new GraphTraversal().Store(args);
+        }
+
+        public static GraphTraversal Subgraph(params object[] args)
+        {
+            return new GraphTraversal().Subgraph(args);
+        }
+
+        public static GraphTraversal Sum(params object[] args)
+        {
+            return new GraphTraversal().Sum(args);
+        }
+
+        public static GraphTraversal Tail(params object[] args)
+        {
+            return new GraphTraversal().Tail(args);
+        }
+
+        public static GraphTraversal TimeLimit(params object[] args)
+        {
+            return new GraphTraversal().TimeLimit(args);
+        }
+
+        public static GraphTraversal Times(params object[] args)
+        {
+            return new GraphTraversal().Times(args);
+        }
+
+        public static GraphTraversal To(params object[] args)
+        {
+            return new GraphTraversal().To(args);
+        }
+
+        public static GraphTraversal ToE(params object[] args)
+        {
+            return new GraphTraversal().ToE(args);
+        }
+
+        public static GraphTraversal ToV(params object[] args)
+        {
+            return new GraphTraversal().ToV(args);
+        }
+
+        public static GraphTraversal Tree(params object[] args)
+        {
+            return new GraphTraversal().Tree(args);
+        }
+
+        public static GraphTraversal Unfold(params object[] args)
+        {
+            return new GraphTraversal().Unfold(args);
+        }
+
+        public static GraphTraversal Union(params object[] args)
+        {
+            return new GraphTraversal().Union(args);
+        }
+
+        public static GraphTraversal Until(params object[] args)
+        {
+            return new GraphTraversal().Until(args);
+        }
+
+        public static GraphTraversal Value(params object[] args)
+        {
+            return new GraphTraversal().Value(args);
+        }
+
+        public static GraphTraversal ValueMap(params object[] args)
+        {
+            return new GraphTraversal().ValueMap(args);
+        }
+
+        public static GraphTraversal Values(params object[] args)
+        {
+            return new GraphTraversal().Values(args);
+        }
+
+        public static GraphTraversal Where(params object[] args)
+        {
+            return new GraphTraversal().Where(args);
+        }
+	}
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Structure/Graph.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Structure/Graph.cs b/gremlin-dotnet/src/Gremlin.CSharp/Structure/Graph.cs
new file mode 100644
index 0000000..3ae5bef
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Structure/Graph.cs
@@ -0,0 +1,35 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+
+namespace Gremlin.CSharp.Structure
+{
+    public class Graph
+    {
+        public GraphTraversalSource Traversal()
+        {
+            return new GraphTraversalSource();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Gremlin.Net.Process.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Gremlin.Net.Process.csproj b/gremlin-dotnet/src/Gremlin.Net.Process/Gremlin.Net.Process.csproj
new file mode 100644
index 0000000..5e2d7fc
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Gremlin.Net.Process.csproj
@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <Version>3.2.5-SNAPSHOT</Version>
+    <TargetFramework>netstandard1.3</TargetFramework>
+    <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
+    <PackageProjectUrl>http://tinkerpop.apache.org</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/apache/tinkerpop/blob/master/LICENSE</PackageLicenseUrl>
+    <RepositoryUrl>https://github.com/apache/tinkerpop</RepositoryUrl>
+    <Authors>Apache TinkerPop</Authors>
+    <PackageTags>gremlin;tinkerpop;gremlin-dotnet</PackageTags>
+    <Description>This package provides implementations and interfaces for Gremlin language variants.</Description>
+  </PropertyGroup>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DocumentationFile></DocumentationFile>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
+    <PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
+  </ItemGroup>
+
+</Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Remote/IRemoteConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Remote/IRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Remote/IRemoteConnection.cs
new file mode 100644
index 0000000..8555cb3
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Remote/IRemoteConnection.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Threading.Tasks;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Process.Remote
+{
+    /// <summary>
+    ///     A simple abstraction of a "connection" to a "server".
+    /// </summary>
+    public interface IRemoteConnection
+    {
+        /// <summary>
+        ///     Submits <see cref="ITraversal" /> <see cref="Bytecode" /> to a server and returns a
+        ///     <see cref="ITraversal" />.
+        /// </summary>
+        /// <param name="bytecode">The <see cref="Bytecode" /> to send.</param>
+        /// <returns>The <see cref="ITraversal" /> with the results and optional side-effects.</returns>
+        Task<ITraversal> SubmitAsync(Bytecode bytecode);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Remote/RemoteStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Remote/RemoteStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Remote/RemoteStrategy.cs
new file mode 100644
index 0000000..4826113
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Remote/RemoteStrategy.cs
@@ -0,0 +1,61 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Threading.Tasks;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Process.Remote
+{
+    /// <summary>
+    ///     Reconstructs a <see cref="ITraversal" /> by submitting it to a remote server via an
+    ///     <see cref="IRemoteConnection" /> instance.
+    /// </summary>
+    public class RemoteStrategy : ITraversalStrategy
+    {
+        private readonly IRemoteConnection _remoteConnection;
+
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="RemoteStrategy" /> class.
+        /// </summary>
+        /// <param name="remoteConnection">The <see cref="IRemoteConnection" /> that should be used.</param>
+        public RemoteStrategy(IRemoteConnection remoteConnection)
+        {
+            _remoteConnection = remoteConnection;
+        }
+
+        /// <inheritdoc />
+        public void Apply(ITraversal traversal)
+        {
+            ApplyAsync(traversal).Wait();
+        }
+
+        /// <inheritdoc />
+        public async Task ApplyAsync(ITraversal traversal)
+        {
+            if (traversal.Traversers != null) return;
+            var remoteTraversal = await _remoteConnection.SubmitAsync(traversal.Bytecode).ConfigureAwait(false);
+            traversal.SideEffects = remoteTraversal.SideEffects;
+            traversal.Traversers = remoteTraversal.Traversers;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Binding.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Binding.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Binding.cs
new file mode 100644
index 0000000..80c8269
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Binding.cs
@@ -0,0 +1,80 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     Associates a variable with a value.
+    /// </summary>
+    public class Binding : IEquatable<Binding>
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Binding" /> class.
+        /// </summary>
+        /// <param name="key">The key that identifies the <see cref="Binding" />.</param>
+        /// <param name="value">The value of the <see cref="Binding" />.</param>
+        public Binding(string key, object value)
+        {
+            Key = key;
+            Value = value;
+        }
+
+        /// <summary>
+        ///     Gets the key that identifies the <see cref="Binding" />.
+        /// </summary>
+        public string Key { get; }
+
+        /// <summary>
+        ///     Gets the value of the <see cref="Binding" />.
+        /// </summary>
+        public object Value { get; }
+
+        /// <inheritdoc />
+        public bool Equals(Binding other)
+        {
+            if (other == null)
+                return false;
+            return Key == other.Key && Value.Equals(other.Value);
+        }
+
+        /// <inheritdoc />
+        public override bool Equals(object other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            if (other.GetType() != GetType()) return false;
+            return Equals(other as Binding);
+        }
+
+        /// <inheritdoc />
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                return ((Key?.GetHashCode() ?? 0) * 397) ^ (Value?.GetHashCode() ?? 0);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bindings.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bindings.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bindings.cs
new file mode 100644
index 0000000..985369e
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bindings.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     Bindings are used to associate a variable with a value.
+    /// </summary>
+    public class Bindings
+    {
+        /// <summary>
+        ///     Binds the variable to the specified value.
+        /// </summary>
+        /// <param name="variable">The variable to bind.</param>
+        /// <param name="value">The value to which the variable should be bound.</param>
+        /// <returns>The bound value.</returns>
+        public Binding Of(string variable, object value)
+        {
+            return new Binding(variable, value);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bytecode.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bytecode.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bytecode.cs
new file mode 100644
index 0000000..b35e8db
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Bytecode.cs
@@ -0,0 +1,85 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     A language agnostic representation of <see cref="ITraversal" /> mutations.
+    /// </summary>
+    /// <remarks>
+    ///     Bytecode is simply a list of ordered instructions.
+    ///     Bytecode can be serialized between environments and machines by way of a GraphSON representation.
+    ///     Thus, Gremlin-CSharp can create bytecode in C# and ship it to Gremlin-Java for evaluation in Java.
+    /// </remarks>
+    public class Bytecode
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Bytecode" /> class.
+        /// </summary>
+        public Bytecode()
+        {
+        }
+
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Bytecode" /> class.
+        /// </summary>
+        /// <param name="byteCode">Already existing <see cref="Bytecode" /> that should be cloned.</param>
+        public Bytecode(Bytecode byteCode)
+        {
+            SourceInstructions = new List<Instruction>(byteCode.SourceInstructions);
+            StepInstructions = new List<Instruction>(byteCode.StepInstructions);
+        }
+
+        /// <summary>
+        ///     Gets the traversal source instructions.
+        /// </summary>
+        public List<Instruction> SourceInstructions { get; } = new List<Instruction>();
+
+        /// <summary>
+        ///     Gets the <see cref="ITraversal" /> instructions.
+        /// </summary>
+        public List<Instruction> StepInstructions { get; } = new List<Instruction>();
+
+        /// <summary>
+        ///     Add a traversal source instruction to the bytecode.
+        /// </summary>
+        /// <param name="sourceName">The traversal source method name (e.g. withSack()).</param>
+        /// <param name="args">The traversal source method arguments.</param>
+        public void AddSource(string sourceName, params object[] args)
+        {
+            SourceInstructions.Add(new Instruction(sourceName, args));
+        }
+
+        /// <summary>
+        ///     Adds a <see cref="ITraversal" /> instruction to the bytecode.
+        /// </summary>
+        /// <param name="stepName">The traversal method name (e.g. out()).</param>
+        /// <param name="args">The traversal method arguments.</param>
+        public void AddStep(string stepName, params object[] args)
+        {
+            StepInstructions.Add(new Instruction(stepName, args));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/DefaultTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/DefaultTraversal.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/DefaultTraversal.cs
new file mode 100644
index 0000000..86c636c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/DefaultTraversal.cs
@@ -0,0 +1,195 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     A traversal represents a directed walk over a graph.
+    /// </summary>
+    public abstract class DefaultTraversal : ITraversal
+    {
+        private IEnumerator<Traverser> _traverserEnumerator;
+
+        /// <summary>
+        ///     Gets the <see cref="Bytecode" /> representation of this traversal.
+        /// </summary>
+        public Bytecode Bytecode { get; protected set; }
+
+        /// <summary>
+        ///     Gets or sets the <see cref="ITraversalSideEffects" /> of this traversal.
+        /// </summary>
+        public ITraversalSideEffects SideEffects { get; set; }
+
+        /// <summary>
+        ///     Gets or sets the <see cref="Traverser" />'s of this traversal that hold the results of the traversal.
+        /// </summary>
+        public IEnumerable<Traverser> Traversers { get; set; }
+
+        /// <summary>
+        ///     Gets or sets the <see cref="ITraversalStrategy" /> strategies of this traversal.
+        /// </summary>
+        protected ICollection<ITraversalStrategy> TraversalStrategies { get; set; } = new List<ITraversalStrategy>();
+
+        private IEnumerator<Traverser> TraverserEnumerator
+            => _traverserEnumerator ?? (_traverserEnumerator = GetTraverserEnumerator());
+
+        /// <inheritdoc />
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        /// <inheritdoc />
+        public bool MoveNext()
+        {
+            var currentTraverser = TraverserEnumerator.Current;
+            if (currentTraverser?.Bulk > 1)
+            {
+                currentTraverser.Bulk--;
+                return true;
+            }
+            return TraverserEnumerator.MoveNext();
+        }
+
+        /// <summary>
+        ///     Reset is not supported.
+        /// </summary>
+        /// <exception cref="NotSupportedException">Thrown always as this operation is not supported.</exception>
+        public void Reset()
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <inheritdoc />
+        public object Current => TraverserEnumerator.Current?.Object;
+
+        private IEnumerator<Traverser> GetTraverserEnumerator()
+        {
+            if (Traversers == null)
+                ApplyStrategies();
+            return Traversers.GetEnumerator();
+        }
+
+        private void ApplyStrategies()
+        {
+            foreach (var strategy in TraversalStrategies)
+                strategy.Apply(this);
+        }
+
+        private async Task ApplyStrategiesAsync()
+        {
+            foreach (var strategy in TraversalStrategies)
+                await strategy.ApplyAsync(this).ConfigureAwait(false);
+        }
+
+        /// <summary>
+        ///     Gets the next result from the traversal.
+        /// </summary>
+        /// <returns>The result.</returns>
+        public object Next()
+        {
+            MoveNext();
+            return Current;
+        }
+
+        /// <summary>
+        ///     Gets the next n-number of results from the traversal.
+        /// </summary>
+        /// <param name="amount">The number of results to get.</param>
+        /// <returns>The n-results.</returns>
+        public IEnumerable<object> Next(int amount)
+        {
+            for (var i = 0; i < amount; i++)
+                yield return Next();
+        }
+
+        /// <summary>
+        ///     Iterates all <see cref="Traverser" /> instances in the traversal.
+        /// </summary>
+        /// <returns>The fully drained traversal.</returns>
+        public ITraversal Iterate()
+        {
+            while (MoveNext())
+            {
+            }
+            return this;
+        }
+
+        /// <summary>
+        ///     Gets the next <see cref="Traverser" />.
+        /// </summary>
+        /// <returns>The next <see cref="Traverser" />.</returns>
+        public Traverser NextTraverser()
+        {
+            TraverserEnumerator.MoveNext();
+            return TraverserEnumerator.Current;
+        }
+
+        /// <summary>
+        ///     Puts all the results into a <see cref="List{T}" />.
+        /// </summary>
+        /// <returns>The results in a list.</returns>
+        public List<object> ToList()
+        {
+            var objs = new List<object>();
+            while (MoveNext())
+                objs.Add(Current);
+            return objs;
+        }
+
+        /// <summary>
+        ///     Puts all the results into a <see cref="HashSet{T}" />.
+        /// </summary>
+        /// <returns>The results in a set.</returns>
+        public HashSet<object> ToSet()
+        {
+            var objs = new HashSet<object>();
+            while (MoveNext())
+                objs.Add(Current);
+            return objs;
+        }
+
+        /// <inheritdoc />
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposing)
+                SideEffects?.Dispose();
+        }
+
+        /// <summary>
+        ///     Starts a promise to execute a function on the current traversal that will be completed in the future.
+        /// </summary>
+        /// <typeparam name="TReturn">The return type of the <paramref name="callback" />.</typeparam>
+        /// <param name="callback">The function to execute on the current traversal.</param>
+        /// <returns>The result of the executed <paramref name="callback" />.</returns>
+        public async Task<TReturn> Promise<TReturn>(Func<ITraversal, TReturn> callback)
+        {
+            await ApplyStrategiesAsync().ConfigureAwait(false);
+            return callback(this);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversal.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversal.cs
new file mode 100644
index 0000000..cb472b7
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversal.cs
@@ -0,0 +1,96 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     A traversal represents a directed walk over a graph.
+    /// </summary>
+    public interface ITraversal : IDisposable, IEnumerator
+    {
+        /// <summary>
+        ///     Gets the <see cref="Bytecode" /> representation of this traversal.
+        /// </summary>
+        Bytecode Bytecode { get; }
+
+        /// <summary>
+        ///     Gets or sets the <see cref="ITraversalSideEffects" /> of this traversal.
+        /// </summary>
+        ITraversalSideEffects SideEffects { get; set; }
+
+        /// <summary>
+        ///     Gets or sets the <see cref="Traverser" />'s of this traversal that hold the results of the traversal.
+        /// </summary>
+        IEnumerable<Traverser> Traversers { get; set; }
+
+        /// <summary>
+        ///     Gets the next result from the traversal.
+        /// </summary>
+        /// <returns>The result.</returns>
+        object Next();
+
+        /// <summary>
+        ///     Gets the next n-number of results from the traversal.
+        /// </summary>
+        /// <param name="amount">The number of results to get.</param>
+        /// <returns>The n-results.</returns>
+        IEnumerable<object> Next(int amount);
+
+        /// <summary>
+        ///     Iterates all <see cref="Traverser" /> instances in the traversal.
+        /// </summary>
+        /// <returns>The fully drained traversal.</returns>
+        ITraversal Iterate();
+
+        /// <summary>
+        ///     Gets the next <see cref="Traverser" />.
+        /// </summary>
+        /// <returns>The next <see cref="Traverser" />.</returns>
+        Traverser NextTraverser();
+
+        /// <summary>
+        ///     Puts all the results into a <see cref="List{T}" />.
+        /// </summary>
+        /// <returns>The results in a list.</returns>
+        List<object> ToList();
+
+        /// <summary>
+        ///     Puts all the results into a <see cref="HashSet{T}" />.
+        /// </summary>
+        /// <returns>The results in a set.</returns>
+        HashSet<object> ToSet();
+
+        /// <summary>
+        ///     Starts a promise to execute a function on the current traversal that will be completed in the future.
+        /// </summary>
+        /// <typeparam name="TReturn">The return type of the <paramref name="callback" />.</typeparam>
+        /// <param name="callback">The function to execute on the current traversal.</param>
+        /// <returns>The result of the executed <paramref name="callback" />.</returns>
+        Task<TReturn> Promise<TReturn>(Func<ITraversal, TReturn> callback);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalSideEffects.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalSideEffects.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalSideEffects.cs
new file mode 100644
index 0000000..0378fe6
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalSideEffects.cs
@@ -0,0 +1,52 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     A <see cref="ITraversal" /> can maintain global sideEffects.
+    /// </summary>
+    public interface ITraversalSideEffects : IDisposable
+    {
+        /// <summary>
+        ///     Retrieves the keys of the side-effect that can be supplied to <see cref="Get" />.
+        /// </summary>
+        /// <returns>The keys of the side-effect.</returns>
+        IReadOnlyCollection<string> Keys();
+
+        /// <summary>
+        ///     Gets the side-effect associated with the provided key.
+        /// </summary>
+        /// <param name="key">The key to get the value for.</param>
+        /// <returns>The value associated with key.</returns>
+        object Get(string key);
+
+        /// <summary>
+        ///     Invalidates the side effect cache for traversal.
+        /// </summary>
+        void Close();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalStrategy.cs
new file mode 100644
index 0000000..991a807
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/ITraversalStrategy.cs
@@ -0,0 +1,46 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     A <see cref="ITraversalStrategy" /> defines a particular atomic operation for mutating a
+    ///     <see cref="ITraversal" /> prior to its evaluation.
+    /// </summary>
+    public interface ITraversalStrategy
+    {
+        /// <summary>
+        ///     Applies the strategy to the given <see cref="ITraversal" />.
+        /// </summary>
+        /// <param name="traversal">The <see cref="ITraversal" /> the strategy should be applied to.</param>
+        void Apply(ITraversal traversal);
+
+        /// <summary>
+        ///     Applies the strategy to the given <see cref="ITraversal" /> asynchronously.
+        /// </summary>
+        /// <param name="traversal">The <see cref="ITraversal" /> the strategy should be applied to.</param>
+        Task ApplyAsync(ITraversal traversal);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Instruction.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Instruction.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Instruction.cs
new file mode 100644
index 0000000..195b7bf
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Instruction.cs
@@ -0,0 +1,52 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     Represents a <see cref="Bytecode" /> instruction by an operator name and its arguments.
+    /// </summary>
+    public class Instruction
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Instruction" /> class.
+        /// </summary>
+        /// <param name="operatorName">The name of the operator.</param>
+        /// <param name="arguments">The arguments.</param>
+        public Instruction(string operatorName, params dynamic[] arguments)
+        {
+            OperatorName = operatorName;
+            Arguments = arguments;
+        }
+
+        /// <summary>
+        ///     Gets the name of the operator.
+        /// </summary>
+        public string OperatorName { get; }
+
+        /// <summary>
+        ///     Gets the arguments.
+        /// </summary>
+        public dynamic[] Arguments { get; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/AbstractTraversalStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/AbstractTraversalStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/AbstractTraversalStrategy.cs
new file mode 100644
index 0000000..8c9666c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/AbstractTraversalStrategy.cs
@@ -0,0 +1,86 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Process.Traversal.Strategy
+{
+    /// <summary>
+    ///     Provides a common base class for strategies that are only included in <see cref="Bytecode" />
+    ///     to be applied remotely.
+    /// </summary>
+    public abstract class AbstractTraversalStrategy : ITraversalStrategy, IEquatable<AbstractTraversalStrategy>
+    {
+        /// <summary>
+        ///     Gets the name of the strategy.
+        /// </summary>
+        public string StrategyName => GetType().Name;
+
+        /// <summary>
+        ///     Gets the configuration of the strategy.
+        /// </summary>
+        public Dictionary<string, dynamic> Configuration { get; } = new Dictionary<string, dynamic>();
+
+        /// <inheritdoc />
+        public bool Equals(AbstractTraversalStrategy other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return StrategyName == other.StrategyName;
+        }
+
+        /// <inheritdoc />
+        public virtual void Apply(ITraversal traversal)
+        {
+        }
+
+        /// <inheritdoc />
+        public virtual Task ApplyAsync(ITraversal traversal)
+        {
+            return Task.CompletedTask;
+        }
+
+        /// <inheritdoc />
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != GetType()) return false;
+            return Equals((AbstractTraversalStrategy) obj);
+        }
+
+        /// <inheritdoc />
+        public override int GetHashCode()
+        {
+            return StrategyName.GetHashCode();
+        }
+
+        /// <inheritdoc />
+        public override string ToString()
+        {
+            return StrategyName;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ConnectiveStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ConnectiveStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ConnectiveStrategy.cs
new file mode 100644
index 0000000..2bca7c2
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ConnectiveStrategy.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+    /// <summary>
+    ///     ConnectiveStrategy rewrites the binary conjunction form of <c>a.and().b</c> into an AndStep of
+    ///     <c>and(a, b)</c> (likewise for OrStep).
+    /// </summary>
+    public class ConnectiveStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ElementIdStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ElementIdStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ElementIdStrategy.cs
new file mode 100644
index 0000000..6079f58
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/ElementIdStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+    /// <summary>
+    ///     Provides a degree of control over element identifier assignment as some graphs don't provide that feature.
+    /// </summary>
+    public class ElementIdStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/HaltedTraverserStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/HaltedTraverserStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/HaltedTraverserStrategy.cs
new file mode 100644
index 0000000..98f949c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/HaltedTraverserStrategy.cs
@@ -0,0 +1,34 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+    public class HaltedTraverserStrategy : AbstractTraversalStrategy
+    {
+        public HaltedTraverserStrategy(string haltedTraverserFactoryName = null)
+        {
+            if (haltedTraverserFactoryName != null)
+                Configuration["haltedTraverserFactory"] = haltedTraverserFactoryName;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/PartitionStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/PartitionStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/PartitionStrategy.cs
new file mode 100644
index 0000000..f89037b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/PartitionStrategy.cs
@@ -0,0 +1,56 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+    /// <summary>
+    ///     Partitions the vertices, edges and vertex properties of a graph into String named partitions.
+    /// </summary>
+    public class PartitionStrategy : AbstractTraversalStrategy
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="PartitionStrategy" /> class.
+        /// </summary>
+        /// <param name="partitionKey">Specifies the partition key name.</param>
+        /// <param name="writePartition">
+        ///     Specifies the name of the partition to write when adding vertices, edges and vertex
+        ///     properties.
+        /// </param>
+        /// <param name="readPartitions">Specifies the partition of the graph to read from.</param>
+        /// <param name="includeMetaProperties">Set to true if vertex properties should get assigned to partitions.</param>
+        public PartitionStrategy(string partitionKey = null, string writePartition = null,
+            IEnumerable<string> readPartitions = null, bool? includeMetaProperties = null)
+        {
+            if (partitionKey != null)
+                Configuration["partitionKey"] = partitionKey;
+            if (writePartition != null)
+                Configuration["writePartition"] = writePartition;
+            if (readPartitions != null)
+                Configuration["readPartitions"] = readPartitions;
+            if (includeMetaProperties != null)
+                Configuration["includeMetaProperties"] = includeMetaProperties.Value;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/SubgraphStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/SubgraphStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/SubgraphStrategy.cs
new file mode 100644
index 0000000..2f0d23e
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/SubgraphStrategy.cs
@@ -0,0 +1,48 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+    /// <summary>
+    ///     Provides a way to limit the view of a <see cref="ITraversal" />.
+    /// </summary>
+    public class SubgraphStrategy : AbstractTraversalStrategy
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="SubgraphStrategy" /> class.
+        /// </summary>
+        /// <param name="vertexCriterion">Constrains vertices for the <see cref="ITraversal" />.</param>
+        /// <param name="edgeCriterion">Constrains edges for the <see cref="ITraversal" />.</param>
+        /// <param name="vertexPropertyCriterion">Constrains vertex properties for the <see cref="ITraversal" />.</param>
+        public SubgraphStrategy(ITraversal vertexCriterion = null, ITraversal edgeCriterion = null,
+            ITraversal vertexPropertyCriterion = null)
+        {
+            if (vertexCriterion != null)
+                Configuration["vertices"] = vertexCriterion;
+            if (edgeCriterion != null)
+                Configuration["edges"] = edgeCriterion;
+            if (vertexPropertyCriterion != null)
+                Configuration["vertexProperties"] = vertexPropertyCriterion;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/VertexProgramStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/VertexProgramStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/VertexProgramStrategy.cs
new file mode 100644
index 0000000..1c5b5f2
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Decoration/VertexProgramStrategy.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Decoration
+{
+    public class VertexProgramStrategy : AbstractTraversalStrategy
+    {
+        public VertexProgramStrategy(string graphComputer = null, int? workers = null, string persist = null,
+            string result = null, ITraversal vertices = null, ITraversal edges = null,
+            Dictionary<string, dynamic> configuration = null)
+        {
+            if (graphComputer != null)
+                Configuration["graphComputer"] = graphComputer;
+            if (workers != null)
+                Configuration["workers"] = workers;
+            if (persist != null)
+                Configuration["persist"] = persist;
+            if (result != null)
+                Configuration["result"] = result;
+            if (vertices != null)
+                Configuration["vertices"] = vertices;
+            if (edges != null)
+                Configuration["edges"] = edges;
+            configuration?.ToList().ForEach(x => Configuration[x.Key] = x.Value);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Finalization/MatchAlgorithmStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Finalization/MatchAlgorithmStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Finalization/MatchAlgorithmStrategy.cs
new file mode 100644
index 0000000..11a9e2c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Finalization/MatchAlgorithmStrategy.cs
@@ -0,0 +1,34 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Finalization
+{
+    public class MatchAlgorithmStrategy : AbstractTraversalStrategy
+    {
+        public MatchAlgorithmStrategy(string matchAlgorithm = null)
+        {
+            if (matchAlgorithm != null)
+                Configuration["matchAlgorithm"] = matchAlgorithm;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/AdjacentToIncidentStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/AdjacentToIncidentStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/AdjacentToIncidentStrategy.cs
new file mode 100644
index 0000000..bae85d7
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/AdjacentToIncidentStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Optimizes vertex- and value-emitting steps.
+    /// </summary>
+    public class AdjacentToIncidentStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file


[2/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet

Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Properties/AssemblyInfo.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..579426b
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Gremlin.CSharp.IntegrationTest")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("232f0f2b-178e-4214-99c7-cc4dc6710f44")]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/appsettings.json
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/appsettings.json b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/appsettings.json
new file mode 100644
index 0000000..38007ec
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/appsettings.json
@@ -0,0 +1,4 @@
+{
+  "TestServerIpAddress": "localhost",
+  "TestServerPort": 45950
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/GraphTraversalSourceTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/GraphTraversalSourceTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/GraphTraversalSourceTests.cs
new file mode 100644
index 0000000..bac2d55
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/GraphTraversalSourceTests.cs
@@ -0,0 +1,68 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.UnitTest
+{
+    public class GraphTraversalSourceTests
+    {
+        [Fact]
+        public void ShouldBeIndependentFromReturnedGraphTraversalModififyingBytecode()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal();
+
+            g.V().Has("someKey", "someValue").Drop();
+
+            Assert.Equal(0, g.Bytecode.StepInstructions.Count);
+            Assert.Equal(0, g.Bytecode.SourceInstructions.Count);
+        }
+
+        [Fact]
+        public void ShouldBeIndependentFromReturnedGraphTraversalSourceModififyingBytecode()
+        {
+            var graph = new Graph();
+            var g1 = graph.Traversal();
+
+            var g2 = g1.WithSideEffect("someSideEffectKey", "someSideEffectValue");
+
+            Assert.Equal(0, g1.Bytecode.SourceInstructions.Count);
+            Assert.Equal(0, g1.Bytecode.StepInstructions.Count);
+            Assert.Equal(1, g2.Bytecode.SourceInstructions.Count);
+        }
+
+        [Fact]
+        public void ShouldBeIndependentFromReturnedGraphTraversalSourceModififyingTraversalStrategies()
+        {
+            var graph = new Graph();
+            var gLocal = graph.Traversal();
+
+            var gRemote = gLocal.WithRemote(null);
+
+            Assert.Equal(0, gLocal.TraversalStrategies.Count);
+            Assert.Equal(1, gRemote.TraversalStrategies.Count);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/Gremlin.CSharp.UnitTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/Gremlin.CSharp.UnitTest.csproj b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/Gremlin.CSharp.UnitTest.csproj
new file mode 100644
index 0000000..ea81928
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/Gremlin.CSharp.UnitTest.csproj
@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>    
+    <TargetFramework>netcoreapp1.1</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+    <PackageReference Include="xunit" Version="2.2.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\Gremlin.CSharp\Gremlin.CSharp.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+
+</Project>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/PredicateTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/PredicateTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/PredicateTests.cs
new file mode 100644
index 0000000..c06fb68
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.UnitTest/PredicateTests.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+using Xunit;
+
+namespace Gremlin.CSharp.UnitTest
+{
+    public class PredicateTests
+    {
+        [Fact]
+        public void ShouldKeepOrderForNestedPredicate()
+        {
+            Assert.Equal("and(eq(a),lt(b))", P.Eq("a").And(P.Lt("b")).ToString());
+        }
+
+        [Fact]
+        public void ShouldKeepOrderForDoubleNestedPredicate()
+        {
+            Assert.Equal("and(or(lt(b),gt(c)),neq(d))", P.Lt("b").Or(P.Gt("c")).And(P.Neq("d")).ToString());
+        }
+
+        [Fact]
+        public void ShouldKeepOrderForTripleNestedPredicate()
+        {
+            Assert.Equal("and(or(lt(b),gt(c)),or(neq(d),gte(e)))",
+                P.Lt("b").Or(P.Gt("c")).And(P.Neq("d").Or(P.Gte("e"))).ToString());
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/ConfigProvider.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/ConfigProvider.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/ConfigProvider.cs
new file mode 100644
index 0000000..b7afe74
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/ConfigProvider.cs
@@ -0,0 +1,47 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.IO;
+using Microsoft.Extensions.Configuration;
+
+namespace Gremlin.Net.IntegrationTest
+{
+    public static class ConfigProvider
+    {
+        static ConfigProvider()
+        {
+            Configuration = GetConfig();
+        }
+
+        public static IConfiguration Configuration { get; }
+
+        private static IConfiguration GetConfig()
+        {
+            var configFile = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
+            var builder = new ConfigurationBuilder()
+                .AddJsonFile(configFile, false, false);
+
+            return builder.Build();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
new file mode 100644
index 0000000..21a2627
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
@@ -0,0 +1,90 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver;
+using Gremlin.Net.IntegrationTest.Util;
+using Xunit;
+
+namespace Gremlin.Net.IntegrationTest.Driver
+{
+    public class ConnectionPoolTests
+    {
+        private readonly RequestMessageProvider _requestMessageProvider = new RequestMessageProvider();
+        private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+        private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+        private async Task ExecuteMultipleLongRunningRequestsInParallel(IGremlinClient gremlinClient, int nrRequests,
+            int requestRunningTimeInMs)
+        {
+            var longRunningRequestMsg = _requestMessageProvider.GetSleepMessage(requestRunningTimeInMs);
+            var tasks = new List<Task>(nrRequests);
+            for (var i = 0; i < nrRequests; i++)
+                tasks.Add(gremlinClient.SubmitAsync(longRunningRequestMsg));
+            await Task.WhenAll(tasks);
+        }
+
+        [Fact]
+        public async Task ShouldReuseConnectionForSequentialRequests()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                await gremlinClient.SubmitAsync("");
+                await gremlinClient.SubmitAsync("");
+
+                var nrConnections = gremlinClient.NrConnections;
+                Assert.Equal(1, nrConnections);
+            }
+        }
+
+        [Fact]
+        public void ShouldOnlyCreateConnectionWhenNecessary()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var nrConnections = gremlinClient.NrConnections;
+                Assert.Equal(0, nrConnections);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldExecuteParallelRequestsOnDifferentConnections()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var sleepTime = 50;
+                var nrParallelRequests = 5;
+
+                await ExecuteMultipleLongRunningRequestsInParallel(gremlinClient, nrParallelRequests, sleepTime);
+
+                var nrConnections = gremlinClient.NrConnections;
+                Assert.Equal(nrParallelRequests, nrConnections);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
new file mode 100644
index 0000000..351b83d
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
@@ -0,0 +1,212 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Exceptions;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.IntegrationTest.Util;
+using Xunit;
+
+namespace Gremlin.Net.IntegrationTest.Driver
+{
+    public class GremlinClientTests
+    {
+        private readonly RequestMessageProvider _requestMessageProvider = new RequestMessageProvider();
+        private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+        private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+        [Theory]
+        [InlineData("'justAString'", "justAString")]
+        [InlineData("'Hello' + 'World'", "HelloWorld")]
+        public async Task ShouldSendScriptForEvaluationAndReturnCorrectResult(string requestMsg, string expectedResponse)
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var response = await gremlinClient.SubmitWithSingleResultAsync<string>(requestMsg);
+
+                Assert.Equal(expectedResponse, response);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldHandleBigResponse()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var responseMsgSize = 5000;
+                var requestMsg = $"'1'*{responseMsgSize}";
+
+                var response = await gremlinClient.SubmitWithSingleResultAsync<string>(requestMsg);
+
+                Assert.Equal(responseMsgSize, response.Length);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldHandleResponseWithoutContent()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var gremlinScript = "g.V().has(propertyKey, propertyValue);";
+                var bindings = new Dictionary<string, object>
+                {
+                    {"propertyKey", "name"},
+                    {"propertyValue", "unknownTestName"}
+                };
+
+                var response =
+                    await gremlinClient.SubmitWithSingleResultAsync<object>(gremlinScript, bindings);
+
+                Assert.Null(response);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldThrowExceptionForInvalidScript()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var requestMsg = "invalid";
+
+                var exception =
+                    await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(requestMsg));
+
+                Assert.Equal(typeof(ResponseException), exception.GetType());
+                Assert.Contains($"ScriptEvaluationError: No such property: {requestMsg}",
+                    exception.Message);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldReassembleResponseBatches()
+        {
+            const int batchSize = 2;
+            var expectedResult = new List<int> {1, 2, 3, 4, 5};
+            var requestScript = $"{nameof(expectedResult)}";
+            var bindings = new Dictionary<string, object> {{nameof(expectedResult), expectedResult}};
+            var requestMessage =
+                RequestMessage.Build(Tokens.OpsEval)
+                    .AddArgument(Tokens.ArgsBatchSize, batchSize)
+                    .AddArgument(Tokens.ArgsGremlin, requestScript)
+                    .AddArgument(Tokens.ArgsBindings, bindings)
+                    .Create();
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var response = await gremlinClient.SubmitAsync<int>(requestMessage);
+
+                Assert.Equal(expectedResult, response);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldCorrectlyAssignResponsesToRequests()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var sleepTime = 100;
+                var expectedFirstResult = 1;
+                var gremlinScript = _requestMessageProvider.GetSleepGremlinScript(sleepTime);
+                gremlinScript += $"{expectedFirstResult}";
+                var firstRequestMsg = RequestMessage.Build(Tokens.OpsEval)
+                    .AddArgument(Tokens.ArgsGremlin, gremlinScript).Create();
+                var expectedSecondResponse = 2;
+                var secondScript = $"{expectedSecondResponse}";
+
+                var firstResponseTask = gremlinClient.SubmitWithSingleResultAsync<int>(firstRequestMsg);
+                var secondResponseTask = gremlinClient.SubmitWithSingleResultAsync<int>(secondScript);
+
+                var secondResponse = await secondResponseTask;
+                Assert.Equal(expectedSecondResponse, secondResponse);
+                var firstResponse = await firstResponseTask;
+                Assert.Equal(expectedFirstResult, firstResponse);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldReturnEnumerableResult()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var expectedResult = new List<int> {1, 2, 3, 4, 5};
+                var requestMsg = $"{nameof(expectedResult)}";
+                var bindings = new Dictionary<string, object> {{nameof(expectedResult), expectedResult}};
+
+                var response = await gremlinClient.SubmitAsync<int>(requestMsg, bindings);
+
+                Assert.Equal(expectedResult, response);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldThrowOnExecutionOfSimpleInvalidScript()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var invalidRequestScript = "invalid";
+
+                await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(invalidRequestScript));
+            }
+        }
+
+        [Fact]
+        public async Task ShouldHandleSimpleScriptWithoutErrors()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var requestMsg = _requestMessageProvider.GetDummyMessage();
+
+                await gremlinClient.SubmitAsync(requestMsg);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldUseBindingsForScript()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var requestMsg = "a + b";
+                var a = 1;
+                var b = 2;
+                var bindings = new Dictionary<string, object> {{"a", a}, {"b", b}};
+
+                var response =
+                    await gremlinClient.SubmitWithSingleResultAsync<int>(requestMsg, bindings);
+
+                Assert.Equal(a + b, response);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/MessagesTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/MessagesTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/MessagesTests.cs
new file mode 100644
index 0000000..6f6505f
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/MessagesTests.cs
@@ -0,0 +1,147 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Exceptions;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.IntegrationTest.Util;
+using Xunit;
+
+namespace Gremlin.Net.IntegrationTest.Driver
+{
+    public class MessagesTests
+    {
+        private readonly RequestMessageProvider _requestMessageProvider = new RequestMessageProvider();
+        private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+        private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+        [Fact]
+        public async Task ShouldUseAliasForTraversalSource()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var aliasTraversalSource = "g2";
+                var aliases = new Dictionary<string, string> {{aliasTraversalSource, "g"}};
+                var gremlinScript = $"{aliasTraversalSource}.V().count()";
+                var requestMsg =
+                    RequestMessage.Build(Tokens.OpsEval)
+                        .AddArgument(Tokens.ArgsAliases, aliases)
+                        .AddArgument(Tokens.ArgsGremlin, gremlinScript)
+                        .Create();
+
+                var result = await gremlinClient.SubmitWithSingleResultAsync<long>(requestMsg);
+
+                Assert.NotNull(result);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldThrowForInvalidOperation()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var ivalidOperationName = "invalid";
+                var requestMsg = RequestMessage.Build(ivalidOperationName).Create();
+
+                var thrownException =
+                    await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync<dynamic>(requestMsg));
+
+                Assert.Contains("MalformedRequest", thrownException.Message);
+                Assert.Contains(ivalidOperationName, thrownException.Message);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldThrowForInvalidProcessor()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var invalidProcessorName = "invalid";
+                var requestMsg = RequestMessage.Build("").Processor(invalidProcessorName).Create();
+
+                var thrownException =
+                    await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync<dynamic>(requestMsg));
+
+                Assert.Contains("InvalidRequestArguments", thrownException.Message);
+                Assert.Contains(invalidProcessorName, thrownException.Message);
+                Assert.Contains("OpProcessor", thrownException.Message);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldUseSpecifiedScriptEvaluationTimeout()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                const int timeOutInMs = 1;
+                const int scriptSleepTimeInMs = 5000;
+                var sleepScript = _requestMessageProvider.GetSleepGremlinScript(scriptSleepTimeInMs);
+
+                var requestMsg =
+                    RequestMessage.Build(Tokens.OpsEval)
+                        .AddArgument(Tokens.ArgsGremlin, sleepScript)
+                        .AddArgument(Tokens.ArgsEvalTimeout, timeOutInMs)
+                        .Create();
+                var evaluationStopWatch = new Stopwatch();
+                evaluationStopWatch.Start();
+
+                var thrownException =
+                    await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(requestMsg));
+
+                evaluationStopWatch.Stop();
+                Assert.Contains("ServerTimeout", thrownException.Message);
+                Assert.Contains(timeOutInMs.ToString(), thrownException.Message);
+                Assert.True(evaluationStopWatch.ElapsedMilliseconds < scriptSleepTimeInMs);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldThrowForUnsupportedLanguage()
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            using (var gremlinClient = new GremlinClient(gremlinServer))
+            {
+                var unknownLanguage = "unknown";
+                var requestMsg =
+                    RequestMessage.Build(Tokens.OpsEval)
+                        .AddArgument(Tokens.ArgsGremlin, "1")
+                        .AddArgument(Tokens.ArgsLanguage, unknownLanguage)
+                        .Create();
+
+                var thrownException =
+                    await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(requestMsg));
+
+                Assert.Contains("ScriptEvaluationError", thrownException.Message);
+                Assert.Contains(unknownLanguage, thrownException.Message);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
new file mode 100644
index 0000000..f8407a9
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
@@ -0,0 +1,41 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <DebugType>portable</DebugType>
+    <AssemblyName>Gremlin.Net.IntegrationTest</AssemblyName>
+    <PackageId>Gremlin.Net.IntegrationTest</PackageId>
+    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
+    <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
+    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <None Update="appsettings.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+    <ProjectReference Include="..\..\src\Gremlin.Net\Gremlin.Net.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+    <PackageReference Include="xunit" Version="2.2.0" />
+    <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.1" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
+    <PackageReference Include="xunit.runner.console" Version="2.2.0" />
+    <PackageReference Include="OpenCover" Version="4.6.519" />
+    <PackageReference Include="coveralls.io" Version="1.3.4" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+
+</Project>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Remote/RemoteStrategyTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Remote/RemoteStrategyTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Remote/RemoteStrategyTests.cs
new file mode 100644
index 0000000..de91152
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Remote/RemoteStrategyTests.cs
@@ -0,0 +1,85 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Remote;
+using Gremlin.Net.Process.Remote;
+using Gremlin.Net.Process.Traversal;
+using Xunit;
+
+namespace Gremlin.Net.IntegrationTest.Process.Remote
+{
+    public class RemoteStrategyTests
+    {
+        private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+        private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+        [Fact]
+        public void ShouldSendBytecodeToGremlinServer()
+        {
+            const string expectedResult = "gremlin";
+            var testBytecode = new Bytecode();
+            testBytecode.AddStep("V");
+            testBytecode.AddStep("has", "test");
+            testBytecode.AddStep("inject", expectedResult);
+            var testTraversal = CreateTraversalWithRemoteStrategy(testBytecode);
+
+            var actualResult = testTraversal.Next();
+
+            Assert.Equal(expectedResult, actualResult);
+        }
+
+        [Fact]
+        public async Task ShouldSendBytecodeToGremlinServerAsynchronouslyForTraversalPromise()
+        {
+            const string expectedResult = "gremlin";
+            var testBytecode = new Bytecode();
+            testBytecode.AddStep("V");
+            testBytecode.AddStep("has", "test");
+            testBytecode.AddStep("inject", expectedResult);
+            var testTraversal = CreateTraversalWithRemoteStrategy(testBytecode);
+
+            var actualResult = await testTraversal.Promise(t => t.Next());
+
+            Assert.Equal(expectedResult, actualResult);
+        }
+
+        private DefaultTraversal CreateTraversalWithRemoteStrategy(Bytecode bytecode)
+        {
+            var remoteStrategy =
+                new RemoteStrategy(new DriverRemoteConnection(new GremlinClient(new GremlinServer(TestHost, TestPort))));
+            return new TestTraversal(remoteStrategy, bytecode);
+        }
+    }
+
+    internal class TestTraversal : DefaultTraversal
+    {
+        public TestTraversal(ITraversalStrategy traversalStrategy, Bytecode bytecode)
+        {
+            TraversalStrategies.Add(traversalStrategy);
+            Bytecode = bytecode;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Properties/AssemblyInfo.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5dea6f0
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Gremlin.Net.IntegrationTest")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("cc54abe3-13d2-491c-81e2-4d0355abfa93")]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Util/RequestMessageProvider.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Util/RequestMessageProvider.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Util/RequestMessageProvider.cs
new file mode 100644
index 0000000..eb8735f
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Util/RequestMessageProvider.cs
@@ -0,0 +1,54 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.IntegrationTest.Util
+{
+    internal class RequestMessageProvider
+    {
+        public string GetSleepGremlinScript(int sleepTimeInMs)
+        {
+            return $"Thread.sleep({sleepTimeInMs});";
+        }
+
+        public RequestMessage GetSleepMessage(int sleepTimeInMs)
+        {
+            var gremlinScript = $"Thread.sleep({nameof(sleepTimeInMs)});";
+            var bindings = new Dictionary<string, object> {{nameof(sleepTimeInMs), sleepTimeInMs}};
+            return
+                RequestMessage.Build(Tokens.OpsEval)
+                    .AddArgument(Tokens.ArgsGremlin, gremlinScript)
+                    .AddArgument(Tokens.ArgsBindings, bindings)
+                    .Create();
+        }
+
+        public RequestMessage GetDummyMessage()
+        {
+            var gremlinScript = "1";
+            return RequestMessage.Build(Tokens.OpsEval).AddArgument(Tokens.ArgsGremlin, gremlinScript).Create();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json
new file mode 100644
index 0000000..38007ec
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/appsettings.json
@@ -0,0 +1,4 @@
+{
+  "TestServerIpAddress": "localhost",
+  "TestServerPort": 45950
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Gremlin.Net.Process.UnitTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Gremlin.Net.Process.UnitTest.csproj b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Gremlin.Net.Process.UnitTest.csproj
new file mode 100644
index 0000000..2345f31
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Gremlin.Net.Process.UnitTest.csproj
@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>    
+    <TargetFramework>netcoreapp1.1</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+    <PackageReference Include="Moq" Version="4.7.1" />
+    <PackageReference Include="xunit" Version="2.2.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+
+</Project>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/BytecodeTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/BytecodeTests.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/BytecodeTests.cs
new file mode 100644
index 0000000..de0a0b7
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/BytecodeTests.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+using Xunit;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+    public class BytecodeTests
+    {
+        [Fact]
+        public void ShouldUseBingings()
+        {
+            var bytecode = new Bytecode();
+            var bindings = new Bindings();
+
+            bytecode.AddStep("hasLabel", bindings.Of("label", "testLabel"));
+
+            var arg = bytecode.StepInstructions[0].Arguments[0];
+            var binding = arg as Binding;
+            Assert.Equal(new Binding("label", "testLabel"), binding);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/Strategy/StrategyTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/Strategy/StrategyTests.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/Strategy/StrategyTests.cs
new file mode 100644
index 0000000..2e7dc5e
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/Strategy/StrategyTests.cs
@@ -0,0 +1,109 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal.Strategy;
+using Gremlin.Net.Process.Traversal.Strategy.Optimization;
+using Gremlin.Net.Process.Traversal.Strategy.Verification;
+using Xunit;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal.Strategy
+{
+    public class StrategyTests
+    {
+        [Fact]
+        public void ShouldReturnFalseForEqualsOfStrategiesWithDifferentStrategyNames()
+        {
+            var firstStrategy = new TestStrategy("aConfigKey", "aConfigValue");
+            var secondStrategy = new IncidentToAdjacentStrategy();
+
+            var areEqual = firstStrategy.Equals(secondStrategy);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsOfStrategiesWithEqualNamesButDifferentConfigurations()
+        {
+            var firstStrategy = new TestStrategy("aConfigKey", "aConfigValue");
+            var secondStrategy = new TestStrategy("anotherKey", "anotherValue");
+
+            var areEqual = firstStrategy.Equals(secondStrategy);
+
+            Assert.True(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnDifferentHashcodesForStrategiesWithDifferentNames()
+        {
+            var firstStrategy = new TestStrategy();
+            var secondStrategy = new ReadOnlyStrategy();
+
+            var firstHashCode = firstStrategy.GetHashCode();
+            var secondHashCode = secondStrategy.GetHashCode();
+
+            Assert.NotEqual(firstHashCode, secondHashCode);
+        }
+
+        [Fact]
+        public void ShouldReturnEqualHashcodesForStrategiesWithEqualNamesButDifferentConfigurations()
+        {
+            var firstStrategy = new TestStrategy("aConfigKey", "aConfigValue");
+            var secondStrategy = new TestStrategy("anotherKey", "anotherValue");
+
+            var firstHashCode = firstStrategy.GetHashCode();
+            var secondHashCode = secondStrategy.GetHashCode();
+
+            Assert.Equal(firstHashCode, secondHashCode);
+        }
+
+        [Fact]
+        public void ShouldReturnClassNameForStrategyNameProperty()
+        {
+            var testStrategy = new TestStrategy();
+
+            Assert.Equal("TestStrategy", testStrategy.StrategyName);
+        }
+
+        [Fact]
+        public void ShouldReturnStrategyNameWhenForToString()
+        {
+            var testStrategy = new TestStrategy();
+
+            var strategyStr = testStrategy.ToString();
+
+            Assert.Equal("TestStrategy", strategyStr);
+        }
+    }
+
+    internal class TestStrategy : AbstractTraversalStrategy
+    {
+        public TestStrategy()
+        {
+        }
+
+        public TestStrategy(string configKey, dynamic configValue)
+        {
+            Configuration[configKey] = configValue;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversal.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversal.cs
new file mode 100644
index 0000000..34f88df
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversal.cs
@@ -0,0 +1,51 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+    public class TestTraversal : Process.Traversal.DefaultTraversal
+    {
+        public TestTraversal(List<object> traverserObjs)
+        {
+            var traversers = new List<Traverser>(traverserObjs.Count);
+            traverserObjs.ForEach(o => traversers.Add(new Traverser(o)));
+            Traversers = traversers;
+        }
+
+        public TestTraversal(IReadOnlyList<object> traverserObjs, IReadOnlyList<long> traverserBulks)
+        {
+            var traversers = new List<Traverser>(traverserObjs.Count);
+            traversers.AddRange(traverserObjs.Select((t, i) => new Traverser(t, traverserBulks[i])));
+            Traversers = traversers;
+        }
+
+        public TestTraversal(IList<ITraversalStrategy> traversalStrategies)
+        {
+            TraversalStrategies = traversalStrategies;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversalStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversalStrategy.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversalStrategy.cs
new file mode 100644
index 0000000..d643440
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TestTraversalStrategy.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+    public class TestTraversalStrategy : ITraversalStrategy
+    {
+        private readonly IEnumerable<Traverser> _traversers;
+
+        public TestTraversalStrategy(IEnumerable<Traverser> traversersToAddOnApplication)
+        {
+            _traversers = traversersToAddOnApplication;
+        }
+
+        public void Apply(ITraversal traversal)
+        {
+            traversal.Traversers = _traversers;
+        }
+
+        public Task ApplyAsync(ITraversal traversal)
+        {
+            traversal.Traversers = _traversers;
+            return Task.CompletedTask;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraversalTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraversalTests.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraversalTests.cs
new file mode 100644
index 0000000..a823a5d
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraversalTests.cs
@@ -0,0 +1,177 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Process.Traversal;
+using Moq;
+using Xunit;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+    public class TraversalTests
+    {
+        [Theory]
+        [InlineData(1)]
+        [InlineData("test")]
+        public void ShouldReturnAvailableTraverserObjWhenNextIsCalled(object traverserObj)
+        {
+            var traversal = new TestTraversal(new List<object> {traverserObj});
+
+            var actualObj = traversal.Next();
+
+            Assert.Equal(traverserObj, actualObj);
+        }
+
+        [Theory]
+        [InlineData(3)]
+        [InlineData(10)]
+        public void ShouldReturnCorrectNrOfResultObjsWhenNextIsCalledWithAmountArgument(int nrOfResults)
+        {
+            var objs = new List<object>(20);
+            for (var i = 0; i < 20; i++)
+                objs.Add(i);
+            var traversal = new TestTraversal(objs);
+
+            var traversedObjs = traversal.Next(nrOfResults);
+
+            var traversedObjsList = traversedObjs.ToList();
+            Assert.Equal(nrOfResults, traversedObjsList.Count);
+            for (var i = 0; i < nrOfResults; i++)
+                Assert.Equal(objs[i], traversedObjsList[i]);
+        }
+
+        private List<object> UnfoldBulks(IReadOnlyList<object> objs, IReadOnlyList<long> bulks)
+        {
+            var unfoldedObjs = new List<object>();
+            for (var traverserIdx = 0; traverserIdx < objs.Count; traverserIdx++)
+            for (var currentBulkObjIdx = 0; currentBulkObjIdx < bulks[traverserIdx]; currentBulkObjIdx++)
+                unfoldedObjs.Add(objs[traverserIdx]);
+            return unfoldedObjs;
+        }
+
+        [Fact]
+        public void ShouldDrainAllTraversersWhenIterateIsCalled()
+        {
+            var someObjs = new List<object> {1, 2, 3};
+            var traversal = new TestTraversal(someObjs);
+
+            var drainedTraversal = traversal.Iterate();
+
+            Assert.Null(drainedTraversal.Next());
+        }
+
+        [Fact]
+        public void ShouldReturnNullWhenNextIsCalledAndNoTraverserIsAvailable()
+        {
+            var expectedFirstObj = 1;
+            var traversal = new TestTraversal(new List<object> {expectedFirstObj});
+
+            var actualFirstObj = traversal.Next();
+            var actualSecondObj = traversal.Next();
+
+            Assert.Equal(expectedFirstObj, actualFirstObj);
+            Assert.Null(actualSecondObj);
+        }
+
+        [Fact]
+        public void ShouldReturnTraversalsTraverserWhenNextTraverserIsCalled()
+        {
+            var someObjs = new List<object> {1, 2, 3};
+            var traversal = new TestTraversal(someObjs);
+
+            var traverser = traversal.NextTraverser();
+
+            Assert.Equal(traversal.Traversers.First(), traverser);
+        }
+
+        [Fact]
+        public void ShouldThrowNotSupportedExceptionWhenResetIsCalled()
+        {
+            var someObjs = new List<object> {1, 2, 3};
+            var traversal = new TestTraversal(someObjs);
+
+            Assert.Throws<NotSupportedException>(() => traversal.Reset());
+        }
+
+        [Fact]
+        public void ShouldReturnAllTraverserObjsWhenToListIsCalled()
+        {
+            var expectedObjs = new List<object> {1, 2, 3};
+            var traversal = new TestTraversal(expectedObjs);
+
+            var traversedObjs = traversal.ToList();
+
+            Assert.Equal(expectedObjs, traversedObjs);
+        }
+
+        [Fact]
+        public void ShouldReturnAllTraverserObjWithoutDuplicatesWhenToSetIsCalled()
+        {
+            var traverserObjs = new List<object> {1, 1, 2, 3};
+            var traversal = new TestTraversal(traverserObjs);
+
+            var traversedObjSet = traversal.ToSet();
+
+            Assert.Equal(3, traversedObjSet.Count);
+            Assert.Equal(new HashSet<object>(traverserObjs), traversedObjSet);
+        }
+
+        [Fact]
+        public void ShouldApplyStrategiesWhenNextIsCalledAndNoTraversersPresent()
+        {
+            const int expectedObj = 531;
+            var testStrategy = new TestTraversalStrategy(new List<Traverser> {new Traverser(expectedObj)});
+            var testTraversal = new TestTraversal(new List<ITraversalStrategy> {testStrategy});
+
+            var actualObj = testTraversal.Next();
+
+            Assert.Equal(expectedObj, actualObj);
+        }
+
+        [Fact]
+        public void ShouldBeUnfoldTraverserBulksWhenToListIsCalled()
+        {
+            var objs = new List<object> {1, 2, 3};
+            var bulks = new List<long> {3, 2, 1};
+            var traversal = new TestTraversal(objs, bulks);
+
+            var traversedObjs = traversal.ToList();
+
+            var expectedObjs = UnfoldBulks(objs, bulks);
+            Assert.Equal(expectedObjs, traversedObjs);
+        }
+
+        [Fact]
+        public void ShouldDisposeSideEffectsWhenDisposeIsCalled()
+        {
+            var sideEffectsMock = new Mock<ITraversalSideEffects>();
+            var traversal = new TestTraversal(new List<object>()) {SideEffects = sideEffectsMock.Object};
+
+            traversal.Dispose();
+
+            sideEffectsMock.Verify(m => m.Dispose());
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraverserTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraverserTests.cs b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraverserTests.cs
new file mode 100644
index 0000000..4f6d2b5
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.Process.UnitTest/Traversal/TraverserTests.cs
@@ -0,0 +1,75 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+using Xunit;
+
+namespace Gremlin.Net.Process.UnitTest.Traversal
+{
+    public class TraverserTests
+    {
+        [Fact]
+        public void ShouldReturnFalseForEqualsWhereOtherIsNull()
+        {
+            var traverser = new Traverser("anObject");
+
+            var areEqual = traverser.Equals(null);
+
+            Assert.False(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsWithSameObjectAndDifferentBulk()
+        {
+            var firstTraverser = new Traverser("anObject", 1234);
+            var secondTraverser = new Traverser("anObject", 9876);
+
+            var areEqual = firstTraverser.Equals(secondTraverser);
+
+            Assert.True(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnTrueForEqualsObjectWithSameObjectAndDifferentBulk()
+        {
+            var firstTraverser = new Traverser("anObject", 1234);
+            object secondTraverser = new Traverser("anObject", 9876);
+
+            var areEqual = firstTraverser.Equals(secondTraverser);
+
+            Assert.True(areEqual);
+        }
+
+        [Fact]
+        public void ShouldReturnEqualHashcodesForTraversersWithSameObjectAndDifferentBulk()
+        {
+            var firstTraverser = new Traverser("anObject", 1234);
+            var secondTraverser = new Traverser("anObject", 9876);
+
+            var firstHashCode = firstTraverser.GetHashCode();
+            var secondHashCode = secondTraverser.GetHashCode();
+
+            Assert.Equal(firstHashCode, secondHashCode);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
new file mode 100644
index 0000000..7ed9c96
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
@@ -0,0 +1,51 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Remote;
+using Moq;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Driver
+{
+    public class DriverRemoteConnectionTests
+    {
+        [Fact]
+        public void ShouldDisposeProvidedGremlinClientOnDispose()
+        {
+            var gremlinClientMock = new Mock<IGremlinClient>();
+            var driverRemoteConnection = new DriverRemoteConnection(gremlinClientMock.Object);
+
+            driverRemoteConnection.Dispose();
+
+            gremlinClientMock.Verify(m => m.Dispose());
+        }
+
+        [Fact]
+        public void ShouldThrowWhenGivenNullAsGremlinClient()
+        {
+            Assert.Throws<ArgumentNullException>(() => new DriverRemoteConnection(null));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/GremlinServerTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/GremlinServerTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/GremlinServerTests.cs
new file mode 100644
index 0000000..54c5a06
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/GremlinServerTests.cs
@@ -0,0 +1,66 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Driver;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Driver
+{
+    public class GremlinServerTests
+    {
+        [Theory]
+        [InlineData("localhost", 8182)]
+        [InlineData("1.2.3.4", 5678)]
+        public void ShouldBuildCorrectUri(string host, int port)
+        {
+            var gremlinServer = new GremlinServer(host, port);
+
+            var uri = gremlinServer.Uri;
+
+            Assert.Equal($"ws://{host}:{port}/gremlin", uri.AbsoluteUri);
+        }
+
+        [Fact]
+        public void ShouldBuildCorrectUriForSsl()
+        {
+            var host = "localhost";
+            var port = 8181;
+            var gremlinServer = new GremlinServer(host, port, true);
+
+            var uri = gremlinServer.Uri;
+
+            Assert.Equal($"wss://{host}:{port}/gremlin", uri.AbsoluteUri);
+        }
+
+        [Fact]
+        public void ShouldUseCorrectDefaultPortWhenNoneProvided()
+        {
+            var host = "testHost";
+            var gremlinServer = new GremlinServer(host);
+
+            var uri = gremlinServer.Uri;
+
+            Assert.Equal(8182, uri.Port);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/RequestMessageBuilderTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/RequestMessageBuilderTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/RequestMessageBuilderTests.cs
new file mode 100644
index 0000000..cc5d2ee
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/RequestMessageBuilderTests.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Driver;
+using Gremlin.Net.Driver.Messages;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Driver
+{
+    public class RequestMessageBuilderTests
+    {
+        [Fact]
+        public void ShouldUseUniqueRequestIds()
+        {
+            var firstMsg = RequestMessage.Build(Tokens.OpsEval).Create();
+            var secondMsg = RequestMessage.Build(Tokens.OpsEval).Create();
+
+            Assert.NotEqual(firstMsg.RequestId, secondMsg.RequestId);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
new file mode 100644
index 0000000..3d2da0d
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
@@ -0,0 +1,35 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <DebugType>portable</DebugType>
+    <AssemblyName>Gremlin.Net.UnitTest</AssemblyName>
+    <PackageId>Gremlin.Net.UnitTest</PackageId>
+    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
+    <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
+    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+    <ProjectReference Include="..\..\src\Gremlin.Net\Gremlin.Net.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+    <PackageReference Include="Moq" Version="4.7.1" />
+    <PackageReference Include="System.Runtime" Version="4.3.0" />
+    <PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+    <PackageReference Include="xunit" Version="2.2.0" />
+    <PackageReference Include="OpenCover" Version="4.6.519" />
+    <PackageReference Include="coveralls.io" Version="1.3.4" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+
+</Project>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Properties/AssemblyInfo.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f339aa0
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Gremlin.Net.UnitTest")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("1fab781b-b857-4ad2-bec8-e20c214d9e21")]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/EdgeTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/EdgeTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/EdgeTests.cs
new file mode 100644
index 0000000..e636580
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/EdgeTests.cs
@@ -0,0 +1,57 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure
+{
+    public class EdgeTests
+    {
+        [Fact]
+        public void ShouldAssignPropertiesCorrectly()
+        {
+            const int id = 2;
+            var outV = new Vertex(1);
+            const string edgeLabel = "said";
+            var inV = new Vertex("hello", "phrase");
+
+            var edge = new Edge(id, outV, edgeLabel, inV);
+
+            Assert.Equal(outV, edge.OutV);
+            Assert.Equal(inV, edge.InV);
+            Assert.Equal(edgeLabel, edge.Label);
+            Assert.NotEqual(edge.InV, edge.OutV);
+        }
+
+        [Fact]
+        public void ShouldReturnCommonStringRepresentationForToString()
+        {
+            var edge = new Edge(2, new Vertex(1), "said", new Vertex("hello", "phrase"));
+
+            var edgeStr = edge.ToString();
+
+            Assert.Equal("e[2][1-said->hello]", edgeStr);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs
new file mode 100644
index 0000000..e367124
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs
@@ -0,0 +1,153 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Xunit;
+
+namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
+{
+    public class BytecodeGraphSONSerializerTests
+    {
+        private GraphSONWriter CreateGraphSONWriter()
+        {
+            return new GraphSONWriter();
+        }
+
+        [Fact]
+        public void ShouldSerializeByteCodeWithNestedTraversal()
+        {
+            var bytecode = new Bytecode();
+            bytecode.AddStep("V");
+            var nestedBytecode = new Bytecode();
+            var nestedTraversal = new TestTraversal(nestedBytecode);
+            nestedBytecode.AddStep("out");
+            bytecode.AddStep("repeat", nestedTraversal);
+            var graphsonWriter = CreateGraphSONWriter();
+
+            var graphSON = graphsonWriter.WriteObject(bytecode);
+
+            var expectedGraphSon =
+                "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\"],[\"repeat\",{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"out\"]]}}]]}}";
+            Assert.Equal(expectedGraphSon, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializeBytecodeWithNumbers()
+        {
+            var bytecode = new Bytecode();
+            bytecode.AddStep("V", (long) 1);
+            bytecode.AddStep("has", "age", 20);
+            bytecode.AddStep("has", "height", 6.5);
+            var graphsonWriter = CreateGraphSONWriter();
+
+            var graphSON = graphsonWriter.WriteObject(bytecode);
+
+            var expectedGraphSon =
+                "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\",{\"@type\":\"g:Int64\",\"@value\":1}],[\"has\",\"age\",{\"@type\":\"g:Int32\",\"@value\":20}],[\"has\",\"height\",{\"@type\":\"g:Double\",\"@value\":6.5}]]}}";
+            Assert.Equal(expectedGraphSon, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerialize_g_V()
+        {
+            var bytecode = new Bytecode();
+            bytecode.AddStep("V");
+            var graphsonWriter = CreateGraphSONWriter();
+
+            var graphSON = graphsonWriter.WriteObject(bytecode);
+
+            Assert.Equal("{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\"]]}}", graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerialize_g_V_Count()
+        {
+            var bytecode = new Bytecode();
+            bytecode.AddStep("V");
+            bytecode.AddStep("count");
+            var graphsonWriter = CreateGraphSONWriter();
+
+            var graphSON = graphsonWriter.WriteObject(bytecode);
+
+            var expectedGraphSon = "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\"],[\"count\"]]}}";
+            Assert.Equal(expectedGraphSon, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerialize_g_V_HasXPerson_Name_GremlinX_Count()
+        {
+            var bytecode = new Bytecode();
+            bytecode.AddStep("V");
+            bytecode.AddStep("has", "Person", "Name", "Gremlin");
+            bytecode.AddStep("count");
+            var graphsonWriter = CreateGraphSONWriter();
+
+            var graphSON = graphsonWriter.WriteObject(bytecode);
+
+            var expectedGraphSon =
+                "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\"],[\"has\",\"Person\",\"Name\",\"Gremlin\"],[\"count\"]]}}";
+            Assert.Equal(expectedGraphSon, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializeBytecodeWithSourcesStep()
+        {
+            var bytecode = new Bytecode();
+            bytecode.AddSource("withSideEffect", "a", new List<string> {"josh", "peter"});
+            bytecode.AddStep("V", 1);
+            bytecode.AddStep("values", "name");
+            bytecode.AddStep("where", new TraversalPredicate("within", "a"));
+            var graphsonWriter = CreateGraphSONWriter();
+
+            var graphSON = graphsonWriter.WriteObject(bytecode);
+
+            var expectedGraphSon =
+                "{\"@type\":\"g:Bytecode\",\"@value\":{\"source\":[[\"withSideEffect\",\"a\",[\"josh\",\"peter\"]]],\"step\":[[\"V\",{\"@type\":\"g:Int32\",\"@value\":1}],[\"values\",\"name\"],[\"where\",{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"within\",\"value\":\"a\"}}]]}}";
+            Assert.Equal(expectedGraphSon, graphSON);
+        }
+
+        [Fact]
+        public void ShouldSerializeBytecodeWithBindings()
+        {
+            var bytecode = new Bytecode();
+            bytecode.AddStep("V", new Binding("id", 123));
+            var graphsonWriter = CreateGraphSONWriter();
+
+            var graphSon = graphsonWriter.WriteObject(bytecode);
+
+            var expectedGraphSon =
+                "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"V\",{\"@type\":\"g:Binding\",\"@value\":{\"value\":{\"@type\":\"g:Int32\",\"@value\":123},\"key\":\"id\"}}]]}}";
+            Assert.Equal(expectedGraphSon, graphSon);
+        }
+    }
+
+    internal class TestTraversal : DefaultTraversal
+    {
+        public TestTraversal(Bytecode bytecode)
+        {
+            Bytecode = bytecode;
+        }
+    }
+}
\ No newline at end of file


[5/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet

Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs
new file mode 100644
index 0000000..3443e71
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/FilterRankingStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Reorders filter- and order-steps according to their rank.
+    /// </summary>
+    public class FilterRankingStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs
new file mode 100644
index 0000000..aaaee2c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/GraphFilterStrategy.cs
@@ -0,0 +1,29 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    public class GraphFilterStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs
new file mode 100644
index 0000000..08a4c46
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IdentityRemovalStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Looks for <c>Identity()</c>-steps and removes them.
+    /// </summary>
+    public class IdentityRemovalStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs
new file mode 100644
index 0000000..75b98c2
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/IncidentToAdjacentStrategy.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Replaces <c>.OutE().InV()</c> with <c>.Out()</c>, <c>.InE().OutV()</c> with <c>In()</c> and <c>.BothE().BothV()</c>
+    ///     with <c>Both()</c>.
+    /// </summary>
+    public class IncidentToAdjacentStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs
new file mode 100644
index 0000000..8eade84
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/InlineFilterStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Analyzes filter-steps with child traversals that themselves are pure filters.
+    /// </summary>
+    public class InlineFilterStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs
new file mode 100644
index 0000000..b5cac4a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/LazyBarrierStrategy.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Inserts <c>Barrier()</c>-steps into a <see cref="ITraversal" /> where appropriate in order to gain the "bulking
+    ///     optimization".
+    /// </summary>
+    public class LazyBarrierStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs
new file mode 100644
index 0000000..d535963
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/MatchPredicateStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Folds any post<c>Where()</c> step that maintains a traversal constraint into <c>Match()</c>.
+    /// </summary>
+    public class MatchPredicateStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs
new file mode 100644
index 0000000..82a8df9
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/OrderLimitStrategy.cs
@@ -0,0 +1,29 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    public class OrderLimitStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs
new file mode 100644
index 0000000..2c8e106
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathProcessorStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Helps to ensure that more traversals meet the local child constraint imposed on OLAP traversals.
+    /// </summary>
+    public class PathProcessorStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs
new file mode 100644
index 0000000..e54fbb5
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/PathRetractionStrategy.cs
@@ -0,0 +1,29 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    public class PathRetractionStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs
new file mode 100644
index 0000000..e3024bc
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RangeByIsCountStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    /// <summary>
+    ///     Optimizes any occurrence of <c>Count()</c>-step followed by an <c>Is()</c>-step.
+    /// </summary>
+    public class RangeByIsCountStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs
new file mode 100644
index 0000000..6cac454
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Optimization/RepeatUnrollStrategy.cs
@@ -0,0 +1,29 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
+{
+    public class RepeatUnrollStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs
new file mode 100644
index 0000000..0f488ab
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/LambdaRestrictionStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Verification
+{
+    /// <summary>
+    ///     Does not allow lambdas to be used in a <see cref="ITraversal" />.
+    /// </summary>
+    public class LambdaRestrictionStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs
new file mode 100644
index 0000000..a703e18
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Strategy/Verification/ReadOnlyStrategy.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal.Strategy.Verification
+{
+    /// <summary>
+    ///     Detects mutating steps and throws an exception if one is found.
+    /// </summary>
+    public class ReadOnlyStrategy : AbstractTraversalStrategy
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs
new file mode 100644
index 0000000..b854213
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/TraversalPredicate.cs
@@ -0,0 +1,85 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     Represents a predicate (boolean-valued function) used in a <see cref="ITraversal" />.
+    /// </summary>
+    public class TraversalPredicate
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="TraversalPredicate" /> class.
+        /// </summary>
+        /// <param name="operatorName">The name of the predicate.</param>
+        /// <param name="value">The value of the predicate.</param>
+        /// <param name="other">An optional other predicate that is used as an argument for this predicate.</param>
+        public TraversalPredicate(string operatorName, dynamic value, TraversalPredicate other = null)
+        {
+            OperatorName = operatorName;
+            Value = value;
+            Other = other;
+        }
+
+        /// <summary>
+        ///     Gets the name of the predicate.
+        /// </summary>
+        public string OperatorName { get; }
+
+        /// <summary>
+        ///     Gets the value of the predicate.
+        /// </summary>
+        public dynamic Value { get; }
+
+        /// <summary>
+        ///     Gets an optional other predicate that is used as an argument for this predicate.
+        /// </summary>
+        public TraversalPredicate Other { get; }
+
+        /// <summary>
+        ///     Returns a composed predicate that represents a logical AND of this predicate and another.
+        /// </summary>
+        /// <param name="otherPredicate">A predicate that will be logically-ANDed with this predicate.</param>
+        /// <returns>The composed predicate.</returns>
+        public TraversalPredicate And(TraversalPredicate otherPredicate)
+        {
+            return new TraversalPredicate("and", this, otherPredicate);
+        }
+
+        /// <summary>
+        ///     Returns a composed predicate that represents a logical OR of this predicate and another.
+        /// </summary>
+        /// <param name="otherPredicate">A predicate that will be logically-ORed with this predicate.</param>
+        /// <returns>The composed predicate.</returns>
+        public TraversalPredicate Or(TraversalPredicate otherPredicate)
+        {
+            return new TraversalPredicate("or", this, otherPredicate);
+        }
+
+        /// <inheritdoc />
+        public override string ToString()
+        {
+            return Other == null ? $"{OperatorName}({Value})" : $"{OperatorName}({Value},{Other})";
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs
new file mode 100644
index 0000000..573e57f
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net.Process/Traversal/Traverser.cs
@@ -0,0 +1,75 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     A traverser represents the current state of an object flowing through a <see cref="ITraversal" />.
+    /// </summary>
+    public class Traverser
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Traverser" /> class.
+        /// </summary>
+        /// <param name="obj">The object of the traverser.</param>
+        /// <param name="bulk">The number of traversers represented in this traverser.</param>
+        public Traverser(dynamic obj, long bulk = 1)
+        {
+            Object = obj;
+            Bulk = bulk;
+        }
+
+        /// <summary>
+        ///     Gets the object of this traverser.
+        /// </summary>
+        public dynamic Object { get; }
+
+        /// <summary>
+        ///     Gets the number of traversers represented in this traverser.
+        /// </summary>
+        public long Bulk { get; internal set; }
+
+        /// <inheritdoc />
+        public bool Equals(Traverser other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return Equals(Object, other.Object);
+        }
+
+        /// <inheritdoc />
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != GetType()) return false;
+            return Equals((Traverser) obj);
+        }
+
+        /// <inheritdoc />
+        public override int GetHashCode()
+        {
+            return Object != null ? Object.GetHashCode() : 0;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
new file mode 100644
index 0000000..2315ed4
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
@@ -0,0 +1,133 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Driver.ResultsAggregation;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Driver
+{
+    internal class Connection : IConnection
+    {
+        private readonly GraphSONReader _graphSONReader;
+        private readonly GraphSONWriter _graphSONWriter;
+        private readonly JsonMessageSerializer _messageSerializer = new JsonMessageSerializer();
+        private readonly Uri _uri;
+        private readonly WebSocketConnection _webSocketConnection = new WebSocketConnection();
+
+        public Connection(Uri uri, GraphSONReader graphSONReader, GraphSONWriter graphSONWriter)
+        {
+            _uri = uri;
+            _graphSONReader = graphSONReader;
+            _graphSONWriter = graphSONWriter;
+        }
+
+        public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage)
+        {
+            await SendAsync(requestMessage).ConfigureAwait(false);
+            return await ReceiveAsync<T>().ConfigureAwait(false);
+        }
+
+        public async Task ConnectAsync()
+        {
+            await _webSocketConnection.ConnectAsync(_uri).ConfigureAwait(false);
+        }
+
+        public async Task CloseAsync()
+        {
+            await _webSocketConnection.CloseAsync().ConfigureAwait(false);
+        }
+
+        private async Task SendAsync(RequestMessage message)
+        {
+            var graphsonMsg = _graphSONWriter.WriteObject(message);
+            var serializedMsg = _messageSerializer.SerializeMessage(graphsonMsg);
+            await _webSocketConnection.SendMessageAsync(serializedMsg).ConfigureAwait(false);
+        }
+
+        private async Task<IReadOnlyCollection<T>> ReceiveAsync<T>()
+        {
+            ResponseStatus status;
+            IAggregator aggregator = null;
+            var isAggregatingSideEffects = false;
+            var result = new List<T>();
+            do
+            {
+                var received = await _webSocketConnection.ReceiveMessageAsync().ConfigureAwait(false);
+                var receivedMsg = _messageSerializer.DeserializeMessage<ResponseMessage<JToken>>(received);
+
+                status = receivedMsg.Status;
+                status.ThrowIfStatusIndicatesError();
+
+                if (status.Code != ResponseStatusCode.NoContent)
+                {
+                    var receivedData = _graphSONReader.ToObject(receivedMsg.Result.Data);
+                    foreach (var d in receivedData)
+                        if (receivedMsg.Result.Meta.ContainsKey(Tokens.ArgsSideEffectKey))
+                        {
+                            if (aggregator == null)
+                                aggregator =
+                                    new AggregatorFactory().GetAggregatorFor(
+                                        (string) receivedMsg.Result.Meta[Tokens.ArgsAggregateTo]);
+                            aggregator.Add(d);
+                            isAggregatingSideEffects = true;
+                        }
+                        else
+                        {
+                            result.Add(d);
+                        }
+                }
+            } while (status.Code == ResponseStatusCode.PartialContent);
+
+            if (isAggregatingSideEffects)
+                return new List<T> {(T) aggregator.GetAggregatedResult()};
+            return result;
+        }
+
+        #region IDisposable Support
+
+        private bool _disposed;
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                    _webSocketConnection?.Dispose();
+                _disposed = true;
+            }
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs
new file mode 100644
index 0000000..d31817c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionFactory.cs
@@ -0,0 +1,47 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Gremlin.Net.Structure.IO.GraphSON;
+
+namespace Gremlin.Net.Driver
+{
+    internal class ConnectionFactory
+    {
+        private readonly GraphSONReader _graphSONReader;
+        private readonly GraphSONWriter _graphSONWriter;
+        private readonly Uri _uri;
+
+        public ConnectionFactory(Uri uri, GraphSONReader graphSONReader, GraphSONWriter graphSONWriter)
+        {
+            _uri = uri;
+            _graphSONReader = graphSONReader;
+            _graphSONWriter = graphSONWriter;
+        }
+
+        public Connection CreateConnection()
+        {
+            return new Connection(_uri, _graphSONReader, _graphSONWriter);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
new file mode 100644
index 0000000..e9ce9a8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
@@ -0,0 +1,114 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Gremlin.Net.Driver
+{
+    internal class ConnectionPool : IDisposable
+    {
+        private readonly ConnectionFactory _connectionFactory;
+        private readonly ConcurrentBag<Connection> _connections = new ConcurrentBag<Connection>();
+        private readonly object _connectionsLock = new object();
+
+        public ConnectionPool(ConnectionFactory connectionFactory)
+        {
+            _connectionFactory = connectionFactory;
+        }
+
+        public int NrConnections { get; private set; }
+
+        public async Task<IConnection> GetAvailableConnectionAsync()
+        {
+            Connection connection = null;
+            lock (_connectionsLock)
+            {
+                if (!_connections.IsEmpty)
+                    _connections.TryTake(out connection);
+            }
+
+            if (connection == null)
+                connection = await CreateNewConnectionAsync().ConfigureAwait(false);
+
+            return new ProxyConnection(connection, AddConnection);
+        }
+
+        private async Task<Connection> CreateNewConnectionAsync()
+        {
+            NrConnections++;
+            var newConnection = _connectionFactory.CreateConnection();
+            await newConnection.ConnectAsync().ConfigureAwait(false);
+            return newConnection;
+        }
+
+        private void AddConnection(Connection connection)
+        {
+            lock (_connectionsLock)
+            {
+                _connections.Add(connection);
+            }
+        }
+
+        #region IDisposable Support
+
+        private bool _disposed;
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                    lock (_connectionsLock)
+                    {
+                        if (_connections != null && !_connections.IsEmpty)
+                        {
+                            TeardownAsync().Wait();
+
+                            foreach (var conn in _connections)
+                                conn.Dispose();
+                        }
+                    }
+                _disposed = true;
+            }
+        }
+
+        private async Task TeardownAsync()
+        {
+            var closeTasks = new List<Task>(_connections.Count);
+            closeTasks.AddRange(_connections.Select(conn => conn.CloseAsync()));
+            await Task.WhenAll(closeTasks).ConfigureAwait(false);
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs
new file mode 100644
index 0000000..4706723
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Exceptions/ResponseException.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Driver.Exceptions
+{
+    /// <summary>
+    ///     The exception that is thrown when a response is received from Gremlin Server that indicates that an error occurred.
+    /// </summary>
+    public class ResponseException : Exception
+    {
+        internal ResponseException(string message) : base(message)
+        {
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
new file mode 100644
index 0000000..7833088
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
@@ -0,0 +1,95 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Structure.IO.GraphSON;
+
+namespace Gremlin.Net.Driver
+{
+    /// <summary>
+    ///     Provides a mechanism for submitting Gremlin requests to one Gremlin Server.
+    /// </summary>
+    public class GremlinClient : IGremlinClient
+    {
+        private readonly ConnectionPool _connectionPool;
+
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="GremlinClient" /> class for the specified Gremlin Server.
+        /// </summary>
+        /// <param name="gremlinServer">The <see cref="GremlinServer" /> the requests should be sent to.</param>
+        /// <param name="graphSONReader">A <see cref="GraphSONReader" /> instance to read received GraphSON data.</param>
+        /// <param name="graphSONWriter">a <see cref="GraphSONWriter" /> instance to write GraphSON data.</param>
+        public GremlinClient(GremlinServer gremlinServer, GraphSONReader graphSONReader = null,
+            GraphSONWriter graphSONWriter = null)
+        {
+            var reader = graphSONReader ?? new GraphSONReader();
+            var writer = graphSONWriter ?? new GraphSONWriter();
+            var connectionFactory = new ConnectionFactory(gremlinServer.Uri, reader, writer);
+            _connectionPool = new ConnectionPool(connectionFactory);
+        }
+
+        /// <summary>
+        ///     Gets the number of open connections.
+        /// </summary>
+        public int NrConnections => _connectionPool.NrConnections;
+
+        /// <inheritdoc />
+        public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage)
+        {
+            using (var connection = await _connectionPool.GetAvailableConnectionAsync().ConfigureAwait(false))
+            {
+                return await connection.SubmitAsync<T>(requestMessage).ConfigureAwait(false);
+            }
+        }
+
+        #region IDisposable Support
+
+        private bool _disposed;
+
+        /// <inheritdoc />
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        ///     Releases the resources used by the <see cref="GremlinClient" /> instance.
+        /// </summary>
+        /// <param name="disposing">Specifies whether managed resources should be released.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                    _connectionPool?.Dispose();
+                _disposed = true;
+            }
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
new file mode 100644
index 0000000..4aad73e
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
@@ -0,0 +1,140 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+    /// <summary>
+    ///     Provides extension methods for the <see cref="IGremlinClient" /> interface.
+    /// </summary>
+    public static class GremlinClientExtensions
+    {
+        /// <summary>
+        ///     Submits a request message that consists of a script with bindings as an asynchronous operation where only a single
+        ///     result gets returned.
+        /// </summary>
+        /// <remarks>
+        ///     If multiple results are received from Gremlin Server, then only the first gets returned. Use
+        ///     <see cref="SubmitAsync{T}" /> instead when you expect a collection of results.
+        /// </remarks>
+        /// <typeparam name="T">The type of the expected result.</typeparam>
+        /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+        /// <param name="requestScript">The Gremlin request script to send.</param>
+        /// <param name="bindings">Bindings for parameters used in the requestScript.</param>
+        /// <returns>A single result received from the Gremlin Server.</returns>
+        /// <exception cref="Exceptions.ResponseException">
+        ///     Thrown when a response is received from Gremlin Server that indicates
+        ///     that an error occurred.
+        /// </exception>
+        public static async Task<T> SubmitWithSingleResultAsync<T>(this IGremlinClient gremlinClient,
+            string requestScript,
+            Dictionary<string, object> bindings = null)
+        {
+            var resultCollection = await gremlinClient.SubmitAsync<T>(requestScript, bindings).ConfigureAwait(false);
+            return resultCollection.FirstOrDefault();
+        }
+
+        /// <summary>
+        ///     Submits a request message as an asynchronous operation where only a single result gets returned.
+        /// </summary>
+        /// <remarks>
+        ///     If multiple results are received from Gremlin Server, then only the first gets returned. Use
+        ///     <see cref="SubmitAsync{T}" /> instead when you expect a collection of results.
+        /// </remarks>
+        /// <typeparam name="T">The type of the expected result.</typeparam>
+        /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+        /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param>
+        /// <returns>A single result received from the Gremlin Server.</returns>
+        /// <exception cref="Exceptions.ResponseException">
+        ///     Thrown when a response is received from Gremlin Server that indicates
+        ///     that an error occurred.
+        /// </exception>
+        public static async Task<T> SubmitWithSingleResultAsync<T>(this IGremlinClient gremlinClient,
+            RequestMessage requestMessage)
+        {
+            var resultCollection = await gremlinClient.SubmitAsync<T>(requestMessage).ConfigureAwait(false);
+            return resultCollection.FirstOrDefault();
+        }
+
+        /// <summary>
+        ///     Submits a request message that consists of a script with bindings as an asynchronous operation without returning
+        ///     the result received from the Gremlin Server.
+        /// </summary>
+        /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+        /// <param name="requestScript">The Gremlin request script to send.</param>
+        /// <param name="bindings">Bindings for parameters used in the requestScript.</param>
+        /// <returns>The task object representing the asynchronous operation.</returns>
+        /// <exception cref="Exceptions.ResponseException">
+        ///     Thrown when a response is received from Gremlin Server that indicates
+        ///     that an error occurred.
+        /// </exception>
+        public static async Task SubmitAsync(this IGremlinClient gremlinClient, string requestScript,
+            Dictionary<string, object> bindings = null)
+        {
+            await gremlinClient.SubmitAsync<object>(requestScript, bindings).ConfigureAwait(false);
+        }
+
+        /// <summary>
+        ///     Submits a request message as an asynchronous operation without returning the result received from the Gremlin
+        ///     Server.
+        /// </summary>
+        /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+        /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param>
+        /// <returns>The task object representing the asynchronous operation.</returns>
+        /// <exception cref="Exceptions.ResponseException">
+        ///     Thrown when a response is received from Gremlin Server that indicates
+        ///     that an error occurred.
+        /// </exception>
+        public static async Task SubmitAsync(this IGremlinClient gremlinClient, RequestMessage requestMessage)
+        {
+            await gremlinClient.SubmitAsync<object>(requestMessage).ConfigureAwait(false);
+        }
+
+        /// <summary>
+        ///     Submits a request message that consists of a script with bindings as an asynchronous operation.
+        /// </summary>
+        /// <typeparam name="T">The type of the expected results.</typeparam>
+        /// <param name="gremlinClient">The <see cref="IGremlinClient" /> that submits the request.</param>
+        /// <param name="requestScript">The Gremlin request script to send.</param>
+        /// <param name="bindings">Bindings for parameters used in the requestScript.</param>
+        /// <returns>A collection of the data returned from the server.</returns>
+        /// <exception cref="Exceptions.ResponseException">
+        ///     Thrown when a response is received from Gremlin Server that indicates
+        ///     that an error occurred.
+        /// </exception>
+        public static async Task<IReadOnlyCollection<T>> SubmitAsync<T>(this IGremlinClient gremlinClient,
+            string requestScript,
+            Dictionary<string, object> bindings = null)
+        {
+            var msgBuilder = RequestMessage.Build(Tokens.OpsEval).AddArgument(Tokens.ArgsGremlin, requestScript);
+            if (bindings != null)
+                msgBuilder.AddArgument(Tokens.ArgsBindings, bindings);
+            var msg = msgBuilder.Create();
+            return await gremlinClient.SubmitAsync<T>(msg).ConfigureAwait(false);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
new file mode 100644
index 0000000..8da6d0b
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
@@ -0,0 +1,56 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Driver
+{
+    /// <summary>
+    ///     Represents a Gremlin Server.
+    /// </summary>
+    public class GremlinServer
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="GremlinServer" /> class with the specified connection parameters.
+        /// </summary>
+        /// <param name="hostname">The hostname of the server.</param>
+        /// <param name="port">The port on which Gremlin Server can be reached.</param>
+        /// <param name="enableSsl">Specifies whether SSL should be enabled.</param>
+        public GremlinServer(string hostname, int port = 8182, bool enableSsl = false)
+        {
+            Uri = CreateUri(hostname, port, enableSsl);
+        }
+
+        /// <summary>
+        ///     Gets the URI of the Gremlin Server.
+        /// </summary>
+        /// <value>The WebSocket <see cref="System.Uri" /> that the Gremlin Server responds to.</value>
+        public Uri Uri { get; }
+
+        private Uri CreateUri(string hostname, int port, bool enableSsl)
+        {
+            var scheme = enableSsl ? "wss" : "ws";
+            return new Uri($"{scheme}://{hostname}:{port}/gremlin");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs
new file mode 100644
index 0000000..e1651a6
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/IConnection.cs
@@ -0,0 +1,35 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+    internal interface IConnection : IDisposable
+    {
+        Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs
new file mode 100644
index 0000000..7a7048a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/IGremlinClient.cs
@@ -0,0 +1,48 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+    /// <summary>
+    ///     Provides a mechanism for submitting Gremlin requests.
+    /// </summary>
+    public interface IGremlinClient : IDisposable
+    {
+        /// <summary>
+        ///     Submits a request message as an asynchronous operation.
+        /// </summary>
+        /// <typeparam name="T">The type of the expected results.</typeparam>
+        /// <param name="requestMessage">The <see cref="RequestMessage" /> to send.</param>
+        /// <returns>A collection of the data returned from the server.</returns>
+        /// <exception cref="Exceptions.ResponseException">
+        ///     Thrown when a response is received from Gremlin Server that indicates
+        ///     that an error occurred.
+        /// </exception>
+        Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
new file mode 100644
index 0000000..c3270bf
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
@@ -0,0 +1,49 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Text;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Driver
+{
+    internal class JsonMessageSerializer
+    {
+        private const string MimeType = "application/vnd.gremlin-v2.0+json";
+
+        public byte[] SerializeMessage(string msg)
+        {
+            return Encoding.UTF8.GetBytes(MessageWithHeader(msg));
+        }
+
+        private string MessageWithHeader(string messageContent)
+        {
+            return $"{(char) MimeType.Length}{MimeType}{messageContent}";
+        }
+
+        public TMessage DeserializeMessage<TMessage>(byte[] message)
+        {
+            var responseStr = Encoding.UTF8.GetString(message);
+            return JsonConvert.DeserializeObject<TMessage>(responseStr);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs
new file mode 100644
index 0000000..550d9c0
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs
@@ -0,0 +1,143 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Driver.Messages
+{
+    /// <summary>
+    ///     The model for a request message sent to the server.
+    /// </summary>
+    public class RequestMessage
+    {
+        private RequestMessage(Guid requestId, string operation, string processor, Dictionary<string, object> arguments)
+        {
+            RequestId = requestId;
+            Operation = operation;
+            Processor = processor;
+            Arguments = arguments;
+        }
+
+        /// <summary>
+        ///     Gets the ID of this request message.
+        /// </summary>
+        /// <value>A UUID representing the unique identification for the request.</value>
+        public Guid RequestId { get; }
+
+        /// <summary>
+        ///     Gets the name of the operation that should be executed by the Gremlin Server.
+        /// </summary>
+        /// <value>
+        ///     The name of the "operation" to execute based on the available OpProcessor configured in the Gremlin Server. This
+        ///     defaults to "eval" which evaluates a request script.
+        /// </value>
+        public string Operation { get; }
+
+        /// <summary>
+        ///     Gets the name of the OpProcessor to utilize.
+        /// </summary>
+        /// <value>
+        ///     The name of the OpProcessor to utilize. This defaults to an empty string which represents the default
+        ///     OpProcessor for evaluating scripts.
+        /// </value>
+        public string Processor { get; }
+
+        /// <summary>
+        ///     Gets arguments of the <see cref="RequestMessage" />.
+        /// </summary>
+        public Dictionary<string, object> Arguments { get; }
+
+        /// <summary>
+        ///     Initializes a <see cref="Builder" /> to build a <see cref="RequestMessage" />.
+        /// </summary>
+        /// <param name="operation">The name of the OpProcessor to utilize.</param>
+        /// <returns>A <see cref="Builder" /> to build a <see cref="RequestMessage" />.</returns>
+        public static Builder Build(string operation)
+        {
+            return new Builder(operation);
+        }
+
+        /// <summary>
+        ///     Allows to build <see cref="RequestMessage" /> objects.
+        /// </summary>
+        public class Builder
+        {
+            private const string DefaultProcessor = "";
+            private readonly Dictionary<string, object> _arguments = new Dictionary<string, object>();
+            private readonly string _operation;
+            private string _processor = DefaultProcessor;
+            private Guid _requestId = Guid.NewGuid();
+
+            internal Builder(string operation)
+            {
+                _operation = operation;
+            }
+
+            /// <summary>
+            ///     If this value is not set in the builder then the <see cref="RequestMessage.Processor" /> defaults to
+            ///     the standard op processor (empty string).
+            /// </summary>
+            /// <param name="processor">The name of the processor.</param>
+            /// <returns>The <see cref="Builder" />.</returns>
+            public Builder Processor(string processor)
+            {
+                _processor = processor;
+                return this;
+            }
+
+            /// <summary>
+            ///     Overrides the request identifier with a specified one, otherwise the
+            ///     <see cref="Builder" /> will randomly generate a <see cref="Guid" />.
+            /// </summary>
+            /// <param name="requestId">The request identifier to use.</param>
+            /// <returns>The <see cref="Builder" />.</returns>
+            public Builder OverrideRequestId(Guid requestId)
+            {
+                _requestId = requestId;
+                return this;
+            }
+
+            /// <summary>
+            ///     Adds and argument to the <see cref="RequestMessage" />.
+            /// </summary>
+            /// <param name="key">The key of the argument.</param>
+            /// <param name="value">The value of the argument.</param>
+            /// <returns>The <see cref="Builder" />.</returns>
+            public Builder AddArgument(string key, object value)
+            {
+                _arguments.Add(key, value);
+                return this;
+            }
+
+            /// <summary>
+            ///     Creates the <see cref="RequestMessage" /> given the settings provided to the <see cref="Builder" />.
+            /// </summary>
+            /// <returns>The built <see cref="RequestMessage" />.</returns>
+            public RequestMessage Create()
+            {
+                return new RequestMessage(_requestId, _operation, _processor, _arguments);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
new file mode 100644
index 0000000..602b013
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
@@ -0,0 +1,40 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Driver.Messages
+{
+    internal class ResponseMessage<T>
+    {
+        [JsonProperty(PropertyName = "requestId")]
+        public Guid RequestId { get; set; }
+
+        [JsonProperty(PropertyName = "status")]
+        public ResponseStatus Status { get; set; }
+
+        [JsonProperty(PropertyName = "result")]
+        public ResponseResult<T> Result { get; set; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
new file mode 100644
index 0000000..643fbe8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Driver.Messages
+{
+    internal class ResponseResult<T>
+    {
+        [JsonProperty(PropertyName = "data")]
+        public List<T> Data { get; set; }
+
+        [JsonProperty(PropertyName = "meta")]
+        public Dictionary<string, object> Meta { get; set; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
new file mode 100644
index 0000000..e3c1797
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Driver.Exceptions;
+using Newtonsoft.Json;
+
+namespace Gremlin.Net.Driver.Messages
+{
+    internal class ResponseStatus
+    {
+        [JsonProperty(PropertyName = "code")]
+        public ResponseStatusCode Code { get; set; }
+
+        [JsonProperty(PropertyName = "attributes")]
+        public Dictionary<string, object> Attributes { get; set; }
+
+        [JsonProperty(PropertyName = "message")]
+        public string Message { get; set; }
+    }
+
+    internal static class ResponseStatusExtensions
+    {
+        public static void ThrowIfStatusIndicatesError(this ResponseStatus status)
+        {
+            if (status.Code.IndicatesError())
+                throw new ResponseException($"{status.Code}: {status.Message}");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs
new file mode 100644
index 0000000..7b0bc94
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatusCode.cs
@@ -0,0 +1,67 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Driver.Messages
+{
+    internal enum ResponseStatusCode
+    {
+        Success = 200,
+        NoContent = 204,
+        PartialContent = 206,
+        Unauthorized = 401,
+        Authenticate = 407,
+        MalformedRequest = 498,
+        InvalidRequestArguments = 499,
+        ServerError = 500,
+        ScriptEvaluationError = 597,
+        ServerTimeout = 598,
+        ServerSerializationError = 599
+    }
+
+    internal static class ResponseStatusCodeExtensions
+    {
+        public static bool IndicatesError(this ResponseStatusCode statusCode)
+        {
+            switch (statusCode)
+            {
+                case ResponseStatusCode.Success:
+                case ResponseStatusCode.NoContent:
+                case ResponseStatusCode.PartialContent:
+                    return false;
+                case ResponseStatusCode.Unauthorized:
+                case ResponseStatusCode.Authenticate:
+                case ResponseStatusCode.MalformedRequest:
+                case ResponseStatusCode.InvalidRequestArguments:
+                case ResponseStatusCode.ServerError:
+                case ResponseStatusCode.ScriptEvaluationError:
+                case ResponseStatusCode.ServerTimeout:
+                case ResponseStatusCode.ServerSerializationError:
+                    return true;
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(statusCode), statusCode, null);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs
new file mode 100644
index 0000000..cbe15ec
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ProxyConnection.cs
@@ -0,0 +1,52 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+
+namespace Gremlin.Net.Driver
+{
+    internal sealed class ProxyConnection : IConnection
+    {
+        private readonly Connection _realConnection;
+        private readonly Action<Connection> _releaseAction;
+
+        public ProxyConnection(Connection realConnection, Action<Connection> releaseAction)
+        {
+            _realConnection = realConnection;
+            _releaseAction = releaseAction;
+        }
+
+        public async Task<IReadOnlyCollection<T>> SubmitAsync<T>(RequestMessage requestMessage)
+        {
+            return await _realConnection.SubmitAsync<T>(requestMessage).ConfigureAwait(false);
+        }
+
+        public void Dispose()
+        {
+            _releaseAction(_realConnection);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
new file mode 100644
index 0000000..2ba5d6c
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
@@ -0,0 +1,80 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Gremlin.Net.Driver.Messages;
+using Gremlin.Net.Process.Remote;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Driver.Remote
+{
+    /// <summary>
+    ///     A <see cref="IRemoteConnection" /> implementation for Gremlin Server.
+    /// </summary>
+    public class DriverRemoteConnection : IRemoteConnection, IDisposable
+    {
+        private readonly IGremlinClient _client;
+
+        /// <summary>
+        ///     Initializes a new <see cref="IRemoteConnection" />.
+        /// </summary>
+        /// <param name="client">The <see cref="IGremlinClient" /> that will be used for the connection.</param>
+        /// <exception cref="ArgumentNullException">Thrown when client is null.</exception>
+        public DriverRemoteConnection(IGremlinClient client)
+        {
+            _client = client ?? throw new ArgumentNullException(nameof(client));
+        }
+
+        /// <summary>
+        ///     Submits <see cref="Bytecode" /> for evaluation to a remote Gremlin Server.
+        /// </summary>
+        /// <param name="bytecode">The <see cref="Bytecode" /> to submit.</param>
+        /// <returns>A <see cref="ITraversal" /> allowing to access the results and side-effects.</returns>
+        public async Task<ITraversal> SubmitAsync(Bytecode bytecode)
+        {
+            var requestId = Guid.NewGuid();
+            var resultSet = await SubmitBytecodeAsync(requestId, bytecode).ConfigureAwait(false);
+            return new DriverRemoteTraversal(_client, requestId, resultSet);
+        }
+
+        private async Task<IEnumerable<Traverser>> SubmitBytecodeAsync(Guid requestid, Bytecode bytecode)
+        {
+            var requestMsg =
+                RequestMessage.Build(Tokens.OpsBytecode)
+                    .Processor(Tokens.ProcessorTraversal)
+                    .OverrideRequestId(requestid)
+                    .AddArgument(Tokens.ArgsGremlin, bytecode)
+                    .AddArgument(Tokens.ArgsAliases, new Dictionary<string, string> {{"g", "g"}})
+                    .Create();
+            return await _client.SubmitAsync<Traverser>(requestMsg).ConfigureAwait(false);
+        }
+
+        /// <inheritdoc />
+        public void Dispose()
+        {
+            _client?.Dispose();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs
new file mode 100644
index 0000000..f3f26d1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversal.cs
@@ -0,0 +1,39 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Driver.Remote
+{
+    internal class DriverRemoteTraversal : DefaultTraversal
+    {
+        public DriverRemoteTraversal(IGremlinClient gremlinClient, Guid requestId,
+            IEnumerable<Traverser> traversers)
+        {
+            Traversers = traversers;
+            SideEffects = new DriverRemoteTraversalSideEffects(gremlinClient, requestId);
+        }
+    }
+}
\ No newline at end of file


[3/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet

Posted by sp...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalSerializer.cs
new file mode 100644
index 0000000..cc809aa
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalSerializer.cs
@@ -0,0 +1,38 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class TraversalSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            ITraversal traversal = objectData;
+            var bytecode = traversal.Bytecode;
+            return writer.ToDict(bytecode);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalStrategySerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalStrategySerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalStrategySerializer.cs
new file mode 100644
index 0000000..9b70978
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalStrategySerializer.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal.Strategy;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class TraversalStrategySerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            AbstractTraversalStrategy strategy = objectData;
+            return GraphSONUtil.ToTypedValue(strategy.StrategyName, writer.ToDict(strategy.Configuration));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
new file mode 100644
index 0000000..abbb45f
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
@@ -0,0 +1,38 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.Net.Process.Traversal;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class TraverserReader : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            var bulkObj = reader.ToObject(graphsonObject["bulk"]);
+            var valueObj = reader.ToObject(graphsonObject["value"]);
+            return new Traverser(valueObj, bulkObj);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
new file mode 100644
index 0000000..82ca43d
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
@@ -0,0 +1,36 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class UuidDeserializer : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            return graphsonObject.ToObject<Guid>();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidSerializer.cs
new file mode 100644
index 0000000..5f31bfc
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidSerializer.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class UuidSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            Guid guid = objectData;
+            return GraphSONUtil.ToTypedValue("UUID", guid);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
new file mode 100644
index 0000000..f1d64ed
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
@@ -0,0 +1,37 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class VertexDeserializer : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            var id = reader.ToObject(graphsonObject["id"]);
+            var label = (string) graphsonObject["label"] ?? Vertex.DefaultLabel;
+            return new Vertex(id, label);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
new file mode 100644
index 0000000..7c2505f
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Newtonsoft.Json.Linq;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class VertexPropertyDeserializer : IGraphSONDeserializer
+    {
+        public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+        {
+            var id = reader.ToObject(graphsonObject["id"]);
+            var label = (string) graphsonObject["label"];
+            var value = reader.ToObject(graphsonObject["value"]);
+            var vertex = graphsonObject["vertex"] != null
+                ? new Vertex(reader.ToObject(graphsonObject["vertex"]))
+                : null;
+            return new VertexProperty(id, label, value, vertex);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertySerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertySerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertySerializer.cs
new file mode 100644
index 0000000..12cc7ac
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertySerializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class VertexPropertySerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            VertexProperty vertexProperty = objectData;
+            var valueDict = new Dictionary<string, dynamic>
+            {
+                {"id", writer.ToDict(vertexProperty.Id)},
+                {"label", vertexProperty.Label},
+                {"value", writer.ToDict(vertexProperty.Value)},
+                {"vertex", writer.ToDict(vertexProperty.Vertex.Id)}
+            };
+            return GraphSONUtil.ToTypedValue(nameof(VertexProperty), valueDict);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexSerializer.cs
new file mode 100644
index 0000000..d3ad9f1
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexSerializer.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class VertexSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            Vertex vertex = objectData;
+            var vertexDict = new Dictionary<string, dynamic>
+            {
+                {"id", writer.ToDict(vertex.Id)},
+                {"label", writer.ToDict(vertex.Label)}
+            };
+            return GraphSONUtil.ToTypedValue(nameof(Vertex), vertexDict);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Path.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Path.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Path.cs
new file mode 100644
index 0000000..01a436a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Path.cs
@@ -0,0 +1,193 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure
+{
+    /// <summary>
+    ///     A Path denotes a particular walk through a graph as defined by a <see cref="ITraversal" />.
+    /// </summary>
+    /// <remarks>
+    ///     In abstraction, any Path implementation maintains two lists: a list of sets of labels and a list of objects.
+    ///     The list of labels are the labels of the steps traversed. The list of objects are the objects traversed.
+    /// </remarks>
+    public class Path : IReadOnlyList<object>, IEquatable<Path>
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Path" /> class.
+        /// </summary>
+        /// <param name="labels">The labels associated with the path</param>
+        /// <param name="objects">The objects in the <see cref="Path" />.</param>
+        public Path(List<List<string>> labels, List<object> objects)
+        {
+            Labels = labels;
+            Objects = objects;
+        }
+
+        /// <summary>
+        ///     Gets an ordered list of the labels associated with the <see cref="Path" />.
+        /// </summary>
+        public List<List<string>> Labels { get; }
+
+        /// <summary>
+        ///     Gets an ordered list of the objects in the <see cref="Path" />.
+        /// </summary>
+        public List<object> Objects { get; }
+
+        /// <summary>
+        ///     Gets the object associated with the particular label of the path.
+        /// </summary>
+        /// <remarks>If the path has multiple labels of the type, then get a collection of those objects.</remarks>
+        /// <param name="label">The label of the path</param>
+        /// <returns>The object associated with the label of the path</returns>
+        /// <exception cref="KeyNotFoundException">Thrown if the path does not contain the label.</exception>
+        public object this[string label]
+        {
+            get
+            {
+                var objFound = TryGetValue(label, out object obj);
+                if (!objFound)
+                    throw new KeyNotFoundException($"The step with label {label} does not exist");
+                return obj;
+            }
+        }
+
+        /// <inheritdoc />
+        public bool Equals(Path other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return ObjectsEqual(other.Objects) && LabelsEqual(other.Labels);
+        }
+
+        /// <summary>
+        ///     Get the object associated with the specified index into the path.
+        /// </summary>
+        /// <param name="index">The index of the path</param>
+        /// <returns>The object associated with the index of the path</returns>
+        public dynamic this[int index] => Objects[index];
+
+        /// <summary>
+        ///     Gets the number of steps in the path.
+        /// </summary>
+        public int Count => Objects.Count;
+
+        /// <inheritdoc />
+        public IEnumerator<object> GetEnumerator()
+        {
+            return ((IReadOnlyList<object>) Objects).GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return ((IReadOnlyList<object>) Objects).GetEnumerator();
+        }
+
+        /// <inheritdoc />
+        public override string ToString()
+        {
+            return $"[{string.Join(", ", Objects)}]";
+        }
+
+        /// <summary>
+        ///     Returns true if the path has the specified label, else return false.
+        /// </summary>
+        /// <param name="key">The label to search for.</param>
+        /// <returns>True if the label exists in the path.</returns>
+        public bool ContainsKey(string key)
+        {
+            return Labels.Any(objLabels => objLabels.Contains(key));
+        }
+
+        /// <summary>
+        ///     Tries to get the object associated with the particular label of the path.
+        /// </summary>
+        /// <remarks>If the path has multiple labels of the type, then get a collection of those objects.</remarks>
+        /// <param name="label">The label of the path.</param>
+        /// <param name="value">The object associated with the label of the path.</param>
+        /// <returns>True, if an object was found for the label.</returns>
+        public bool TryGetValue(string label, out object value)
+        {
+            value = null;
+            for (var i = 0; i < Labels.Count; i++)
+            {
+                if (!Labels[i].Contains(label)) continue;
+                if (value == null)
+                    value = Objects[i];
+                else if (value.GetType() == typeof(List<object>))
+                    ((List<object>) value).Add(Objects[i]);
+                else
+                    value = new List<object> {value, Objects[i]};
+            }
+            return value != null;
+        }
+
+        private bool ObjectsEqual(IReadOnlyCollection<object> otherObjects)
+        {
+            if (Objects == null)
+                return otherObjects == null;
+            return Objects.SequenceEqual(otherObjects);
+        }
+
+        private bool LabelsEqual(IReadOnlyList<List<string>> otherLabels)
+        {
+            if (Labels == null)
+                return otherLabels == null;
+            if (Labels.Count != otherLabels.Count)
+                return false;
+            var foundUnequalObjLabels = Labels.Where((objLabels, i) => !objLabels.SequenceEqual(otherLabels[i])).Any();
+            return !foundUnequalObjLabels;
+        }
+
+        /// <inheritdoc />
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != GetType()) return false;
+            return Equals((Path) obj);
+        }
+
+        /// <inheritdoc />
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                var hashCode = 19;
+                if (Labels != null)
+                    hashCode = Labels.Where(objLabels => objLabels != null)
+                        .Aggregate(hashCode,
+                            (current1, objLabels) => objLabels.Aggregate(current1,
+                                (current, label) => current * 31 + label.GetHashCode()));
+                if (Objects != null)
+                    hashCode = Objects.Aggregate(hashCode, (current, obj) => current * 31 + obj.GetHashCode());
+                return hashCode;
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Property.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Property.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Property.cs
new file mode 100644
index 0000000..daa052a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Property.cs
@@ -0,0 +1,96 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Structure
+{
+    /// <summary>
+    ///     A <see cref="Property" /> denotes a key/value pair associated with an <see cref="Edge" />.
+    /// </summary>
+    public class Property : IEquatable<Property>
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Property" /> class.
+        /// </summary>
+        /// <param name="key">The key of the property.</param>
+        /// <param name="value">The value of the property.</param>
+        /// <param name="element">The element that the property is associated with.</param>
+        public Property(string key, dynamic value, Element element)
+        {
+            Key = key;
+            Value = value;
+            Element = element;
+        }
+
+        /// <summary>
+        ///     Gets the key of the property.
+        /// </summary>
+        public string Key { get; }
+
+        /// <summary>
+        ///     Gets the value of the property.
+        /// </summary>
+        public dynamic Value { get; }
+
+        /// <summary>
+        ///     Gets the element that this property is associated with.
+        /// </summary>
+        public Element Element { get; }
+
+        /// <inheritdoc />
+        public bool Equals(Property other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return string.Equals(Key, other.Key) && Equals(Value, other.Value) && Equals(Element, other.Element);
+        }
+
+        /// <inheritdoc />
+        public override string ToString()
+        {
+            return $"p[{Key}->{Value}]";
+        }
+
+        /// <inheritdoc />
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != GetType()) return false;
+            return Equals((Property) obj);
+        }
+
+        /// <inheritdoc />
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                var hashCode = Key?.GetHashCode() ?? 0;
+                hashCode = (hashCode * 397) ^ (Value != null ? Value.GetHashCode() : 0);
+                hashCode = (hashCode * 397) ^ (Element?.GetHashCode() ?? 0);
+                return hashCode;
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/Vertex.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Vertex.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Vertex.cs
new file mode 100644
index 0000000..f667d26
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Vertex.cs
@@ -0,0 +1,52 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Structure
+{
+    /// <summary>
+    ///     Represents a vertex.
+    /// </summary>
+    public class Vertex : Element
+    {
+        /// <summary>
+        ///     The default label to use for a vertex.
+        /// </summary>
+        public const string DefaultLabel = "vertex";
+
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="Vertex" /> class.
+        /// </summary>
+        /// <param name="id">The id of the vertex.</param>
+        /// <param name="label">The label of the vertex.</param>
+        public Vertex(object id, string label = DefaultLabel)
+            : base(id, label)
+        {
+        }
+
+        /// <inheritdoc />
+        public override string ToString()
+        {
+            return $"v[{Id}]";
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.Net/Structure/VertexProperty.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/VertexProperty.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/VertexProperty.cs
new file mode 100644
index 0000000..8e20723
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/VertexProperty.cs
@@ -0,0 +1,66 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Structure
+{
+    /// <summary>
+    ///     A <see cref="VertexProperty" /> denotes a key/value pair associated with a <see cref="Vertex" />.
+    /// </summary>
+    public class VertexProperty : Element
+    {
+        /// <summary>
+        ///     Initializes a new instance of the <see cref="VertexProperty" /> class.
+        /// </summary>
+        /// <param name="id">The id of the vertex property.</param>
+        /// <param name="label">The label of the vertex property.</param>
+        /// <param name="value">The id of the vertex property.</param>
+        /// <param name="vertex">The <see cref="Vertex" /> that owns this <see cref="VertexProperty" />.</param>
+        public VertexProperty(object id, string label, dynamic value, Vertex vertex)
+            : base(id, label)
+        {
+            Value = value;
+            Vertex = vertex;
+        }
+
+        /// <summary>
+        ///     The value of this <see cref="VertexProperty" />.
+        /// </summary>
+        public dynamic Value { get; }
+
+        /// <summary>
+        ///     The <see cref="Vertex" /> that owns this <see cref="VertexProperty" />.
+        /// </summary>
+        public Vertex Vertex { get; }
+
+        /// <summary>
+        ///     The key of this <see cref="VertexProperty" />.
+        /// </summary>
+        public string Key => Label;
+
+        /// <inheritdoc />
+        public override string ToString()
+        {
+            return $"vp[{Label}->{Value}]";
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/pom.xml b/gremlin-dotnet/src/pom.xml
new file mode 100644
index 0000000..5fef134
--- /dev/null
+++ b/gremlin-dotnet/src/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.tinkerpop</groupId>
+        <artifactId>gremlin-dotnet</artifactId>
+        <version>3.2.5-SNAPSHOT</version>
+    </parent>
+    <artifactId>Gremlin-DotNet-Source</artifactId>
+    <packaging>${packaging.type}</packaging>
+    <profiles>
+        <profile>
+            <id>gremlin-dotnet-standard</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <properties>
+                <packaging.type>pom</packaging.type>
+            </properties>
+        </profile>
+        <!-- activates the building of .NET components and requires that the .NET Core SDK be installed on the system -->
+        <profile>
+            <id>gremlin-dotnet</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <file>
+                    <exists>.glv</exists>
+                </file>
+            </activation>
+            <properties>
+                <packaging.type>dotnet-library</packaging.type>
+            </properties>
+            <build>
+                <directory>${basedir}/target</directory>
+                <finalName>${project.artifactId}-${project.version}</finalName>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.eobjects.build</groupId>
+                        <artifactId>dotnet-maven-plugin</artifactId>
+                        <extensions>true</extensions>
+                        <configuration>
+                            <packOutput>${project.parent.basedir}/target/nuget</packOutput>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/BytecodeGenerationTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/BytecodeGenerationTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/BytecodeGenerationTests.cs
new file mode 100644
index 0000000..672ff35
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/BytecodeGenerationTests.cs
@@ -0,0 +1,76 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.BytecodeGeneration
+{
+    public class BytecodeGenerationTests
+    {
+        [Fact]
+        public void g_V_OutXcreatedX()
+        {
+            var g = new Graph().Traversal();
+
+            var bytecode = g.V().Out("created").Bytecode;
+
+            Assert.Equal(0, bytecode.SourceInstructions.Count);
+            Assert.Equal(2, bytecode.StepInstructions.Count);
+            Assert.Equal("V", bytecode.StepInstructions[0].OperatorName);
+            Assert.Equal("out", bytecode.StepInstructions[1].OperatorName);
+            Assert.Equal("created", bytecode.StepInstructions[1].Arguments[0]);
+            Assert.Equal(1, bytecode.StepInstructions[1].Arguments.Length);
+        }
+
+        [Fact]
+        public void g_WithSackX1X_E_GroupCount_ByXweightX()
+        {
+            var g = new Graph().Traversal();
+
+            var bytecode = g.WithSack(1).E().GroupCount().By("weight").Bytecode;
+
+            Assert.Equal(1, bytecode.SourceInstructions.Count);
+            Assert.Equal("withSack", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(1, bytecode.SourceInstructions[0].Arguments[0]);
+            Assert.Equal(3, bytecode.StepInstructions.Count);
+            Assert.Equal("E", bytecode.StepInstructions[0].OperatorName);
+            Assert.Equal("groupCount", bytecode.StepInstructions[1].OperatorName);
+            Assert.Equal("by", bytecode.StepInstructions[2].OperatorName);
+            Assert.Equal("weight", bytecode.StepInstructions[2].Arguments[0]);
+            Assert.Equal(0, bytecode.StepInstructions[0].Arguments.Length);
+            Assert.Equal(0, bytecode.StepInstructions[1].Arguments.Length);
+            Assert.Equal(1, bytecode.StepInstructions[2].Arguments.Length);
+        }
+
+        [Fact]
+        public void AnonymousTraversal_Start_EmptyBytecode()
+        {
+            var bytecode = __.Start().Bytecode;
+
+            Assert.Equal(0, bytecode.SourceInstructions.Count);
+            Assert.Equal(0, bytecode.StepInstructions.Count);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/StrategiesTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/StrategiesTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/StrategiesTests.cs
new file mode 100644
index 0000000..6afda71
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/BytecodeGeneration/StrategiesTests.cs
@@ -0,0 +1,170 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+using Gremlin.Net.Process.Traversal.Strategy.Finalization;
+using Gremlin.Net.Process.Traversal.Strategy.Optimization;
+using Gremlin.Net.Process.Traversal.Strategy.Verification;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.BytecodeGeneration
+{
+    public class StrategiesTests
+    {
+        [Fact]
+        public void TraversalWithoutStrategies_AfterWithStrategiesWasCalled_WithStrategiesNotAffected()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal().WithStrategies(new ReadOnlyStrategy(), new IncidentToAdjacentStrategy());
+
+            var bytecode = g.WithoutStrategies(new ReadOnlyStrategy()).Bytecode;
+
+            Assert.Equal(2, bytecode.SourceInstructions.Count);
+            Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(2, bytecode.SourceInstructions[0].Arguments.Length);
+            Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+            Assert.Equal(new IncidentToAdjacentStrategy(), bytecode.SourceInstructions[0].Arguments[1]);
+
+            Assert.Equal("withoutStrategies", bytecode.SourceInstructions[1].OperatorName);
+            Assert.Equal(1, bytecode.SourceInstructions[1].Arguments.Length);
+            Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[1].Arguments[0]);
+        }
+
+        [Fact]
+        public void ShouldIncludeMultipleStrategiesInBytecodeWhenGivenToWithoutStrategies()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal();
+
+            var bytecode = g.WithoutStrategies(new ReadOnlyStrategy(), new LazyBarrierStrategy()).Bytecode;
+
+            Assert.Equal(1, bytecode.SourceInstructions.Count);
+            Assert.Equal(2, bytecode.SourceInstructions[0].Arguments.Length);
+            Assert.Equal("withoutStrategies", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+            Assert.Equal(new LazyBarrierStrategy(), bytecode.SourceInstructions[0].Arguments[1]);
+        }
+
+        [Fact]
+        public void ShouldIncludeOneStrategyInBytecodeWhenGivenToWithoutStrategies()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal();
+
+            var bytecode = g.WithoutStrategies(new ReadOnlyStrategy()).Bytecode;
+
+            Assert.Equal(1, bytecode.SourceInstructions.Count);
+            Assert.Equal(1, bytecode.SourceInstructions[0].Arguments.Length);
+            Assert.Equal("withoutStrategies", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+        }
+
+        [Fact]
+        public void ShouldIncludeConfigurationInBytecodeWhenGivenToWithStrategies()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal();
+
+            var bytecode = g.WithStrategies(new MatchAlgorithmStrategy("greedy")).Bytecode;
+
+            Assert.Equal(1, bytecode.SourceInstructions.Count);
+            Assert.Equal(1, bytecode.SourceInstructions[0].Arguments.Length);
+            Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(new MatchAlgorithmStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+            Assert.Contains("greedy",
+                ((MatchAlgorithmStrategy) bytecode.SourceInstructions[0].Arguments[0]).Configuration.Values);
+        }
+
+        [Fact]
+        public void ShouldIncludeMultipleStrategiesInBytecodeWhenGivenToWithStrategies()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal();
+
+            var bytecode = g.WithStrategies(new ReadOnlyStrategy(), new IncidentToAdjacentStrategy()).Bytecode;
+
+            Assert.Equal(1, bytecode.SourceInstructions.Count);
+            Assert.Equal(2, bytecode.SourceInstructions[0].Arguments.Length);
+            Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+            Assert.Equal(new IncidentToAdjacentStrategy(), bytecode.SourceInstructions[0].Arguments[1]);
+        }
+
+        [Fact]
+        public void ShouldIncludeOneStrategyInBytecodeWhenGivenToWithStrategies()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal();
+
+            var bytecode = g.WithStrategies(new ReadOnlyStrategy()).Bytecode;
+
+            Assert.Equal(1, bytecode.SourceInstructions.Count);
+            Assert.Equal(1, bytecode.SourceInstructions[0].Arguments.Length);
+            Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+            Assert.Equal("ReadOnlyStrategy", bytecode.SourceInstructions[0].Arguments[0].ToString());
+            Assert.Equal(new ReadOnlyStrategy().GetHashCode(), bytecode.SourceInstructions[0].Arguments[0].GetHashCode());
+            Assert.Equal(0, g.TraversalStrategies.Count);
+        }
+
+        [Fact]
+        public void TraversalWithStrategies_Strategies_ApplyToReusedGraphTraversalSource()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal().WithStrategies(new ReadOnlyStrategy(), new IncidentToAdjacentStrategy());
+
+            var bytecode = g.V().Bytecode;
+
+            Assert.Equal(1, bytecode.SourceInstructions.Count);
+            Assert.Equal(2, bytecode.SourceInstructions[0].Arguments.Length);
+            Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(new ReadOnlyStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+            Assert.Equal(new IncidentToAdjacentStrategy(), bytecode.SourceInstructions[0].Arguments[1]);
+            Assert.Equal(1, bytecode.StepInstructions.Count);
+            Assert.Equal("V", bytecode.StepInstructions[0].OperatorName);
+        }
+
+        [Fact]
+        public void TraversalWithStrategies_StrategyWithTraversalInConfig_IncludeTraversalInInConfigInBytecode()
+        {
+            var graph = new Graph();
+            var g = graph.Traversal();
+
+            var bytecode = g.WithStrategies(new SubgraphStrategy(__.Has("name", "marko"))).Bytecode;
+
+            Assert.Equal(1, bytecode.SourceInstructions.Count);
+            Assert.Equal(1, bytecode.SourceInstructions[0].Arguments.Length);
+            Assert.Equal("withStrategies", bytecode.SourceInstructions[0].OperatorName);
+            Assert.Equal(new SubgraphStrategy(), bytecode.SourceInstructions[0].Arguments[0]);
+            SubgraphStrategy strategy = bytecode.SourceInstructions[0].Arguments[0];
+            Assert.Equal(1, strategy.Configuration.Count);
+            Assert.Equal(typeof(GraphTraversal), strategy.Configuration["vertices"].GetType());
+            GraphTraversal traversal = strategy.Configuration["vertices"];
+            Assert.Equal("has", traversal.Bytecode.StepInstructions[0].OperatorName);
+            Assert.Equal(new List<string> {"name", "marko"}, traversal.Bytecode.StepInstructions[0].Arguments);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/ConfigProvider.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/ConfigProvider.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/ConfigProvider.cs
new file mode 100644
index 0000000..27e7009
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/ConfigProvider.cs
@@ -0,0 +1,47 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.IO;
+using Microsoft.Extensions.Configuration;
+
+namespace Gremlin.CSharp.IntegrationTest
+{
+    public static class ConfigProvider
+    {
+        static ConfigProvider()
+        {
+            Configuration = GetConfig();
+        }
+
+        public static IConfiguration Configuration { get; }
+
+        private static IConfiguration GetConfig()
+        {
+            var configFile = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
+            var builder = new ConfigurationBuilder()
+                .AddJsonFile(configFile, false, false);
+
+            return builder.Build();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/EnumTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/EnumTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/EnumTests.cs
new file mode 100644
index 0000000..a49a09d
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/EnumTests.cs
@@ -0,0 +1,59 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+    public class EnumTests
+    {
+        private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+        [Fact]
+        public void ShouldUseOrderDecrInByStep()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var orderedAges = g.V().Values("age").Order().By(Order.decr).ToList();
+
+            Assert.Equal(new List<object> {35, 32, 29, 27}, orderedAges);
+        }
+
+        [Fact]
+        public void ShouldUseTLabelInHasStep()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var personsCount = g.V().Has(T.label, "person").Count().Next();
+
+            Assert.Equal((long) 4, personsCount);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalSourceTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalSourceTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalSourceTests.cs
new file mode 100644
index 0000000..f8c12e2
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalSourceTests.cs
@@ -0,0 +1,55 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+    public class GraphTraversalSourceTests
+    {
+        private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+        [Fact]
+        public void ShouldUseSideEffectSpecifiedInWithSideEffect()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var results = g.WithSideEffect("a", new List<string> {"josh", "peter"})
+                .V(1)
+                .Out("created")
+                .In("created")
+                .Values("name")
+                .Where(P.Within("a"))
+                .ToList();
+
+            Assert.Equal(2, results.Count);
+            Assert.Contains("josh", results);
+            Assert.Contains("peter", results);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalTests.cs
new file mode 100644
index 0000000..91a41ba
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/GraphTraversalTests.cs
@@ -0,0 +1,171 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+    public class GraphTraversalTests
+    {
+        private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+        [Fact]
+        public void g_V_Count()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var count = g.V().Count().Next();
+
+            Assert.Equal((long) 6, count);
+        }
+
+        [Fact]
+        public void g_VX1X_Next()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var vertex = (Vertex) g.V(1).Next();
+
+            Assert.Equal(new Vertex((long) 1), vertex);
+            Assert.Equal((long) 1, vertex.Id);
+        }
+
+        [Fact]
+        public void g_VX1X_NextTraverser()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var traverser = g.V(1).NextTraverser();
+
+            Assert.Equal(new Traverser(new Vertex((long)1)), traverser);
+        }
+
+        [Fact]
+        public void g_VX1X_ToList()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var list = g.V(1).ToList();
+
+            Assert.Equal(1, list.Count);
+        }
+
+        [Fact]
+        public void g_V_RepeatXBothX_TimesX5X_NextX10X()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var result = g.V().Repeat(__.Both()).Times(5).Next(10);
+
+            Assert.Equal(10, result.Count());
+        }
+
+        [Fact]
+        public void g_V_HasXname_markoX_ValueMap_Next()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var receivedValueMap = g.V().Has("name", "marko").ValueMap().Next();
+
+            var expectedValueMap = new Dictionary<string, dynamic>
+            {
+                {"age", new List<object> {29}},
+                {"name", new List<object> {"marko"}}
+            };
+            Assert.Equal(expectedValueMap, receivedValueMap);
+        }
+
+        [Fact]
+        public void g_V_RepeatXOutX_TimesX2X_ValuesXNameX()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var t = g.V().Repeat(__.Out()).Times(2).Values("name");
+            var names = t.ToList();
+
+            Assert.Equal((long) 2, names.Count);
+            Assert.Contains("lop", names);
+            Assert.Contains("ripple", names);
+        }
+
+        [Fact]
+        public void ShortestPathTest()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var shortestPath =
+                (Path) g.V(5).Repeat(__.Both().SimplePath()).Until(__.HasId(6)).Limit(1).Path().Next();
+
+            Assert.Equal((long) 4, shortestPath.Count);
+            Assert.Equal(new Vertex((long) 6), shortestPath[3]);
+        }
+
+        [Fact]
+        public void ShouldUseBindingsInTraversal()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var b = new Bindings();
+            var count = g.V().Has(b.Of("propertyKey", "name"), b.Of("propertyValue", "marko")).OutE().Count().Next();
+
+            Assert.Equal((long) 3, count);
+        }
+
+        [Fact]
+        public async Task ShouldExecuteAsynchronouslyWhenPromiseIsCalled()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var count = await g.V().Count().Promise(t => t.Next());
+
+            Assert.Equal((long) 6, count);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/PredicateTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/PredicateTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/PredicateTests.cs
new file mode 100644
index 0000000..8dffa43
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/PredicateTests.cs
@@ -0,0 +1,58 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+    public class PredicateTests
+    {
+        private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+        [Fact]
+        public void ShouldUsePredicatesCombinedWithPAndInHasStep()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var count = g.V().Has("age", P.Gt(30).And(P.Lt(35))).Count().Next();
+
+            Assert.Equal((long) 1, count);
+        }
+
+        [Fact]
+        public void ShouldUsePWithinInHasStep()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var count = g.V().Has("name", P.Within("josh", "vadas")).Count().Next();
+
+            Assert.Equal((long) 2, count);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/RemoteConnectionFactory.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/RemoteConnectionFactory.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/RemoteConnectionFactory.cs
new file mode 100644
index 0000000..53b6e50
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/RemoteConnectionFactory.cs
@@ -0,0 +1,41 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using Gremlin.Net.Driver;
+using Gremlin.Net.Process.Remote;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+    internal class RemoteConnectionFactory
+    {
+        private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"];
+        private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]);
+
+        public IRemoteConnection CreateRemoteConnection()
+        {
+            return new Net.Driver.Remote.DriverRemoteConnection(
+                new GremlinClient(new GremlinServer(TestHost, TestPort)));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/SideEffectTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/SideEffectTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/SideEffectTests.cs
new file mode 100644
index 0000000..8051167
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/SideEffectTests.cs
@@ -0,0 +1,221 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Gremlin.CSharp.Structure;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+    public class SideEffectTests
+    {
+        private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+        [Fact]
+        public void ShouldReturnCachedSideEffectWhenGetIsCalledAfterClose()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var t = g.V().Aggregate("a").Iterate();
+
+            t.SideEffects.Get("a");
+            t.SideEffects.Close();
+            var results = t.SideEffects.Get("a");
+
+            Assert.NotNull(results);
+        }
+
+        [Fact]
+        public void ShouldThrowWhenGetIsCalledAfterCloseAndNoSideEffectsAreCachec()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var t = g.V().Aggregate("a").Iterate();
+
+            t.SideEffects.Close();
+            Assert.Throws<InvalidOperationException>(() => t.SideEffects.Get("a"));
+        }
+
+        [Fact]
+        public void ShouldThrowWhenGetIsCalledAfterDisposeAndNoSideEffectsAreCachec()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var t = g.V().Aggregate("a").Iterate();
+
+            t.SideEffects.Dispose();
+            Assert.Throws<InvalidOperationException>(() => t.SideEffects.Get("a"));
+        }
+
+        [Fact]
+        public void ShouldReturnSideEffectValueWhenGetIsCalledForGroupCountTraversal()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var t = g.V().Out("created").GroupCount("m").By("name").Iterate();
+            t.SideEffects.Keys();
+
+            var m = t.SideEffects.Get("m") as Dictionary<string, dynamic>;
+
+            Assert.Equal(2, m.Count);
+            Assert.Equal((long) 3, m["lop"]);
+            Assert.Equal((long) 1, m["ripple"]);
+        }
+
+        [Fact]
+        public void ShouldReturnSideEffectValueWhenGetIsCalledOnATraversalWithSideEffect()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var t = g.WithSideEffect("a", new List<string> {"first", "second"}).V().Iterate();
+            t.SideEffects.Keys();
+
+            var a = t.SideEffects.Get("a") as List<object>;
+
+            Assert.Equal(2, a.Count);
+            Assert.Equal("first", a[0]);
+            Assert.Equal("second", a[1]);
+        }
+
+        [Fact]
+        public void ShouldThrowWhenGetIsCalledWithAnUnknownKey()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var t = g.V().Iterate();
+
+            Assert.Throws<KeyNotFoundException>(() => t.SideEffects.Get("m"));
+        }
+
+        [Fact]
+        public void ShouldReturnBothSideEffectForTraversalWithTwoSideEffects_()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var t = g.V().Out("created").GroupCount("m").By("name").Values("name").Aggregate("n").Iterate();
+
+            var keys = t.SideEffects.Keys().ToList();
+            Assert.Equal(2, keys.Count);
+            Assert.Contains("m", keys);
+            Assert.Contains("n", keys);
+            var n = (Dictionary<object, long>) t.SideEffects.Get("n");
+            Assert.Equal(2, n.Count);
+            Assert.Equal(3, n["lop"]);
+            Assert.Equal(1, n["ripple"]);
+        }
+
+        [Fact]
+        public void ShouldReturnAnEmptyCollectionWhenKeysIsCalledForTraversalWithoutSideEffect()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var t = g.V().Iterate();
+            var keys = t.SideEffects.Keys();
+
+            Assert.Equal(0, keys.Count);
+        }
+
+        [Fact]
+        public void ShouldReturnCachedKeysWhenForCloseAfterSomeGet()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var t = g.V().Aggregate("a").Aggregate("b").Iterate();
+
+            t.SideEffects.Get("a");
+            t.SideEffects.Close();
+            var keys = t.SideEffects.Keys();
+
+            Assert.Equal(2, keys.Count);
+            Assert.Contains("a", keys);
+            Assert.Contains("b", keys);
+        }
+
+        [Fact]
+        public void ShouldReturnSideEffectKeyWhenKeysIsCalledForNamedGroupCount()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+            var t = g.V().Out("created").GroupCount("m").By("name").Iterate();
+
+            var keys = t.SideEffects.Keys();
+
+            var keysList = keys.ToList();
+            Assert.Equal(1, keysList.Count);
+            Assert.Contains("m", keysList);
+        }
+
+        [Fact]
+        public async Task ShouldReturnSideEffectsKeysWhenKeysIsCalledOnTraversalThatExecutedAsynchronously()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var t = await g.V().Aggregate("a").Promise(x => x);
+            var keys = t.SideEffects.Keys();
+
+            Assert.Equal(1, keys.Count);
+            Assert.Contains("a", keys);
+        }
+
+        [Fact]
+        public async Task ShouldReturnSideEffectValueWhenGetIsCalledOnTraversalThatExecutedAsynchronously()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var t = await g.V().Aggregate("a").Promise(x => x);
+            var value = t.SideEffects.Get("a");
+
+            Assert.NotNull(value);
+        }
+
+        [Fact]
+        public async Task ShouldNotThrowWhenCloseIsCalledOnTraversalThatExecutedAsynchronously()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection);
+
+            var t = await g.V().Aggregate("a").Promise(x => x);
+            t.SideEffects.Close();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/StrategiesTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/StrategiesTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/StrategiesTests.cs
new file mode 100644
index 0000000..59e2092
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/DriverRemoteConnection/StrategiesTests.cs
@@ -0,0 +1,193 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Threading.Tasks;
+using Gremlin.CSharp.Process;
+using Gremlin.CSharp.Structure;
+using Gremlin.Net.Driver.Exceptions;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+using Gremlin.Net.Process.Traversal.Strategy.Verification;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest.DriverRemoteConnection
+{
+    public class StrategiesTests
+    {
+        private readonly RemoteConnectionFactory _connectionFactory = new RemoteConnectionFactory();
+
+        [Fact]
+        public void g_V_Count_Next_WithVertexLabelSubgraphStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g =
+                graph.Traversal()
+                    .WithRemote(connection)
+                    .WithStrategies(new SubgraphStrategy(vertexCriterion: __.HasLabel("person")));
+
+            var count = g.V().Count().Next();
+
+            Assert.Equal((long) 4, count);
+        }
+
+        [Fact]
+        public void g_E_Count_Next_WithVertexAndEdgeLabelSubgraphStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g =
+                graph.Traversal()
+                    .WithRemote(connection)
+                    .WithStrategies(new SubgraphStrategy(vertexCriterion: __.HasLabel("person"),
+                        edgeCriterion: __.HasLabel("created")));
+
+            var count = g.E().Count().Next();
+
+            Assert.Equal((long)0, count);
+        }
+
+        [Fact]
+        public void g_V_Label_Dedup_Count_Next_WithVertexLabelSubgraphStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g =
+                graph.Traversal()
+                    .WithRemote(connection)
+                    .WithStrategies(new SubgraphStrategy(vertexCriterion: __.HasLabel("person")));
+
+            var count = g.V().Label().Dedup().Count().Next();
+
+            Assert.Equal((long)1, count);
+        }
+
+        [Fact]
+        public void g_V_Label_Dedup_Next_WWithVertexLabelSubgraphStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g =
+                graph.Traversal()
+                    .WithRemote(connection)
+                    .WithStrategies(new SubgraphStrategy(vertexCriterion: __.HasLabel("person")));
+
+            var label = g.V().Label().Dedup().Next();
+
+            Assert.Equal("person", label);
+        }
+
+        [Fact]
+        public void g_V_Count_Next_WithVertexHasPropertySubgraphStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g =
+                graph.Traversal()
+                    .WithRemote(connection)
+                    .WithStrategies(new SubgraphStrategy(vertexCriterion: __.Has("name", "marko")));
+
+            var count = g.V().Count().Next();
+
+            Assert.Equal((long)1, count);
+        }
+
+        [Fact]
+        public void g_E_Count_Next_WithEdgeLimitSubgraphStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g =
+                graph.Traversal()
+                    .WithRemote(connection)
+                    .WithStrategies(new SubgraphStrategy(edgeCriterion: __.Limit(0)));
+
+            var count = g.E().Count().Next();
+
+            Assert.Equal((long)0, count);
+        }
+
+        [Fact]
+        public void g_V_Label_Dedup_Next_WithVertexHasPropertySubgraphStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g =
+                graph.Traversal()
+                    .WithRemote(connection)
+                    .WithStrategies(new SubgraphStrategy(vertexCriterion: __.Has("name", "marko")));
+
+            var label = g.V().Label().Dedup().Next();
+
+            Assert.Equal("person", label);
+        }
+
+        [Fact]
+        public void g_V_ValuesXnameX_Next_WithVertexHasPropertySubgraphStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g =
+                graph.Traversal()
+                    .WithRemote(connection)
+                    .WithStrategies(new SubgraphStrategy(vertexCriterion: __.Has("name", "marko")));
+
+            var name = g.V().Values("name").Next();
+
+            Assert.Equal("marko", name);
+        }
+
+        [Fact]
+        public void g_V_Count_Next_WithComputer()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection).WithComputer();
+
+            var count = g.V().Count().Next();
+
+            Assert.Equal((long)6, count);
+        }
+
+        [Fact]
+        public void g_E_Count_Next_WithComputer()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection).WithComputer();
+
+            var count = g.E().Count().Next();
+
+            Assert.Equal((long)6, count);
+        }
+
+        [Fact]
+        public async Task ShouldThrowWhenModifyingTraversalSourceWithReadOnlyStrategy()
+        {
+            var graph = new Graph();
+            var connection = _connectionFactory.CreateRemoteConnection();
+            var g = graph.Traversal().WithRemote(connection).WithStrategies(new ReadOnlyStrategy());
+
+            await Assert.ThrowsAsync<ResponseException>(async () => await g.AddV("person").Promise(t => t.Next()));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/GraphSONWriterTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/GraphSONWriterTests.cs b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/GraphSONWriterTests.cs
new file mode 100644
index 0000000..99a1b65
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/GraphSONWriterTests.cs
@@ -0,0 +1,50 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using Gremlin.CSharp.Process;
+using Gremlin.Net.Structure.IO.GraphSON;
+using Xunit;
+
+namespace Gremlin.CSharp.IntegrationTest
+{
+    public class GraphSONWriterTests
+    {
+        [Fact]
+        public void ShouldSerializeLongPredicateCorrectly()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var predicate = P.Lt("b").Or(P.Gt("c")).And(P.Neq("d"));
+
+            var graphSon = writer.WriteObject(predicate);
+
+            const string expected =
+                "{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"and\",\"value\":[{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"or\",\"value\":[{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"lt\",\"value\":\"b\"}},{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"gt\",\"value\":\"c\"}}]}},{\"@type\":\"g:P\",\"@value\":{\"predicate\":\"neq\",\"value\":\"d\"}}]}}";
+            Assert.Equal(expected, graphSon);
+        }
+
+        private GraphSONWriter CreateStandardGraphSONWriter()
+        {
+            return new GraphSONWriter();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Gremlin.CSharp.IntegrationTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Gremlin.CSharp.IntegrationTest.csproj b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Gremlin.CSharp.IntegrationTest.csproj
new file mode 100644
index 0000000..1e7a7d2
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.CSharp.IntegrationTest/Gremlin.CSharp.IntegrationTest.csproj
@@ -0,0 +1,38 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <AssemblyName>Gremlin.CSharp.IntegrationTest</AssemblyName>
+    <PackageId>Gremlin.CSharp.IntegrationTest</PackageId>
+    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
+    <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
+    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\Gremlin.CSharp\Gremlin.CSharp.csproj" />
+    <ProjectReference Include="..\..\src\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+    <ProjectReference Include="..\..\src\Gremlin.Net\Gremlin.Net.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+    <PackageReference Include="xunit" Version="2.2.0" />
+    <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.1" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <None Update="appsettings.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+
+</Project>


[7/7] tinkerpop git commit: Add Gremlin-CSharp and Gremlin-DotNet

Posted by sp...@apache.org.
Add Gremlin-CSharp and Gremlin-DotNet

This adds Gremlin-CSharp (a C# GLV), together with a .NET driver. The
driver is based on Gremlin.Net
(https://github.com/FlorianHockmann/Gremlin.Net) with added support for
GLVs and Gremlin-CSharp is auto generated, very similar to
Gremlin-Python.
This should fix TINKERPOP-1552.


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

Branch: refs/heads/TINKERPOP-1552
Commit: 72553d680ef5a07b445518524809afc86c2743c8
Parents: abe23d4
Author: Florian Hockmann <fh...@florian-hockmann.de>
Authored: Thu Apr 6 19:02:23 2017 +0200
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 18 12:49:37 2017 -0400

----------------------------------------------------------------------
 .gitignore                                      |   9 +
 .travis.yml                                     |   5 +
 docker/Dockerfile                               |   6 +-
 .../developer/development-environment.asciidoc  |  20 +-
 docs/src/reference/gremlin-variants.asciidoc    | 196 ++++++
 gremlin-csharp-generator/pom.xml                |  60 ++
 .../csharp/AnonymousTraversalGenerator.groovy   |  71 +++
 .../gremlin/csharp/CommonContentHelper.groovy   |  49 ++
 .../gremlin/csharp/EnumGenerator.groovy         |  62 ++
 .../gremlin/csharp/GenerateGremlinCSharp.groovy |  32 +
 .../csharp/GraphTraversalGenerator.groovy       |  77 +++
 .../csharp/GraphTraversalSourceGenerator.groovy | 140 +++++
 .../gremlin/csharp/PredicateGenerator.groovy    |  66 ++
 .../gremlin/csharp/SymbolHelper.groovy          |  31 +
 gremlin-dotnet/Gremlin.Net.sln                  |  80 +++
 gremlin-dotnet/pom.xml                          |  39 ++
 .../src/Gremlin.CSharp/Gremlin.CSharp.csproj    |  21 +
 .../src/Gremlin.CSharp/Process/Barrier.cs       |  30 +
 .../src/Gremlin.CSharp/Process/Cardinality.cs   |  32 +
 .../src/Gremlin.CSharp/Process/Column.cs        |  31 +
 .../src/Gremlin.CSharp/Process/Direction.cs     |  32 +
 .../Gremlin.CSharp/Process/GraphTraversal.cs    | 630 +++++++++++++++++++
 .../Process/GraphTraversalSource.cs             | 143 +++++
 .../src/Gremlin.CSharp/Process/Operator.cs      |  40 ++
 .../src/Gremlin.CSharp/Process/Order.cs         |  36 ++
 gremlin-dotnet/src/Gremlin.CSharp/Process/P.cs  | 108 ++++
 .../src/Gremlin.CSharp/Process/Pick.cs          |  31 +
 .../src/Gremlin.CSharp/Process/Pop.cs           |  32 +
 .../src/Gremlin.CSharp/Process/Scope.cs         |  31 +
 gremlin-dotnet/src/Gremlin.CSharp/Process/T.cs  |  33 +
 gremlin-dotnet/src/Gremlin.CSharp/Process/__.cs | 488 ++++++++++++++
 .../src/Gremlin.CSharp/Structure/Graph.cs       |  35 ++
 .../Gremlin.Net.Process.csproj                  |  24 +
 .../Remote/IRemoteConnection.cs                 |  42 ++
 .../Remote/RemoteStrategy.cs                    |  61 ++
 .../Gremlin.Net.Process/Traversal/Binding.cs    |  80 +++
 .../Gremlin.Net.Process/Traversal/Bindings.cs   |  42 ++
 .../Gremlin.Net.Process/Traversal/Bytecode.cs   |  85 +++
 .../Traversal/DefaultTraversal.cs               | 195 ++++++
 .../Gremlin.Net.Process/Traversal/ITraversal.cs |  96 +++
 .../Traversal/ITraversalSideEffects.cs          |  52 ++
 .../Traversal/ITraversalStrategy.cs             |  46 ++
 .../Traversal/Instruction.cs                    |  52 ++
 .../Strategy/AbstractTraversalStrategy.cs       |  86 +++
 .../Strategy/Decoration/ConnectiveStrategy.cs   |  33 +
 .../Strategy/Decoration/ElementIdStrategy.cs    |  32 +
 .../Decoration/HaltedTraverserStrategy.cs       |  34 +
 .../Strategy/Decoration/PartitionStrategy.cs    |  56 ++
 .../Strategy/Decoration/SubgraphStrategy.cs     |  48 ++
 .../Decoration/VertexProgramStrategy.cs         |  50 ++
 .../Finalization/MatchAlgorithmStrategy.cs      |  34 +
 .../Optimization/AdjacentToIncidentStrategy.cs  |  32 +
 .../Optimization/FilterRankingStrategy.cs       |  32 +
 .../Optimization/GraphFilterStrategy.cs         |  29 +
 .../Optimization/IdentityRemovalStrategy.cs     |  32 +
 .../Optimization/IncidentToAdjacentStrategy.cs  |  33 +
 .../Optimization/InlineFilterStrategy.cs        |  32 +
 .../Optimization/LazyBarrierStrategy.cs         |  33 +
 .../Optimization/MatchPredicateStrategy.cs      |  32 +
 .../Strategy/Optimization/OrderLimitStrategy.cs |  29 +
 .../Optimization/PathProcessorStrategy.cs       |  32 +
 .../Optimization/PathRetractionStrategy.cs      |  29 +
 .../Optimization/RangeByIsCountStrategy.cs      |  32 +
 .../Optimization/RepeatUnrollStrategy.cs        |  29 +
 .../Verification/LambdaRestrictionStrategy.cs   |  32 +
 .../Strategy/Verification/ReadOnlyStrategy.cs   |  32 +
 .../Traversal/TraversalPredicate.cs             |  85 +++
 .../Gremlin.Net.Process/Traversal/Traverser.cs  |  75 +++
 .../src/Gremlin.Net/Driver/Connection.cs        | 133 ++++
 .../src/Gremlin.Net/Driver/ConnectionFactory.cs |  47 ++
 .../src/Gremlin.Net/Driver/ConnectionPool.cs    | 114 ++++
 .../Driver/Exceptions/ResponseException.cs      |  37 ++
 .../src/Gremlin.Net/Driver/GremlinClient.cs     |  95 +++
 .../Driver/GremlinClientExtensions.cs           | 140 +++++
 .../src/Gremlin.Net/Driver/GremlinServer.cs     |  56 ++
 .../src/Gremlin.Net/Driver/IConnection.cs       |  35 ++
 .../src/Gremlin.Net/Driver/IGremlinClient.cs    |  48 ++
 .../Gremlin.Net/Driver/JsonMessageSerializer.cs |  49 ++
 .../Driver/Messages/RequestMessage.cs           | 143 +++++
 .../Driver/Messages/ResponseMessage.cs          |  40 ++
 .../Driver/Messages/ResponseResult.cs           |  37 ++
 .../Driver/Messages/ResponseStatus.cs           |  50 ++
 .../Driver/Messages/ResponseStatusCode.cs       |  67 ++
 .../src/Gremlin.Net/Driver/ProxyConnection.cs   |  52 ++
 .../Driver/Remote/DriverRemoteConnection.cs     |  80 +++
 .../Driver/Remote/DriverRemoteTraversal.cs      |  39 ++
 .../Remote/DriverRemoteTraversalSideEffects.cs  | 126 ++++
 .../ResultsAggregation/AggregatorFactory.cs     |  44 ++
 .../ResultsAggregation/DefaultAggregator.cs     |  42 ++
 .../ResultsAggregation/DictionaryAggregator.cs  |  44 ++
 .../Driver/ResultsAggregation/IAggregator.cs    |  31 +
 .../ResultsAggregation/TraverserAggregator.cs   |  44 ++
 gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs | 114 ++++
 .../Gremlin.Net/Driver/WebSocketConnection.cs   |  96 +++
 .../src/Gremlin.Net/Gremlin.Net.csproj          |  43 ++
 .../src/Gremlin.Net/Properties/AssemblyInfo.cs  |  44 ++
 .../src/Gremlin.Net/Structure/Edge.cs           |  61 ++
 .../src/Gremlin.Net/Structure/Element.cs        |  77 +++
 .../Structure/IO/GraphSON/BindingSerializer.cs  |  42 ++
 .../Structure/IO/GraphSON/BytecodeSerializer.cs |  58 ++
 .../Structure/IO/GraphSON/DateDeserializer.cs   |  43 ++
 .../Structure/IO/GraphSON/DateSerializer.cs     |  43 ++
 .../Structure/IO/GraphSON/DoubleConverter.cs    |  33 +
 .../Structure/IO/GraphSON/EdgeDeserializer.cs   |  43 ++
 .../Structure/IO/GraphSON/EdgeSerializer.cs     |  45 ++
 .../Structure/IO/GraphSON/EnumSerializer.cs     |  37 ++
 .../Structure/IO/GraphSON/FloatConverter.cs     |  33 +
 .../Structure/IO/GraphSON/GraphSONReader.cs     | 123 ++++
 .../Structure/IO/GraphSON/GraphSONTokens.cs     |  32 +
 .../Structure/IO/GraphSON/GraphSONUtil.cs       |  62 ++
 .../Structure/IO/GraphSON/GraphSONWriter.cs     | 146 +++++
 .../IO/GraphSON/IGraphSONDeserializer.cs        |  41 ++
 .../IO/GraphSON/IGraphSONSerializer.cs          |  41 ++
 .../Structure/IO/GraphSON/Int32Converter.cs     |  33 +
 .../Structure/IO/GraphSON/Int64Converter.cs     |  33 +
 .../Structure/IO/GraphSON/NumberConverter.cs    |  45 ++
 .../Structure/IO/GraphSON/PathDeserializer.cs   |  41 ++
 .../IO/GraphSON/PropertyDeserializer.cs         |  38 ++
 .../Structure/IO/GraphSON/PropertySerializer.cs |  64 ++
 .../IO/GraphSON/RequestMessageSerializer.cs     |  43 ++
 .../IO/GraphSON/TraversalPredicateSerializer.cs |  45 ++
 .../IO/GraphSON/TraversalSerializer.cs          |  38 ++
 .../IO/GraphSON/TraversalStrategySerializer.cs  |  37 ++
 .../Structure/IO/GraphSON/TraverserReader.cs    |  38 ++
 .../Structure/IO/GraphSON/UuidDeserializer.cs   |  36 ++
 .../Structure/IO/GraphSON/UuidSerializer.cs     |  37 ++
 .../Structure/IO/GraphSON/VertexDeserializer.cs |  37 ++
 .../IO/GraphSON/VertexPropertyDeserializer.cs   |  41 ++
 .../IO/GraphSON/VertexPropertySerializer.cs     |  43 ++
 .../Structure/IO/GraphSON/VertexSerializer.cs   |  41 ++
 .../src/Gremlin.Net/Structure/Path.cs           | 193 ++++++
 .../src/Gremlin.Net/Structure/Property.cs       |  96 +++
 .../src/Gremlin.Net/Structure/Vertex.cs         |  52 ++
 .../src/Gremlin.Net/Structure/VertexProperty.cs |  66 ++
 gremlin-dotnet/src/pom.xml                      |  55 ++
 .../BytecodeGenerationTests.cs                  |  76 +++
 .../BytecodeGeneration/StrategiesTests.cs       | 170 +++++
 .../ConfigProvider.cs                           |  47 ++
 .../DriverRemoteConnection/EnumTests.cs         |  59 ++
 .../GraphTraversalSourceTests.cs                |  55 ++
 .../GraphTraversalTests.cs                      | 171 +++++
 .../DriverRemoteConnection/PredicateTests.cs    |  58 ++
 .../RemoteConnectionFactory.cs                  |  41 ++
 .../DriverRemoteConnection/SideEffectTests.cs   | 221 +++++++
 .../DriverRemoteConnection/StrategiesTests.cs   | 193 ++++++
 .../GraphSONWriterTests.cs                      |  50 ++
 .../Gremlin.CSharp.IntegrationTest.csproj       |  38 ++
 .../Properties/AssemblyInfo.cs                  |  44 ++
 .../appsettings.json                            |   4 +
 .../GraphTraversalSourceTests.cs                |  68 ++
 .../Gremlin.CSharp.UnitTest.csproj              |  21 +
 .../Gremlin.CSharp.UnitTest/PredicateTests.cs   |  50 ++
 .../ConfigProvider.cs                           |  47 ++
 .../Driver/ConnectionPoolTests.cs               |  90 +++
 .../Driver/GremlinClientTests.cs                | 212 +++++++
 .../Driver/MessagesTests.cs                     | 147 +++++
 .../Gremlin.Net.IntegrationTest.csproj          |  41 ++
 .../Process/Remote/RemoteStrategyTests.cs       |  85 +++
 .../Properties/AssemblyInfo.cs                  |  44 ++
 .../Util/RequestMessageProvider.cs              |  54 ++
 .../appsettings.json                            |   4 +
 .../Gremlin.Net.Process.UnitTest.csproj         |  22 +
 .../Traversal/BytecodeTests.cs                  |  44 ++
 .../Traversal/Strategy/StrategyTests.cs         | 109 ++++
 .../Traversal/TestTraversal.cs                  |  51 ++
 .../Traversal/TestTraversalStrategy.cs          |  50 ++
 .../Traversal/TraversalTests.cs                 | 177 ++++++
 .../Traversal/TraverserTests.cs                 |  75 +++
 .../Driver/DriverRemoteConnectionTests.cs       |  51 ++
 .../Driver/GremlinServerTests.cs                |  66 ++
 .../Driver/RequestMessageBuilderTests.cs        |  41 ++
 .../Gremlin.Net.UnitTest.csproj                 |  35 ++
 .../Properties/AssemblyInfo.cs                  |  44 ++
 .../Gremlin.Net.UnitTest/Structure/EdgeTests.cs |  57 ++
 .../GraphSON/BytecodeGraphSONSerializerTests.cs | 153 +++++
 .../IO/GraphSON/GraphSONReaderTests.cs          | 308 +++++++++
 .../IO/GraphSON/GraphSONWriterTests.cs          | 329 ++++++++++
 .../IO/GraphSON/StrategyWriterTests.cs          |  66 ++
 .../Structure/IO/GraphSON/TestClass.cs          |  30 +
 .../Structure/IO/GraphSON/TestUtils.cs          |  36 ++
 .../Gremlin.Net.UnitTest/Structure/PathTests.cs | 416 ++++++++++++
 .../Structure/PropertyTests.cs                  | 165 +++++
 .../Structure/VertexPropertyTests.cs            |  69 ++
 .../Structure/VertexTests.cs                    |  80 +++
 gremlin-dotnet/test/pom.xml                     | 179 ++++++
 pom.xml                                         |   9 +
 186 files changed, 13225 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index ca3160b..fe469b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,12 @@ __pycache__/
 __version__.py
 .glv
 settings.xml
+tools/
+[Dd]ebug/
+[Rr]elease/
+[Oo]bj/
+*.suo
+*.user
+.vscode/
+.vs/
+*nupkg

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index f2513e6..31a98a5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,6 +9,11 @@ addons:
   apt:
     packages:
       - oracle-java8-installer
+before_install:
+  - sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
+  - sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
+  - sudo apt-get update
+  - sudo apt-get install dotnet-dev-1.0.1
 script: 
   - "mvn clean install -Dci"
 #notifications:

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/docker/Dockerfile
----------------------------------------------------------------------
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 87e8b07..932536c 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -20,11 +20,13 @@ FROM ubuntu:trusty
 MAINTAINER Daniel Kuppitz <me...@gremlin.guru>
 
 RUN apt-get update \
-    && apt-get -y install software-properties-common python-software-properties \
+    && apt-get -y install software-properties-common python-software-properties apt-transport-https \
     && echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections \
     && add-apt-repository -y ppa:webupd8team/java \
+    && sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list' \
+    && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893 \
     && apt-get update \
-    && apt-get install -y oracle-java8-installer curl gawk git maven openssh-server \
+    && apt-get install -y oracle-java8-installer curl gawk git maven openssh-server dotnet-dev-1.0.1 \
     && rm -rf /var/lib/apt/lists/* /var/cache/oracle-jdk8-installer
 
 RUN sed -i 's@PermitRootLogin without-password@PermitRootLogin yes@' /etc/ssh/sshd_config

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/docs/src/dev/developer/development-environment.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/developer/development-environment.asciidoc b/docs/src/dev/developer/development-environment.asciidoc
index 4a7a3f0..37475e1 100644
--- a/docs/src/dev/developer/development-environment.asciidoc
+++ b/docs/src/dev/developer/development-environment.asciidoc
@@ -82,9 +82,27 @@ test is configured by a "console-integration-tests" Maven profile. This profile
 simply piggy-back on the `.glv` file in `gremlin-python`. Note that unlike `gremlin-python` the tests are actually
 integration tests and therefore must be actively switched on with `-DskipIntegrationTests=false`:
 
-[source,text
+[source,text]
 mvn clean install -pl gremlin-console -DskipIntegrationTests=false
 
+[[dotnet-environment]]
+.NET Environment
+~~~~~~~~~~~~~~~~
+
+The build optionally requires link:https://www.microsoft.com/net/core[.NET Core SDK] (>=1.1.0) to work with the
+gremlin-dotnet module. If .NET Core SDK is not installed, TinkerPop will still build with Maven, but .NET projects
+will be skipped.
+
+`gremlin-dotnet` which also includes Gremlin-Csharp can be build and tested from the command line with:
+
+[source,text]
+mvn clean install -Pgremlin-dotnet
+
+which enables the „gremlin-dotnet“ Maven profile or in a more automated fashion simply add a `.glv` file to the `src`
+and `test` directories of the `gremlin-dotnet` module  which will signify to Maven that the environment is .NET-ready.
+The `.glv` file need not have any contents and is ignored by Git. A standard `mvn clean install` will then build
+`gremlin-dotnet` in full. 
+
 [[release-environment]]
 Release Environment
 ~~~~~~~~~~~~~~~~~~~

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/docs/src/reference/gremlin-variants.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index 39b5558..01df632 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -354,4 +354,200 @@ graphson_writer = GraphSONWriter({MyType: MyType})
 connection = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g',
                                      graphson_reader=graphson_reader,
                                      graphson_writer=graphson_writer)
+----
+
+[[gremlin-csharp]]
+Gremlin-CSharp
+--------------
+Apache TinkerPop's Gremlin-CSharp implements Gremlin within the C# language. It targets .NET Standard and can
+therefore be used on different operating systems and with different .NET frameworks, such as .NET Framework
+and link:https://www.microsoft.com/net/core[.NET Core]. Since the C# syntax is very similar to that of Java, it should be very easy to switch between
+Gremlin-Java and Gremlin-CSharp. The only major syntactical difference is that all method names in Gremlin-CSharp
+use PascalCase as opposed to camelCase in Gremlin-Java in order to comply with .NET conventions.
+
+[source,powershell]
+nuget install Gremlin.CSharp
+
+In Gremlin-CSharp there exists `GraphTraversalSource`, `GraphTraversal`, and `__` which mirror the respective classes
+in Gremlin-Java. The `GraphTraversalSource` requires a driver in order to communicate with <<gremlin-server,GremlinServer>> (or any
+RemoteConnection-enabled server).
+
+Gremlin-CSharp and Gremlin-DotNet
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Gremlin-CSharp is the C# language variant of Gremlin, but it needs a driver to communicate with a remote
+Gremlin Server. Such a driver is provided as part of Apache TinkerPop’s Gremlin-DotNet that also includes other
+useful functionality to work with Gremlin in .NET.
+Gremlin-DotNet is currently distributed in two NuGet packages:
+
+* `Gremlin.Net.Process` contains core functionality for Gremlin language variants and defines interfaces for drivers.
+Gremlin-CSharp depends on this package. So it will be installed automatically when you install Gremlin-CSharp.
+* `Gremlin.Net` contains a driver that allows Gremlin-CSharp to be used with a remote server and GraphSON serializers and deserializers.
+
+IMPORTANT: For developers wishing to provide another driver implementation, be sure to implement `IRemoteConnection` in
+`Gremlin.Net.Process.Remote` so it can then be used by Gremlin-CSharp’s `GraphTraversal`.
+
+When Gremlin Server is running, Gremlin-CSharp can communicate with Gremlin Server by sending traversals serialized as `Bytecode`.
+
+IMPORTANT: Gremlin-CSharp is compatible with GraphSON 2.0 only, so this serializer must be configured in Gremlin Server.
+
+A traversal source can be spawned with `RemoteStrategy` from an empty `Graph`.
+
+[source,csharp]
+----
+var graph = new Graph();
+var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182))));
+----
+
+When a traversal from the `GraphTraversalSource` is iterated, the traversal’s `Bytecode` is sent over the wire via the registered
+`IRemoteConnection`. The bytecode is used to construct the equivalent traversal at the remote traversal source.
+Since Gremlin-CSharp currently doesn't support lambda expressions, all traversals can be translated to Gremlin-Java on the remote
+location (e.g. Gremlin Server).
+
+IMPORTANT: Gremlin-DotNet’s `ITraversal` interface supports the standard Gremlin methods such as `Next()`, `NextTraverser()`, `ToSet()`,
+`ToList()`, etc. Such "terminal" methods trigger the evaluation of the traversal.
+
+RemoteConnection Submission
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Very similar to Gremlin-Python and Gremlin-Java, there are various ways to submit a traversal to a `IRemoteConnection` using
+terminal/action methods off of `ITraversal`.
+
+* `ITraversal.Next()`
+* `ITraversal.NextTraverser()`
+* `ITraversal.ToList()`
+* `ITraversal.ToSet()`
+* `ITraversal.Iterate()`
+
+Static Enums and Methods
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Gremlin has various tokens (e.g. `T`, `P`, `Order`, `Operator`, etc.) that are represented in Gremlin-CSharp as Enums.
+
+These can be used analogously to how they are used in Gremlin-Java.
+
+[source,csharp]
+g.V().HasLabel("person").Has("age",P.Gt(30)).Order().By("age",Order.decr).ToList()
+
+Moreover, the class prefixes can be ommitted with a `using static`.
+
+[source,csharp]
+----
+using static Gremlin.CSharp.Process.P;
+using static Gremlin.CSharp.Process.Order;
+----
+
+Then it is possible to represent the above traversal as below.
+
+[source,csharp]
+g.V().HasLabel("person").Has("age",Gt(30)).Order().By("age",decr).ToList()
+
+Finally, with using static `__`, anonymous traversals like `__.Out()` can be expressed as below. That is, without the `__.`-prefix.
+
+[source,csharp]
+g.V().Repeat(Out()).Times(2).Values("name").Fold().ToList()
+
+Bindings
+~~~~~~~~
+
+When a traversal bytecode is sent over a `IRemoteConnection` (e.g. Gremlin Server), it will be translated, compiled, 
+and then executed. If the same traversal is sent again, translation and compilation can be skipped as the previously 
+compiled version should be cached. Many traversals are unique up to some parameterization. For instance,
+`g.V(1).Out("created").Values("name")` is considered different from `g.V(4).Out('created').Values("Name")`
+as they have different script "string" representations. However, `g.V(x).Out("created").Values("name")` with bindings of 
+`{x : 1}` and `{x : 4}` are considered the same. If a traversal is going to be executed repeatedly, but with different 
+parameters, then bindings should be used. In Gremlin-CSharp, bindings are objects that can be created as follows.
+
+[source,csharp]
+----
+var b = new Bindings();
+g.V(b.Of("id", 1)).Out("created").Values("name").toList()
+g.V(b.Of("id", 4)).Out("created").Values("name").toList()
+----
+
+Traversal Strategies
+~~~~~~~~~~~~~~~~~~~~
+
+In order to add and remove traversal strategies from a traversal source, Gremlin-DotNet has an `AbstractTraversalStrategy`
+class along with a collection of subclasses that mirror the standard Gremlin-Java strategies.
+
+[source,csharp]
+----
+g = g.WithStrategies(new SubgraphStrategy(vertexCriterion: HasLabel("person"),
+    edgeCriterion: Has("weight", Gt(0.5))));
+var names = g.V().Values("name").ToList();  // names: [marko, vadas, josh, peter]
+
+g = g.WithoutStrategies(new SubgraphStrategy());
+names = g.V().Values("name").ToList(); // names: [marko, vadas, lop, josh, ripple, peter]
+
+var edgeValueMaps = g.V().OutE().ValueMap(true).ToList();
+// edgeValueMaps: [[label:created, id:9, weight:0.4], [label:knows, id:7, weight:0.5], [label:knows, id:8, weight:1.0], 
+//     [label:created, id:10, weight:1.0], [label:created, id:11, weight:0.4], [label:created, id:12, weight:0.2]]
+
+g = g.WithComputer(workers: 2, vertices: Has("name", "marko"));
+names = g.V().Values("name").ToList();  // names: [marko]
+
+edgeValueMaps = g.V().OutE().ValueMap(true).ToList();
+// edgeValueMaps: [[label:created, id:9, weight:0.4], [label:knows, id:7, weight:0.5], [label:knows, id:8, weight:1.0]]
+----
+
+NOTE: Many of the TraversalStrategy classes in Gremlin-DotNet are proxies to the respective strategy on Apache TinkerPop’s
+JVM-based Gremlin traversal machine. As such, their `Apply(ITraversal)` method does nothing. However, the strategy is
+encoded in the Gremlin-DotNet bytecode and transmitted to the Gremlin traversal machine for re-construction machine-side.
+
+Custom Serialization
+~~~~~~~~~~~~~~~~~~~~
+
+Gremlin-DotNet provides a GraphSON 2.0 serialization package with the standard Apache TinkerPop `g`-types registered
+(see link:http://tinkerpop.apache.org/docs/x.y.z/dev/io/#graphson-2d0[GraphSON 2.0]). It is possible for users to add new
+types by creating serializers and deserializers in C# (or any other .NET language) and registering them with the `GremlinClient`.
+
+[source,csharp]
+----
+internal class MyType
+{
+    public static string GraphsonPrefix = "providerx";
+    public static string GraphsonBaseType = "MyType";
+    public static string GraphsonType = GraphSONUtil.FormatTypeName(GraphsonPrefix, GraphsonBaseType);
+
+    public MyType(int x, int y)
+    {
+        X = x;
+        Y = y;
+    }
+
+    public int X { get; }
+    public int Y { get; }
+}
+
+internal class MyClassWriter : IGraphSONSerializer
+{
+    public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+    {
+        MyType myType = objectData;
+        var valueDict = new Dictionary<string, object>
+        {
+            {"x", myType.X},
+            {"y", myType.Y}
+        };
+        return GraphSONUtil.ToTypedValue(nameof(TestClass), valueDict, MyType.GraphsonPrefix);
+    }
+}
+
+internal class MyTypeReader : IGraphSONDeserializer
+{
+    public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+    {
+        var x = reader.ToObject(graphsonObject["x"]);
+        var y = reader.ToObject(graphsonObject["y"]);
+        return new MyType(x, y);
+    }
+}
+
+var graphsonReader = new GraphSONReader(
+    new Dictionary<string, IGraphSONDeserializer> {{MyType.GraphsonType, new MyTypeReader()}});
+var graphsonWriter = new GraphSONWriter(
+    new Dictionary<Type, IGraphSONSerializer> {{typeof(MyType), new MyClassWriter()}});
+
+var gremlinClient = new GremlinClient(new GremlinServer("localhost", 8182), graphsonReader, graphsonWriter);
 ----
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/pom.xml b/gremlin-csharp-generator/pom.xml
new file mode 100644
index 0000000..f488f02
--- /dev/null
+++ b/gremlin-csharp-generator/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.tinkerpop</groupId>
+        <artifactId>tinkerpop</artifactId>
+        <version>3.2.5-SNAPSHOT</version>
+    </parent>
+    <artifactId>gremlin-csharp-generator</artifactId>
+    <name>Apache TinkerPop :: Gremlin-CSharp Generator</name>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>gremlin-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy</artifactId>
+            <version>${groovy.version}</version>
+            <classifier>indy</classifier>
+        </dependency>
+    </dependencies>
+    <build>
+        <directory>${basedir}/target</directory>
+        <finalName>${project.artifactId}-${project.version}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                    <execution>
+                        <id>generate-csharp</id>
+                        <phase>generate-test-resources</phase>
+                        <goals>
+                            <goal>java</goal>
+                        </goals>
+                        <configuration>
+                            <mainClass>org.apache.tinkerpop.gremlin.csharp.GenerateGremlinCSharp</mainClass>
+                            <arguments>
+                                <argument>${project.parent.basedir}/gremlin-dotnet/src/Gremlin.CSharp</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.gmavenplus</groupId>
+                <artifactId>gmavenplus-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/AnonymousTraversalGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/AnonymousTraversalGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/AnonymousTraversalGenerator.groovy
new file mode 100644
index 0000000..6e2e191
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/AnonymousTraversalGenerator.groovy
@@ -0,0 +1,71 @@
+/*
+ *  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.csharp
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__
+
+import java.lang.reflect.Modifier
+
+class AnonymousTraversalGenerator {
+
+    public static void create(final String anonymousTraversalFile) {
+
+        final StringBuilder csharpClass = new StringBuilder()
+
+        csharpClass.append(CommonContentHelper.getLicense())
+
+        csharpClass.append(
+"""
+namespace Gremlin.CSharp.Process
+{
+    public static class __
+    {
+        public static GraphTraversal Start()
+        {
+            return new GraphTraversal();
+        }
+""")
+        __.getMethods().
+                findAll { GraphTraversal.class.equals(it.returnType) }.
+                findAll { Modifier.isStatic(it.getModifiers()) }.
+                collect { it.name }.
+                findAll { !it.equals("__") && !it.equals("start") }.
+                unique().
+                sort { a, b -> a <=> b }.
+                forEach { javaMethodName ->
+                    String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+
+                    csharpClass.append(
+"""
+        public static GraphTraversal ${sharpMethodName}(params object[] args)
+        {
+            return new GraphTraversal().${sharpMethodName}(args);
+        }
+""")
+                }
+        csharpClass.append("\t}\n")
+        csharpClass.append("}")
+
+        final File file = new File(anonymousTraversalFile);
+        file.delete()
+        csharpClass.eachLine { file.append(it + "\n") }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/CommonContentHelper.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/CommonContentHelper.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/CommonContentHelper.groovy
new file mode 100644
index 0000000..c44bcfa
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/CommonContentHelper.groovy
@@ -0,0 +1,49 @@
+/*
+ *  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.csharp
+
+public final class CommonContentHelper {
+
+    public static String getLicense() {
+        return """#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+"""
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/EnumGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/EnumGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/EnumGenerator.groovy
new file mode 100644
index 0000000..a389f9b
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/EnumGenerator.groovy
@@ -0,0 +1,62 @@
+/*
+ *  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.csharp
+
+import org.apache.tinkerpop.gremlin.util.CoreImports
+
+class EnumGenerator {
+
+    public static void create(final String enumDirectory) {
+
+        for (final Class<? extends Enum> enumClass : CoreImports.getClassImports()
+                .findAll { Enum.class.isAssignableFrom(it) }
+                .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }
+                .collect()) {
+            createEnum(enumDirectory, enumClass)
+        }
+    }
+
+    private static void createEnum(final String enumDirectory, final Class<? extends Enum> enumClass){
+        final StringBuilder csharpEnum = new StringBuilder()
+
+        csharpEnum.append(CommonContentHelper.getLicense())
+
+        csharpEnum.append(
+                """
+namespace Gremlin.CSharp.Process
+{
+    public enum ${enumClass.getSimpleName()}
+    {
+""")
+        enumClass.getEnumConstants()
+                .sort { a, b -> a.name() <=> b.name() }
+                .each { value -> csharpEnum.append("        ${value.name()},\n"); }
+        csharpEnum.deleteCharAt(csharpEnum.length() - 2)
+
+        csharpEnum.append("    }\n")
+        csharpEnum.append("}")
+
+        final String enumFileName = "${enumDirectory}/${enumClass.getSimpleName()}.cs"
+        final File file = new File(enumFileName);
+        file.delete()
+        csharpEnum.eachLine { file.append(it + "\n") }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GenerateGremlinCSharp.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GenerateGremlinCSharp.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GenerateGremlinCSharp.groovy
new file mode 100644
index 0000000..7b03e5a
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GenerateGremlinCSharp.groovy
@@ -0,0 +1,32 @@
+/*
+ *  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.csharp
+
+public class GenerateGremlinCSharp {
+
+    public static void main(String[] args) {
+        final String csharpDirectory = args[0]
+        GraphTraversalSourceGenerator.create(csharpDirectory + "/Process/" + "GraphTraversalSource.cs")
+        GraphTraversalGenerator.create(csharpDirectory + "/Process/" + "GraphTraversal.cs")
+        AnonymousTraversalGenerator.create(csharpDirectory + "/Process/" + "__.cs")
+        EnumGenerator.create(csharpDirectory + "/Process/")
+        PredicateGenerator.create(csharpDirectory + "/Process/" + "P.cs")
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalGenerator.groovy
new file mode 100644
index 0000000..54183a3
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalGenerator.groovy
@@ -0,0 +1,77 @@
+/*
+ *  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.csharp
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
+
+class GraphTraversalGenerator {
+
+    public static void create(final String graphTraversalFile) {
+
+        final StringBuilder csharpClass = new StringBuilder()
+
+        csharpClass.append(CommonContentHelper.getLicense())
+
+        csharpClass.append(
+"""
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.CSharp.Process
+{
+    public class GraphTraversal : DefaultTraversal
+    {
+        public GraphTraversal()
+            : this(new List<ITraversalStrategy>(), new Bytecode())
+        {
+        }
+
+        public GraphTraversal(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode)
+        {
+            TraversalStrategies = traversalStrategies;
+            Bytecode = bytecode;
+        }
+""")
+        GraphTraversal.getMethods().
+                findAll { GraphTraversal.class.equals(it.returnType) }.
+                findAll { !it.name.equals("clone") && !it.name.equals("iterate") }.
+                collect { it.name }.
+                unique().
+                sort { a, b -> a <=> b }.
+                forEach { javaMethodName ->
+                    String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+
+                    csharpClass.append(
+                            """
+        public GraphTraversal ${sharpMethodName}(params object[] args)
+        {
+            Bytecode.AddStep("${javaMethodName}", args);
+            return this;
+        }
+""")
+                }
+        csharpClass.append("\t}\n")
+        csharpClass.append("}")
+
+        final File file = new File(graphTraversalFile);
+        file.delete()
+        csharpClass.eachLine { file.append(it + "\n") }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalSourceGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalSourceGenerator.groovy
new file mode 100644
index 0000000..aaa35fb
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/GraphTraversalSourceGenerator.groovy
@@ -0,0 +1,140 @@
+/*
+ *  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.csharp
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource
+
+
+class GraphTraversalSourceGenerator {
+
+    public static void create(final String graphTraversalSourceFile) {
+
+        final StringBuilder csharpClass = new StringBuilder()
+
+        csharpClass.append(CommonContentHelper.getLicense())
+
+        csharpClass.append(
+"""
+using System.Collections.Generic;
+using Gremlin.Net.Process.Remote;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Process.Traversal.Strategy.Decoration;
+
+namespace Gremlin.CSharp.Process
+{
+    public class GraphTraversalSource
+    {
+        public ICollection<ITraversalStrategy> TraversalStrategies { get; set; }
+        public Bytecode Bytecode { get; set; }
+
+         public GraphTraversalSource()
+            : this(new List<ITraversalStrategy>(), new Bytecode())
+        {
+        }
+
+        public GraphTraversalSource(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode)
+        {
+            TraversalStrategies = traversalStrategies;
+            Bytecode = bytecode;
+        }
+"""
+        )
+
+        // Hold the list of methods with their overloads, so we do not create duplicates
+        HashMap<String, ArrayList<String>> sharpMethods = new HashMap<String, ArrayList<String>>()
+
+        GraphTraversalSource.getMethods(). // SOURCE STEPS
+                findAll { GraphTraversalSource.class.equals(it.returnType) }.
+                findAll {
+                    !it.name.equals("clone") &&
+                            // replace by TraversalSource.Symbols.XXX
+                            !it.name.equals("withBindings") &&
+                            !it.name.equals("withRemote") &&
+                            !it.name.equals("withComputer")
+                }.
+                collect { it.name }.
+                unique().
+                sort { a, b -> a <=> b }.
+                forEach { javaMethodName ->
+                    String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+
+                    csharpClass.append(
+"""
+        public GraphTraversalSource ${sharpMethodName}(params object[] args)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.Bytecode.AddSource("${javaMethodName}\", args);
+            return source;
+        }
+""")
+                }
+
+        csharpClass.append(
+                """
+        public GraphTraversalSource WithBindings(object bindings)
+        {
+            return this;
+        }
+
+        public GraphTraversalSource WithRemote(IRemoteConnection remoteConnection)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                new Bytecode(Bytecode));
+            source.TraversalStrategies.Add(new RemoteStrategy(remoteConnection));
+            return source;
+        }
+        
+        public GraphTraversalSource WithComputer(string graphComputer = null, int? workers = null, string persist = null,
+            string result = null, ITraversal vertices = null, ITraversal edges = null,
+            Dictionary<string, dynamic> configuration = null)
+        {
+            return WithStrategies(new VertexProgramStrategy(graphComputer, workers, persist, result, vertices, edges, configuration));
+        }
+""")
+
+        GraphTraversalSource.getMethods(). // SPAWN STEPS
+                findAll { GraphTraversal.class.equals(it.returnType) }.
+                collect { it.name }.
+                unique().
+                sort { a, b -> a <=> b }.
+                forEach { javaMethodName ->
+                    String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+
+                    csharpClass.append(
+                            """
+        public GraphTraversal ${sharpMethodName}(params object[] args)
+        {
+            var traversal = new GraphTraversal(TraversalStrategies, new Bytecode(Bytecode));
+            traversal.Bytecode.AddStep("${javaMethodName}\", args);
+            return traversal;
+        }
+""")
+                }
+
+        csharpClass.append("\t}\n")
+        csharpClass.append("}")
+
+        final File file = new File(graphTraversalSourceFile);
+        file.delete()
+        csharpClass.eachLine { file.append(it + "\n") }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/PredicateGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/PredicateGenerator.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/PredicateGenerator.groovy
new file mode 100644
index 0000000..72e3dba
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/PredicateGenerator.groovy
@@ -0,0 +1,66 @@
+/*
+ *  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.csharp
+
+import org.apache.tinkerpop.gremlin.process.traversal.P
+
+import java.lang.reflect.Modifier
+
+class PredicateGenerator {
+
+    public static void create(final String predicateFile) {
+
+        final StringBuilder csharpClass = new StringBuilder()
+
+        csharpClass.append(CommonContentHelper.getLicense())
+
+        csharpClass.append(
+"""
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.CSharp.Process
+{
+    public class P
+    {""")
+        P.class.getMethods().
+                findAll { Modifier.isStatic(it.getModifiers()) }.
+                findAll { P.class.isAssignableFrom(it.returnType) }.
+                collect { it.name }.
+                unique().
+                sort { a, b -> a <=> b }.
+                each { javaMethodName ->
+                    String sharpMethodName = SymbolHelper.toCSharp(javaMethodName)
+                    csharpClass.append(
+"""
+        public static TraversalPredicate ${sharpMethodName}(params object[] args)
+        {
+            var value = args.Length == 1 ? args[0] : args;
+            return new TraversalPredicate("${javaMethodName}", value);
+        }
+""")
+                }
+        csharpClass.append("\t}\n")
+        csharpClass.append("}")
+
+        final File file = new File(predicateFile)
+        file.delete()
+        csharpClass.eachLine { file.append(it + "\n") }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/SymbolHelper.groovy
----------------------------------------------------------------------
diff --git a/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/SymbolHelper.groovy b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/SymbolHelper.groovy
new file mode 100644
index 0000000..10591d7
--- /dev/null
+++ b/gremlin-csharp-generator/src/main/groovy/org/apache/tinkerpop/gremlin/csharp/SymbolHelper.groovy
@@ -0,0 +1,31 @@
+/*
+ *  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.csharp
+
+public final class SymbolHelper {
+
+    public static String toCSharp(final String symbol) {
+        return (String) Character.toUpperCase(symbol.charAt(0)) + symbol.substring(1)
+    }
+
+    public static String toJava(final String symbol) {
+        return (String) Character.toLowerCase(symbol.charAt(0)) + symbol.substring(1)
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/Gremlin.Net.sln
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/Gremlin.Net.sln b/gremlin-dotnet/Gremlin.Net.sln
new file mode 100644
index 0000000..bfd565f
--- /dev/null
+++ b/gremlin-dotnet/Gremlin.Net.sln
@@ -0,0 +1,80 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.4
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{584F838B-DAE2-44F5-868C-1F532949C827}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D4B935A4-93F9-4A58-BC34-E5BFE1D2E2F7}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.Net", "src\Gremlin.Net\Gremlin.Net.csproj", "{6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.Net.UnitTest", "test\Gremlin.Net.UnitTest\Gremlin.Net.UnitTest.csproj", "{1FAB781B-B857-4AD2-BEC8-E20C214D9E21}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.Net.IntegrationTest", "test\Gremlin.Net.IntegrationTest\Gremlin.Net.IntegrationTest.csproj", "{CC54ABE3-13D2-491C-81E2-4D0355ABFA93}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.CSharp", "src\Gremlin.CSharp\Gremlin.CSharp.csproj", "{709D235A-CA13-434F-9AF9-8C8C009B11D7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gremlin.CSharp.IntegrationTest", "test\Gremlin.CSharp.IntegrationTest\Gremlin.CSharp.IntegrationTest.csproj", "{232F0F2B-178E-4214-99C7-CC4DC6710F44}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gremlin.Net.Process", "src\Gremlin.Net.Process\Gremlin.Net.Process.csproj", "{4949181B-C97D-4BB4-A312-9C1506EC7DA7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gremlin.Net.Process.UnitTest", "test\Gremlin.Net.Process.UnitTest\Gremlin.Net.Process.UnitTest.csproj", "{D97CA283-AC86-4EC9-9E1D-5F9A97977687}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gremlin.CSharp.UnitTest", "test\Gremlin.CSharp.UnitTest\Gremlin.CSharp.UnitTest.csproj", "{F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1FAB781B-B857-4AD2-BEC8-E20C214D9E21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1FAB781B-B857-4AD2-BEC8-E20C214D9E21}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1FAB781B-B857-4AD2-BEC8-E20C214D9E21}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1FAB781B-B857-4AD2-BEC8-E20C214D9E21}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CC54ABE3-13D2-491C-81E2-4D0355ABFA93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CC54ABE3-13D2-491C-81E2-4D0355ABFA93}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CC54ABE3-13D2-491C-81E2-4D0355ABFA93}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CC54ABE3-13D2-491C-81E2-4D0355ABFA93}.Release|Any CPU.Build.0 = Release|Any CPU
+		{709D235A-CA13-434F-9AF9-8C8C009B11D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{709D235A-CA13-434F-9AF9-8C8C009B11D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{709D235A-CA13-434F-9AF9-8C8C009B11D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{709D235A-CA13-434F-9AF9-8C8C009B11D7}.Release|Any CPU.Build.0 = Release|Any CPU
+		{232F0F2B-178E-4214-99C7-CC4DC6710F44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{232F0F2B-178E-4214-99C7-CC4DC6710F44}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{232F0F2B-178E-4214-99C7-CC4DC6710F44}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{232F0F2B-178E-4214-99C7-CC4DC6710F44}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4949181B-C97D-4BB4-A312-9C1506EC7DA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4949181B-C97D-4BB4-A312-9C1506EC7DA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4949181B-C97D-4BB4-A312-9C1506EC7DA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4949181B-C97D-4BB4-A312-9C1506EC7DA7}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D97CA283-AC86-4EC9-9E1D-5F9A97977687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D97CA283-AC86-4EC9-9E1D-5F9A97977687}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D97CA283-AC86-4EC9-9E1D-5F9A97977687}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D97CA283-AC86-4EC9-9E1D-5F9A97977687}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{6C1DD34D-E30F-4E37-AACC-BEB8AD2320D8} = {584F838B-DAE2-44F5-868C-1F532949C827}
+		{1FAB781B-B857-4AD2-BEC8-E20C214D9E21} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+		{CC54ABE3-13D2-491C-81E2-4D0355ABFA93} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+		{709D235A-CA13-434F-9AF9-8C8C009B11D7} = {584F838B-DAE2-44F5-868C-1F532949C827}
+		{232F0F2B-178E-4214-99C7-CC4DC6710F44} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+		{4949181B-C97D-4BB4-A312-9C1506EC7DA7} = {584F838B-DAE2-44F5-868C-1F532949C827}
+		{D97CA283-AC86-4EC9-9E1D-5F9A97977687} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+		{F2D976C2-D5EC-4BE5-9F6F-FCFAA9F59858} = {1B54FAC2-5411-4BB6-B450-FE2FFD8C4782}
+	EndGlobalSection
+EndGlobal

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/pom.xml b/gremlin-dotnet/pom.xml
new file mode 100644
index 0000000..0472324
--- /dev/null
+++ b/gremlin-dotnet/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.tinkerpop</groupId>
+        <artifactId>tinkerpop</artifactId>
+        <version>3.2.5-SNAPSHOT</version>
+    </parent>
+    <groupId>org.apache.tinkerpop</groupId>
+    <artifactId>gremlin-dotnet</artifactId>
+    <name>Apache TinkerPop :: Gremlin-DotNet</name>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>test</module>
+        <module>src</module>
+    </modules>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.eobjects.build</groupId>
+                <artifactId>dotnet-maven-plugin</artifactId>
+                <extensions>true</extensions>
+                <version>0.14</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.gmavenplus</groupId>
+                <artifactId>gmavenplus-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Gremlin.CSharp.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Gremlin.CSharp.csproj b/gremlin-dotnet/src/Gremlin.CSharp/Gremlin.CSharp.csproj
new file mode 100644
index 0000000..82291fc
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Gremlin.CSharp.csproj
@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <Version>3.2.5-SNAPSHOT</Version>
+    <TargetFramework>netstandard1.3</TargetFramework>
+    <AssemblyName>Gremlin.CSharp</AssemblyName>
+    <PackageId>Gremlin.CSharp</PackageId>
+    <GeneratePackageOnBuild>False</GeneratePackageOnBuild>
+    <PackageProjectUrl>http://tinkerpop.apache.org</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/apache/tinkerpop/blob/master/LICENSE</PackageLicenseUrl>
+    <RepositoryUrl>https://github.com/apache/tinkerpop</RepositoryUrl>
+    <Description>Apache TinkerPop’s Gremlin-CSharp implements Gremlin within C# and can be used on any platform.</Description>
+    <PackageTags>gremlin-csharp;gremlin;tinkerpop</PackageTags>
+    <Authors>Apache TinkerPop</Authors>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Gremlin.Net.Process\Gremlin.Net.Process.csproj" />
+  </ItemGroup>
+
+</Project>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Barrier.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Barrier.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Barrier.cs
new file mode 100644
index 0000000..a74b47a
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Barrier.cs
@@ -0,0 +1,30 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Barrier
+    {
+        normSack
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Cardinality.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Cardinality.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Cardinality.cs
new file mode 100644
index 0000000..4b9fae8
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Cardinality.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Cardinality
+    {
+        list,
+        set,
+        single
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Column.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Column.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Column.cs
new file mode 100644
index 0000000..c397b69
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Column.cs
@@ -0,0 +1,31 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Column
+    {
+        keys,
+        values
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/Direction.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/Direction.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/Direction.cs
new file mode 100644
index 0000000..abdf7a2
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/Direction.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+namespace Gremlin.CSharp.Process
+{
+    public enum Direction
+    {
+        BOTH,
+        IN,
+        OUT
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/72553d68/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversal.cs
new file mode 100644
index 0000000..4397838
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.CSharp/Process/GraphTraversal.cs
@@ -0,0 +1,630 @@
+#region License
+
+/*
+ * 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.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.CSharp.Process
+{
+    public class GraphTraversal : DefaultTraversal
+    {
+        public GraphTraversal()
+            : this(new List<ITraversalStrategy>(), new Bytecode())
+        {
+        }
+
+        public GraphTraversal(ICollection<ITraversalStrategy> traversalStrategies, Bytecode bytecode)
+        {
+            TraversalStrategies = traversalStrategies;
+            Bytecode = bytecode;
+        }
+
+        public GraphTraversal V(params object[] args)
+        {
+            Bytecode.AddStep("V", args);
+            return this;
+        }
+
+        public GraphTraversal AddE(params object[] args)
+        {
+            Bytecode.AddStep("addE", args);
+            return this;
+        }
+
+        public GraphTraversal AddInE(params object[] args)
+        {
+            Bytecode.AddStep("addInE", args);
+            return this;
+        }
+
+        public GraphTraversal AddOutE(params object[] args)
+        {
+            Bytecode.AddStep("addOutE", args);
+            return this;
+        }
+
+        public GraphTraversal AddV(params object[] args)
+        {
+            Bytecode.AddStep("addV", args);
+            return this;
+        }
+
+        public GraphTraversal Aggregate(params object[] args)
+        {
+            Bytecode.AddStep("aggregate", args);
+            return this;
+        }
+
+        public GraphTraversal And(params object[] args)
+        {
+            Bytecode.AddStep("and", args);
+            return this;
+        }
+
+        public GraphTraversal As(params object[] args)
+        {
+            Bytecode.AddStep("as", args);
+            return this;
+        }
+
+        public GraphTraversal Barrier(params object[] args)
+        {
+            Bytecode.AddStep("barrier", args);
+            return this;
+        }
+
+        public GraphTraversal Both(params object[] args)
+        {
+            Bytecode.AddStep("both", args);
+            return this;
+        }
+
+        public GraphTraversal BothE(params object[] args)
+        {
+            Bytecode.AddStep("bothE", args);
+            return this;
+        }
+
+        public GraphTraversal BothV(params object[] args)
+        {
+            Bytecode.AddStep("bothV", args);
+            return this;
+        }
+
+        public GraphTraversal Branch(params object[] args)
+        {
+            Bytecode.AddStep("branch", args);
+            return this;
+        }
+
+        public GraphTraversal By(params object[] args)
+        {
+            Bytecode.AddStep("by", args);
+            return this;
+        }
+
+        public GraphTraversal Cap(params object[] args)
+        {
+            Bytecode.AddStep("cap", args);
+            return this;
+        }
+
+        public GraphTraversal Choose(params object[] args)
+        {
+            Bytecode.AddStep("choose", args);
+            return this;
+        }
+
+        public GraphTraversal Coalesce(params object[] args)
+        {
+            Bytecode.AddStep("coalesce", args);
+            return this;
+        }
+
+        public GraphTraversal Coin(params object[] args)
+        {
+            Bytecode.AddStep("coin", args);
+            return this;
+        }
+
+        public GraphTraversal Constant(params object[] args)
+        {
+            Bytecode.AddStep("constant", args);
+            return this;
+        }
+
+        public GraphTraversal Count(params object[] args)
+        {
+            Bytecode.AddStep("count", args);
+            return this;
+        }
+
+        public GraphTraversal CyclicPath(params object[] args)
+        {
+            Bytecode.AddStep("cyclicPath", args);
+            return this;
+        }
+
+        public GraphTraversal Dedup(params object[] args)
+        {
+            Bytecode.AddStep("dedup", args);
+            return this;
+        }
+
+        public GraphTraversal Drop(params object[] args)
+        {
+            Bytecode.AddStep("drop", args);
+            return this;
+        }
+
+        public GraphTraversal Emit(params object[] args)
+        {
+            Bytecode.AddStep("emit", args);
+            return this;
+        }
+
+        public GraphTraversal Filter(params object[] args)
+        {
+            Bytecode.AddStep("filter", args);
+            return this;
+        }
+
+        public GraphTraversal FlatMap(params object[] args)
+        {
+            Bytecode.AddStep("flatMap", args);
+            return this;
+        }
+
+        public GraphTraversal Fold(params object[] args)
+        {
+            Bytecode.AddStep("fold", args);
+            return this;
+        }
+
+        public GraphTraversal From(params object[] args)
+        {
+            Bytecode.AddStep("from", args);
+            return this;
+        }
+
+        public GraphTraversal Group(params object[] args)
+        {
+            Bytecode.AddStep("group", args);
+            return this;
+        }
+
+        public GraphTraversal GroupCount(params object[] args)
+        {
+            Bytecode.AddStep("groupCount", args);
+            return this;
+        }
+
+        public GraphTraversal GroupV3d0(params object[] args)
+        {
+            Bytecode.AddStep("groupV3d0", args);
+            return this;
+        }
+
+        public GraphTraversal Has(params object[] args)
+        {
+            Bytecode.AddStep("has", args);
+            return this;
+        }
+
+        public GraphTraversal HasId(params object[] args)
+        {
+            Bytecode.AddStep("hasId", args);
+            return this;
+        }
+
+        public GraphTraversal HasKey(params object[] args)
+        {
+            Bytecode.AddStep("hasKey", args);
+            return this;
+        }
+
+        public GraphTraversal HasLabel(params object[] args)
+        {
+            Bytecode.AddStep("hasLabel", args);
+            return this;
+        }
+
+        public GraphTraversal HasNot(params object[] args)
+        {
+            Bytecode.AddStep("hasNot", args);
+            return this;
+        }
+
+        public GraphTraversal HasValue(params object[] args)
+        {
+            Bytecode.AddStep("hasValue", args);
+            return this;
+        }
+
+        public GraphTraversal Id(params object[] args)
+        {
+            Bytecode.AddStep("id", args);
+            return this;
+        }
+
+        public GraphTraversal Identity(params object[] args)
+        {
+            Bytecode.AddStep("identity", args);
+            return this;
+        }
+
+        public GraphTraversal In(params object[] args)
+        {
+            Bytecode.AddStep("in", args);
+            return this;
+        }
+
+        public GraphTraversal InE(params object[] args)
+        {
+            Bytecode.AddStep("inE", args);
+            return this;
+        }
+
+        public GraphTraversal InV(params object[] args)
+        {
+            Bytecode.AddStep("inV", args);
+            return this;
+        }
+
+        public GraphTraversal Inject(params object[] args)
+        {
+            Bytecode.AddStep("inject", args);
+            return this;
+        }
+
+        public GraphTraversal Is(params object[] args)
+        {
+            Bytecode.AddStep("is", args);
+            return this;
+        }
+
+        public GraphTraversal Key(params object[] args)
+        {
+            Bytecode.AddStep("key", args);
+            return this;
+        }
+
+        public GraphTraversal Label(params object[] args)
+        {
+            Bytecode.AddStep("label", args);
+            return this;
+        }
+
+        public GraphTraversal Limit(params object[] args)
+        {
+            Bytecode.AddStep("limit", args);
+            return this;
+        }
+
+        public GraphTraversal Local(params object[] args)
+        {
+            Bytecode.AddStep("local", args);
+            return this;
+        }
+
+        public GraphTraversal Loops(params object[] args)
+        {
+            Bytecode.AddStep("loops", args);
+            return this;
+        }
+
+        public GraphTraversal Map(params object[] args)
+        {
+            Bytecode.AddStep("map", args);
+            return this;
+        }
+
+        public GraphTraversal MapKeys(params object[] args)
+        {
+            Bytecode.AddStep("mapKeys", args);
+            return this;
+        }
+
+        public GraphTraversal MapValues(params object[] args)
+        {
+            Bytecode.AddStep("mapValues", args);
+            return this;
+        }
+
+        public GraphTraversal Match(params object[] args)
+        {
+            Bytecode.AddStep("match", args);
+            return this;
+        }
+
+        public GraphTraversal Max(params object[] args)
+        {
+            Bytecode.AddStep("max", args);
+            return this;
+        }
+
+        public GraphTraversal Mean(params object[] args)
+        {
+            Bytecode.AddStep("mean", args);
+            return this;
+        }
+
+        public GraphTraversal Min(params object[] args)
+        {
+            Bytecode.AddStep("min", args);
+            return this;
+        }
+
+        public GraphTraversal Not(params object[] args)
+        {
+            Bytecode.AddStep("not", args);
+            return this;
+        }
+
+        public GraphTraversal Option(params object[] args)
+        {
+            Bytecode.AddStep("option", args);
+            return this;
+        }
+
+        public GraphTraversal Optional(params object[] args)
+        {
+            Bytecode.AddStep("optional", args);
+            return this;
+        }
+
+        public GraphTraversal Or(params object[] args)
+        {
+            Bytecode.AddStep("or", args);
+            return this;
+        }
+
+        public GraphTraversal Order(params object[] args)
+        {
+            Bytecode.AddStep("order", args);
+            return this;
+        }
+
+        public GraphTraversal OtherV(params object[] args)
+        {
+            Bytecode.AddStep("otherV", args);
+            return this;
+        }
+
+        public GraphTraversal Out(params object[] args)
+        {
+            Bytecode.AddStep("out", args);
+            return this;
+        }
+
+        public GraphTraversal OutE(params object[] args)
+        {
+            Bytecode.AddStep("outE", args);
+            return this;
+        }
+
+        public GraphTraversal OutV(params object[] args)
+        {
+            Bytecode.AddStep("outV", args);
+            return this;
+        }
+
+        public GraphTraversal PageRank(params object[] args)
+        {
+            Bytecode.AddStep("pageRank", args);
+            return this;
+        }
+
+        public GraphTraversal Path(params object[] args)
+        {
+            Bytecode.AddStep("path", args);
+            return this;
+        }
+
+        public GraphTraversal PeerPressure(params object[] args)
+        {
+            Bytecode.AddStep("peerPressure", args);
+            return this;
+        }
+
+        public GraphTraversal Profile(params object[] args)
+        {
+            Bytecode.AddStep("profile", args);
+            return this;
+        }
+
+        public GraphTraversal Program(params object[] args)
+        {
+            Bytecode.AddStep("program", args);
+            return this;
+        }
+
+        public GraphTraversal Project(params object[] args)
+        {
+            Bytecode.AddStep("project", args);
+            return this;
+        }
+
+        public GraphTraversal Properties(params object[] args)
+        {
+            Bytecode.AddStep("properties", args);
+            return this;
+        }
+
+        public GraphTraversal Property(params object[] args)
+        {
+            Bytecode.AddStep("property", args);
+            return this;
+        }
+
+        public GraphTraversal PropertyMap(params object[] args)
+        {
+            Bytecode.AddStep("propertyMap", args);
+            return this;
+        }
+
+        public GraphTraversal Range(params object[] args)
+        {
+            Bytecode.AddStep("range", args);
+            return this;
+        }
+
+        public GraphTraversal Repeat(params object[] args)
+        {
+            Bytecode.AddStep("repeat", args);
+            return this;
+        }
+
+        public GraphTraversal Sack(params object[] args)
+        {
+            Bytecode.AddStep("sack", args);
+            return this;
+        }
+
+        public GraphTraversal Sample(params object[] args)
+        {
+            Bytecode.AddStep("sample", args);
+            return this;
+        }
+
+        public GraphTraversal Select(params object[] args)
+        {
+            Bytecode.AddStep("select", args);
+            return this;
+        }
+
+        public GraphTraversal SideEffect(params object[] args)
+        {
+            Bytecode.AddStep("sideEffect", args);
+            return this;
+        }
+
+        public GraphTraversal SimplePath(params object[] args)
+        {
+            Bytecode.AddStep("simplePath", args);
+            return this;
+        }
+
+        public GraphTraversal Store(params object[] args)
+        {
+            Bytecode.AddStep("store", args);
+            return this;
+        }
+
+        public GraphTraversal Subgraph(params object[] args)
+        {
+            Bytecode.AddStep("subgraph", args);
+            return this;
+        }
+
+        public GraphTraversal Sum(params object[] args)
+        {
+            Bytecode.AddStep("sum", args);
+            return this;
+        }
+
+        public GraphTraversal Tail(params object[] args)
+        {
+            Bytecode.AddStep("tail", args);
+            return this;
+        }
+
+        public GraphTraversal TimeLimit(params object[] args)
+        {
+            Bytecode.AddStep("timeLimit", args);
+            return this;
+        }
+
+        public GraphTraversal Times(params object[] args)
+        {
+            Bytecode.AddStep("times", args);
+            return this;
+        }
+
+        public GraphTraversal To(params object[] args)
+        {
+            Bytecode.AddStep("to", args);
+            return this;
+        }
+
+        public GraphTraversal ToE(params object[] args)
+        {
+            Bytecode.AddStep("toE", args);
+            return this;
+        }
+
+        public GraphTraversal ToV(params object[] args)
+        {
+            Bytecode.AddStep("toV", args);
+            return this;
+        }
+
+        public GraphTraversal Tree(params object[] args)
+        {
+            Bytecode.AddStep("tree", args);
+            return this;
+        }
+
+        public GraphTraversal Unfold(params object[] args)
+        {
+            Bytecode.AddStep("unfold", args);
+            return this;
+        }
+
+        public GraphTraversal Union(params object[] args)
+        {
+            Bytecode.AddStep("union", args);
+            return this;
+        }
+
+        public GraphTraversal Until(params object[] args)
+        {
+            Bytecode.AddStep("until", args);
+            return this;
+        }
+
+        public GraphTraversal Value(params object[] args)
+        {
+            Bytecode.AddStep("value", args);
+            return this;
+        }
+
+        public GraphTraversal ValueMap(params object[] args)
+        {
+            Bytecode.AddStep("valueMap", args);
+            return this;
+        }
+
+        public GraphTraversal Values(params object[] args)
+        {
+            Bytecode.AddStep("values", args);
+            return this;
+        }
+
+        public GraphTraversal Where(params object[] args)
+        {
+            Bytecode.AddStep("where", args);
+            return this;
+        }
+	}
+}