You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by jo...@apache.org on 2017/11/23 08:16:17 UTC

[42/50] tinkerpop git commit: Context parameters support

Context parameters support


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

Branch: refs/heads/TINKERPOP-1827
Commit: e3c7453f4fa33f7f8b2741f2dc30b083208a3fc2
Parents: fe6e613
Author: Jorge Bay Gondra <jo...@gmail.com>
Authored: Tue Oct 31 17:33:03 2017 +0100
Committer: Jorge Bay Gondra <jo...@gmail.com>
Committed: Thu Nov 23 09:08:07 2017 +0100

----------------------------------------------------------------------
 .../Process/Traversal/Instruction.cs            |   4 +-
 .../Gherkin/CommonSteps.cs                      | 113 ++++++++++-----
 .../Gherkin/GherkinTestRunner.cs                |  32 +----
 .../Gherkin/ScenarioData.cs                     |  59 ++++++++
 .../ContextBasedParameter.cs                    |  84 +++++++++++
 .../TraversalEvaluation/ITokenParameter.cs      |   3 +-
 .../TraversalEvaluation/NumericParameter.cs     |   8 +-
 .../StaticTraversalParameter.cs                 |   4 +-
 .../TraversalEvaluation/StringParameter.cs      |   3 +-
 .../TraversalEnumParameter.cs                   |   2 +-
 .../TraversalEvaluationTests.cs                 |  46 +++---
 .../TraversalEvaluation/TraversalParser.cs      | 143 +++++++++----------
 .../TraversalPredicateParameter.cs              |   5 +-
 13 files changed, 330 insertions(+), 176 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/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
index 195b7bf..a9163be 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Instruction.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Instruction.cs
@@ -28,6 +28,8 @@ namespace Gremlin.Net.Process.Traversal
     /// </summary>
     public class Instruction
     {
+        private static readonly object[] EmptyArgs = new object[0];
+        
         /// <summary>
         ///     Initializes a new instance of the <see cref="Instruction" /> class.
         /// </summary>
@@ -36,7 +38,7 @@ namespace Gremlin.Net.Process.Traversal
         public Instruction(string operatorName, params dynamic[] arguments)
         {
             OperatorName = operatorName;
-            Arguments = arguments;
+            Arguments = arguments ??  EmptyArgs;
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
index 16aef9d..235f1ba 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
@@ -25,15 +25,12 @@ using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
-using System.Net.Http.Headers;
-using System.Runtime.CompilerServices;
+using System.Text.RegularExpressions;
 using Gherkin.Ast;
 using Gremlin.Net.IntegrationTest.Gherkin.Attributes;
 using Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation;
 using Gremlin.Net.Process.Traversal;
 using Gremlin.Net.Structure;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
 using Xunit;
 
 namespace Gremlin.Net.IntegrationTest.Gherkin
@@ -41,14 +38,26 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
     internal class GeneralDefinitions : StepDefinition
     {
         private GraphTraversalSource _g;
+        private readonly IDictionary<string, object> _parameters = new Dictionary<string, object>();
         private dynamic _traversal;
         private object[] _result;
 
-        private static readonly IDictionary<string, Func<GraphTraversalSource, ITraversal>> FixedTranslations = 
-            new Dictionary<string, Func<GraphTraversalSource, ITraversal>>
+        private static readonly IDictionary<Regex, Func<string, object>> Parsers =
+            new Dictionary<string, Func<string, object>>
             {
-                { "g.V().has(\"no\").count()", g => g.V().Has("no").Count() }
-            };
+                {@"d\[(\d+)\]", x => Convert.ToInt64(x)},
+                {@"d\[(\d+(?:\.\d+)?)\]", x => Convert.ToDouble(x)},
+                {@"v\[(.+)\]", ToVertex},
+                {@"v\[(.+)\]\.id", x => ToVertex(x).Id},
+                {@"v\[(.+)\]\.sid", x => ToVertex(x).Id.ToString()},
+                {@"e\[(.+)\]", ToEdge},
+                {@"e\[(.+)\].id", s => ToEdge(s).Id},
+                {@"e\[(.+)\].sid", s => ToEdge(s).Id.ToString()},
+                {@"p\[(.+)\]", ToPath},
+                {@"l\[(.+)\]", ToList},
+                {@"s\[(.+)\]", ToSet},
+                {@"m\[(.+)\]", ToMap},
+            }.ToDictionary(kv => new Regex("^" + kv.Key + "$", RegexOptions.Compiled), kv => kv.Value);
         
         [Given("the modern graph")]
         public void ChooseModernGraph()
@@ -57,6 +66,22 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             _g = new Graph().Traversal().WithRemote(connection);
         }
 
+        [Given("using the parameter (\\w+) defined as \"(.*)\"")]
+        public void UsingParameter(string name, string value)
+        {
+            _parameters.Add(name, ParseValue(value));
+        }
+
+        [Given("the traversal of")]
+        public void TranslateTraversal(string traversalText)
+        {
+            if (_g == null)
+            {
+                throw new InvalidOperationException("g should be a traversal source");
+            }
+            _traversal = TraversalParser.GetTraversal(traversalText, _g, _parameters);
+        }
+
         [When("iterated to list")]
         public void IterateToList()
         {
@@ -78,16 +103,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             _result = _traversal.Next();
         }
 
-        [Given("the traversal of")]
-        public void TranslateTraversal(string traversalText)
-        {
-            if (_g == null)
-            {
-                throw new InvalidOperationException("g should be a traversal source");
-            }
-            _traversal = TraversalParser.GetTraversal(traversalText, _g);
-        }
-
         [Then("the result should be (\\w+)")]
         public void AssertResult(string characterizedAs, DataTable table)
         {
@@ -104,9 +119,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                     {
                         var row = rows[i];
                         var cells = row.Cells.ToArray();
-                        var typeName = cells[0].Value;
-                        var expectedValue = ConvertExpectedToType(typeName, cells[1].Value);
-                        var resultItem = ConvertResultItem(typeName, _result[i]);
+                        var expectedValue = ParseValue(cells[0].Value);
+                        var resultItem = ConvertResultItem(null, _result[i]);
                         Assert.Equal(expectedValue, resultItem);
                     }
                     break;
@@ -116,10 +130,9 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                     foreach (var row in rows)
                     {
                         var cells = row.Cells.ToArray();
-                        var typeName = cells[0].Value;
-                        var expectedValue = ConvertExpectedToType(typeName, cells[1].Value);
+                        var expectedValue = ParseValue(cells[0].Value);
                         // Convert all the values in the result to the type
-                        var convertedResult = _result.Select(item => ConvertResultItem(typeName, item));
+                        var convertedResult = _result.Select(item => ConvertResultItem(null, item));
                         Assert.Contains(expectedValue, convertedResult);
                     }
                     break;
@@ -149,19 +162,51 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             return result;
         }
 
-        private object ConvertExpectedToType(string typeName, string stringValue)
+        private static IDictionary ToMap(string arg)
+        {
+            throw new NotImplementedException();
+        }
+
+        private static ICollection ToSet(string arg)
+        {
+            throw new NotImplementedException();
+        }
+
+        private static IList ToList(string arg)
+        {
+            throw new NotImplementedException();
+        }
+
+        private static Vertex ToVertex(string name)
         {
-            switch (typeName)
+            return ScenarioData.Instance.ModernVertices[name];
+        }
+
+        private static Edge ToEdge(string s)
+        {
+            throw new NotImplementedException();
+        }
+
+        private static Path ToPath(string arg)
+        {
+            throw new NotImplementedException();
+        }
+
+        private static object ParseValue(string stringValue)
+        {
+            Func<string, object> parser = null;
+            string extractedValue = null;
+            foreach (var kv in Parsers)
             {
-                case "numeric":
-                    return Convert.ToInt64(stringValue);
-                case "string":
-                    return stringValue;
-                case "map":
-                    IDictionary<string, JToken> jsonObject = JObject.Parse(stringValue);
-                    return jsonObject.ToDictionary(item => item.Key, item => item.Value.ToString());
+                var match = kv.Key.Match(stringValue);
+                if (match.Success)
+                {
+                    parser = kv.Value;
+                    extractedValue = match.Groups[1].Value;
+                    break;
+                }
             }
-            throw new NotSupportedException($"Data table result with subtype of {typeName} not supported");
+            return parser != null ? parser(extractedValue) : stringValue;
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
index 7523b0b..d850d08 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
@@ -307,7 +307,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                 var parser = new Parser();
                 WriteOutput("Parsing " + gherkinFile);
                 var doc = parser.Parse(gherkinFile);
-                yield return doc.Feature;   
+                yield return doc.Feature;
             }
         }
 
@@ -332,35 +332,5 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             }
             return rootDir.FullName;
         }
-
-        private void PrintGherkin()
-        {
-            var gherkinFile = "/Users/jorge/workspace/temp/count.feature";
-            var parser = new Parser();
-            GherkinDocument doc = parser.Parse(gherkinFile);
-            foreach (var scenario in doc.Feature.Children)
-            {
-                WriteOutput("--------");
-                WriteOutput("Scenario: " + scenario.Name);
-                foreach (var step in scenario.Steps)
-                {
-                    WriteOutput("  Step");
-                    WriteOutput("    Keyword: " + step.Keyword);
-                    WriteOutput("    Text: " + step.Text);
-                    WriteOutput("    Argument: " + step.Argument);
-                    if (step.Argument is DocString)
-                    {
-                        WriteOutput("      " + ((DocString)step.Argument).Content);
-                    }
-                    if (step.Argument is DataTable)
-                    {
-                        foreach (var row in ((DataTable)step.Argument).Rows)
-                        {
-                            WriteOutput("      Row: " + string.Join(", ", row.Cells.Select(x => x.Value)));   
-                        }
-                    }
-                }
-            }
-        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/ScenarioData.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/ScenarioData.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/ScenarioData.cs
new file mode 100644
index 0000000..c45ed12
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/ScenarioData.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;
+using System.Collections.Generic;
+using System.Linq;
+using Gremlin.Net.IntegrationTest.Process.Traversal.DriverRemoteConnection;
+using Gremlin.Net.Process.Traversal;
+using Gremlin.Net.Structure;
+
+namespace Gremlin.Net.IntegrationTest.Gherkin
+{
+    public class ScenarioData
+    {
+        private static readonly Lazy<ScenarioData> Lazy = new Lazy<ScenarioData>(Load);
+        
+        public static ScenarioData Instance => Lazy.Value;
+
+        public IDictionary<string, Vertex> ModernVertices { get; }
+        
+        public IDictionary<string, Edge> ModernEdges { get; }
+        
+        private ScenarioData(IDictionary<string, Vertex> modernVertices, IDictionary<string, Edge> modernEdges)
+        {
+            ModernVertices = modernVertices;
+            ModernEdges = modernEdges;
+        }
+
+        private static ScenarioData Load()
+        {
+            var connectionFactory = new RemoteConnectionFactory();
+            var g = new Graph().Traversal().WithRemote(connectionFactory.CreateRemoteConnection());
+            //TODO: Remove workaround once Group() is fixed TINKERPOP-1752
+            var vertices = g.V().ToList().ToDictionary(v => g.V(v.Id).Values<string>("name").Next(), v => v);
+            connectionFactory.Dispose();
+            return new ScenarioData(vertices, null);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ContextBasedParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ContextBasedParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ContextBasedParameter.cs
new file mode 100644
index 0000000..4f837d4
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ContextBasedParameter.cs
@@ -0,0 +1,84 @@
+#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.IntegrationTest.Gherkin.TraversalEvaluation
+{
+    public class ContextBasedParameter : ITokenParameter, IEquatable<ContextBasedParameter>
+    {
+        public bool Equals(ContextBasedParameter other)
+        {
+            return string.Equals(_name, other._name) && Equals(_value, other._value);
+        }
+
+        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((ContextBasedParameter) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                return ((_name != null ? _name.GetHashCode() : 0) * 397) ^ (_value != null ? _value.GetHashCode() : 0);
+            }
+        }
+
+        private readonly string _name;
+        private object _value;
+
+        public ContextBasedParameter(string name)
+        {
+            _name = name;
+        }
+
+        private void SetValue(IDictionary<string, object> parameterValues)
+        {
+            if (parameterValues == null || !parameterValues.TryGetValue(_name, out var value))
+            {
+                throw new InvalidOperationException($"Parameter \"{_name}\" was not provided");
+            }
+            _value = value;
+        }
+        
+        public object GetValue(IDictionary<string, object> contextParameterValues)
+        {
+            SetValue(contextParameterValues);
+            return _value;
+        }
+
+        public Type GetParameterType()
+        {
+            if (_value == null)
+            {
+                throw new NullReferenceException($"Value for parameter \"{_name}\" was not set");
+            }
+            return _value.GetType();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs
index 5c8197f..9b06e80 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs
@@ -22,6 +22,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 
 namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
 {
@@ -30,7 +31,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
         /// <summary>
         /// Gets the value of the parameter 
         /// </summary>
-        object GetValue();
+        object GetValue(IDictionary<string, object> contextParameterValues);
 
         /// <summary>
         /// Gets the type of the parameter

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs
index 378680c..7428cc2 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs
@@ -22,6 +22,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 
 namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
 {
@@ -57,7 +58,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             return $"NumericParameter<{typeof(T).Name}>({Value})";
         }
 
-        public object GetValue()
+        public object GetValue(IDictionary<string, object> contextParameterValues)
         {
             return Value;
         }
@@ -74,5 +75,10 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
         {
             return new NumericParameter<TType>(value);
         }
+
+        public static NumericParameter<long> CreateLong(string value)
+        {
+            return NumericParameter.Create(Convert.ToInt64(value.Substring(0, value.Length - 1)));
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
index dca691b..dd38dca 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
@@ -50,9 +50,9 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             return Tokens != null ? Tokens.GetHashCode() : 0;
         }
 
-        public object GetValue()
+        public object GetValue(IDictionary<string, object> contextParameterValues)
         {
-            return TraversalParser.GetTraversalFromTokens(Tokens, null, _traversalText);
+            return TraversalParser.GetTraversalFromTokens(Tokens, null, contextParameterValues, _traversalText);
         }
 
         public Type GetParameterType()

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs
index 82f6cd9..430c2d2 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs
@@ -22,6 +22,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 
 namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
 {
@@ -66,7 +67,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             return $"{GetType().Name}({Value})";
         }
 
-        public object GetValue()
+        public object GetValue(IDictionary<string, object> contextParameterValues)
         {
             return Value;
         }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs
index 663928a..c99fc95 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs
@@ -85,7 +85,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             return _text.GetHashCode();
         }
 
-        public object GetValue()
+        public object GetValue(IDictionary<string, object> contextParameterValues)
         {
             return _value;
         }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
index 9cbceb9..be5f444 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
@@ -31,13 +31,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
 {
     public class TraversalEvaluationTests
     {
-        private readonly ITestOutputHelper _output;
-
-        public TraversalEvaluationTests(ITestOutputHelper output)
-        {
-            _output = output;
-        }
-        
         [Fact]
         public void Traversal_Parser_Should_Parse_Into_Tokens()
         {
@@ -48,6 +41,12 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
                     new[] {new Token("values", new StringParameter("name"))}),
                 Tuple.Create("g.V().constant(123l)", 
                     new[] {new Token("constant", new[] {NumericParameter.Create(123L)})}),
+                Tuple.Create("g.V().constant(123)", 
+                    new[] {new Token("constant", new[] {NumericParameter.Create(123)})}),
+                Tuple.Create("g.V().constant(123.1)", 
+                    new[] {new Token("constant", new[] {NumericParameter.Create(123.1)})}),
+                Tuple.Create("g.V().constant(123.1f)", 
+                    new[] {new Token("constant", new[] {NumericParameter.Create(123.1f)})}),
                 Tuple.Create("g.V().has(\"no\").count()",
                     new[] {new Token("has", new StringParameter("no")), new Token("count")}),
                 Tuple.Create("g.V().has(\"lang\", \"java\")",
@@ -55,7 +54,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
                 Tuple.Create("g.V().where(__.in(\"knows\"))",
                     new[] {new Token("where", new[] {new StaticTraversalParameter(
                         new[] {new Token("__"), new Token("in", new StringParameter("knows"))}, "__.in(\"knows\")")})}),
-                Tuple.Create("g.V().has(\"age\", P.gt(27)", 
+                Tuple.Create("g.V().has(\"age\",P.gt(27))", 
                     new[] {new Token("has", new ITokenParameter[] { new StringParameter("age"),
                         new TraversalPredicateParameter(
                             new[] { new Token("P"), new Token("gt", NumericParameter.Create(27)) }) })}),
@@ -65,14 +64,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             foreach (var item in items)
             {
                 var parts = TraversalParser.ParseTraversal(item.Item1);
-                _output.WriteLine("Parsing " + item.Item1);
-                if (parts[parts.Count-1].Parameters != null)
-                {
-                    _output.WriteLine("{0}", parts[parts.Count-1].Parameters.Count);
-                    _output.WriteLine("Values: " +
-                                      string.Join(", ", parts[parts.Count - 1].Parameters.Select(p => p.ToString())));
-                }
-                Assert.Equal(new[] {new Token("g"), new Token("V")}.Concat(item.Item2), parts);
+                Assert.Equal(item.Item2, parts.Skip(2));
             }
         }
 
@@ -81,21 +73,21 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
         {
             var traversalTexts = new []
             {
-                "g.V().count()",
-                //"g.V().constant(123L)", Can be parsed using the new type-safe API
-                "g.V().has(\"no\").count()",
-                "g.V().values(\"age\")",
-                "g.V().valueMap(\"name\", \"age\")",
-                "g.V().where(__.in(\"created\").count().is(1)).values(\"name\")",
-                "g.V().count(Scope.local)",
-                "g.V().values(\"age\").is(P.lte(30))"
+                Tuple.Create("g.V().count()", 2),
+//                //"g.V().constant(123L)", Can be parsed using the new type-safe API
+                Tuple.Create("g.V().has(\"no\").count()", 3),
+                Tuple.Create("g.V().values(\"age\")", 2),
+                Tuple.Create("g.V().valueMap(\"name\", \"age\")", 2),
+                Tuple.Create("g.V().where(__.in(\"created\").count().is(1)).values(\"name\")", 3),
+                Tuple.Create("g.V().count(Scope.local)", 2),
+                Tuple.Create("g.V().values(\"age\").is(P.lte(30))", 3)
             };
             var g = new Graph().Traversal();
-            foreach (var text in traversalTexts)
+            foreach (var tuple in traversalTexts)
             {
-                var traversal = TraversalParser.GetTraversal(text, g);
+                var traversal = TraversalParser.GetTraversal(tuple.Item1, g, null);
                 Assert.NotNull(traversal);
-                Assert.True(traversal.Bytecode.StepInstructions.Count > 0);
+                Assert.Equal(tuple.Item2, traversal.Bytecode.StepInstructions.Count);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
index 9880a64..4cf7b4a 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
@@ -36,71 +36,60 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             {
                 { "g.V().fold().count(Scope.local)", g => g.V().Fold<object>().Count(Scope.Local)}
             };
-        
-        private static readonly Regex RegexInteger = new Regex(@"\d+", RegexOptions.Compiled);
-        private static readonly Regex RegexDouble = new Regex(@"\d+\.\d+", RegexOptions.Compiled);
-        private static readonly Regex RegexFloat =
-            new Regex(@"\d+\.\d+f", RegexOptions.Compiled | RegexOptions.IgnoreCase);
-        private static readonly Regex RegexLong = new Regex(@"\d+l", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+
+        private static readonly Regex RegexNumeric =
+            new Regex(@"\d+(\.\d+)?(?:l|f)?", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+
         private static readonly Regex RegexEnum = new Regex(@"\w+\.\w+", RegexOptions.Compiled);
 
-        internal static ITraversal GetTraversal(string traversalText, GraphTraversalSource g)
+        private static readonly Regex RegexParam = new Regex(@"\w+", RegexOptions.Compiled);
+
+        internal static ITraversal GetTraversal(string traversalText, GraphTraversalSource g,
+                                                IDictionary<string, object> contextParameterValues)
         {
             if (!FixedTranslations.TryGetValue(traversalText, out var traversalBuilder))
             {
                 var tokens = ParseTraversal(traversalText);
-                return GetTraversalFromTokens(tokens, g, traversalText);
+                return GetTraversalFromTokens(tokens, g, contextParameterValues, traversalText);
             }
             return traversalBuilder(g);
         }
 
         internal static ITraversal GetTraversalFromTokens(IList<Token> tokens, GraphTraversalSource g,
-                                                         string traversalText)
+                                                          IDictionary<string, object> contextParameterValues,
+                                                          string traversalText)
         {
-            ITraversal traversal;
-            Type traversalType;
-            var initialIndex = 2;
+            object instance;
+            Type instanceType;
             if (tokens[0].Name == "g")
             {
-                switch (tokens[1].Name)
-                {
-                    case "V":
-                        //TODO: support V() parameters
-                        traversal = g.V();
-                        break;
-                    case "E":
-                        traversal = g.E();
-                        break;
-                    default:
-                        throw BuildException(traversalText);
-                }
-                traversalType = traversal.GetType();
+                instance = g;
+                instanceType = g.GetType();
             }
             else if (tokens[0].Name == "__")
             {
-                traversal = null;
-                traversalType = typeof(__);
-                initialIndex = 1;
+                instance = null;
+                instanceType = typeof(__);
             }
             else
             {
                 throw BuildException(traversalText);
             }
-            for (var i = initialIndex; i < tokens.Count; i++)
+            for (var i = 1; i < tokens.Count; i++)
             {
                 var token = tokens[i];
                 var name = GetCsharpName(token.Name);
-                var method = traversalType.GetMethod(name);
+                var method = instanceType.GetMethod(name);
                 if (method == null)
                 {
                     throw new InvalidOperationException($"Traversal method '{tokens[i]}' not found for testing");
                 }
-                var parameterValues = BuildParameters(method, token, out var genericParameters);
+                var parameterValues = BuildParameters(method, token, contextParameterValues, out var genericParameters);
                 method = BuildGenericMethod(method, genericParameters, parameterValues);
-                traversal = (ITraversal) method.Invoke(traversal, parameterValues);
-                traversalType = traversal.GetType();
+                instance = method.Invoke(instance, parameterValues);
+                instanceType = instance.GetType();
             }
-            return traversal;
+            return (ITraversal) instance;
         }
 
         private static MethodInfo BuildGenericMethod(MethodInfo method, IDictionary<string, Type> genericParameters,
@@ -133,6 +122,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
         }
 
         private static object[] BuildParameters(MethodInfo method, Token token,
+                                                IDictionary<string, object> contextParameterValues,
                                                 out IDictionary<string, Type> genericParameterTypes)
         {
             var paramsInfo = method.GetParameters();
@@ -145,7 +135,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
                 if (token.Parameters.Count > i)
                 {
                     var tokenParameter = token.Parameters[i];
-                    value =  tokenParameter.GetValue();
+                    value =  tokenParameter.GetValue(contextParameterValues);
                     if (info.ParameterType.IsGenericParameter)
                     {
                         // We've provided a value for parameter of a generic type, we can infer the
@@ -191,41 +181,40 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             var result = new List<Token>();
             var startIndex = i;
             var parsing = ParsingPart.Name;
-            string name = null;
             var parameters = new List<ITokenParameter>();
+            string name = null;
             while (i < text.Length)
             {
                 switch (text[i])
                 {
                     case '.':
-                        if (name == null)
+                        if (parsing == ParsingPart.Name)
                         {
-                            name = text.Substring(startIndex, i - startIndex);
+                            // The previous token was an object property, not a method
+                            result.Add(new Token(text.Substring(startIndex, i - startIndex)));
                         }
                         startIndex = i + 1;
-                        result.Add(new Token(name, parameters));
-                        name = null;
                         parameters = new List<ITokenParameter>();
                         parsing = ParsingPart.Name;
                         break;
                     case '(':
                     {
                         name = text.Substring(startIndex, i - startIndex);
-                        i++;
                         parsing = ParsingPart.StartParameters;
+                        // Start parsing from the next index
+                        i++;
                         var param = ParseParameter(text, ref i);
                         if (param == null)
                         {
-                            parsing = ParsingPart.EndParameters;
-                        }
-                        else
-                        {
-                            parameters.Add(param);
+                            // The next character was a ')', empty params
+                            // Evaluate the current position
+                            continue;
                         }
+                        parameters.Add(param);
                         break;
                     }
                     case ',' when text[i+1] != ' ':
-                    case ' ' when text[i+1] != ' ':
+                    case ' ' when text[i+1] != ' ' && text[i+1] != ')':
                     {
                         if (parsing != ParsingPart.StartParameters)
                         {
@@ -236,31 +225,33 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
                         var param = ParseParameter(text, ref i);
                         if (param == null)
                         {
-                            parsing = ParsingPart.EndParameters;
-                        }
-                        else
-                        {
-                            parameters.Add(param);
+                            // The next character was a ')', empty params
+                            // Evaluate the current position
+                            continue;
                         }
+                        parameters.Add(param);
                         break;
                     }
                     case ')' when parsing != ParsingPart.StartParameters:
-                        // The traversal already ended
-                        i--;
-                        if (name != null)
+                        // The current nested object already ended
+                        if (parsing == ParsingPart.Name)
                         {
-                            result.Add(new Token(name, parameters));
+                            // The previous token was an object property, not a method and finished
+                            result.Add(new Token(text.Substring(startIndex, i - startIndex)));
                         }
+                        i--;
                         return result;
                     case ')':
                         parsing = ParsingPart.EndParameters;
+                        result.Add(new Token(name, parameters));
                         break;
                 }
                 i++;
             }
-            if (name != null)
+            if (parsing == ParsingPart.Name)
             {
-                result.Add(new Token(name, parameters));
+                // The previous token was an object property, not a method and finished
+                result.Add(new Token(text.Substring(startIndex, i - startIndex)));
             }
             return result;
         }
@@ -297,38 +288,40 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             }
             if (RegexEnum.IsMatch(parameterText))
             {
+                i += parameterText.Length - 1;
                 return new TraversalEnumParameter(parameterText);
             }
+            if (RegexParam.IsMatch(parameterText))
+            {
+                i += parameterText.Length - 1;
+                return new ContextBasedParameter(parameterText);
+            }
             throw new NotSupportedException($"Parameter {parameterText} not supported");
         }
         
         private static ITokenParameter ParseNumber(string text, ref int i)
         {
-            var match = RegexLong.Match(text.Substring(i));
-            if (match.Success)
+            var match = RegexNumeric.Match(text, i);
+            if (!match.Success)
             {
-                i += match.Value.Length - 1;
-                return NumericParameter.Create(Convert.ToInt64(match.Value.Substring(0, match.Value.Length-1)));
+                throw new InvalidOperationException(
+                    $"Could not parse numeric value from the beginning of {text.Substring(i)}");
             }
-            match = RegexFloat.Match(text.Substring(i));
-            if (match.Success)
+            var numericText = match.Value.ToUpper();
+            i += match.Value.Length - 1;
+            if (numericText.EndsWith("L"))
             {
-                i += match.Value.Length - 1;
-                return NumericParameter.Create(Convert.ToSingle(match.Value.Substring(0, match.Value.Length-1)));
+                return NumericParameter.Create(Convert.ToInt64(match.Value.Substring(0, match.Value.Length - 1)));
             }
-            match = RegexDouble.Match(text.Substring(i));
-            if (match.Success)
+            if (numericText.EndsWith("F"))
             {
-                i += match.Value.Length;
-                return NumericParameter.Create(Convert.ToSingle(match.Value));
+                return NumericParameter.Create(Convert.ToSingle(match.Value.Substring(0, match.Value.Length-1)));
             }
-            match = RegexInteger.Match(text.Substring(i));
-            if (!match.Success)
+            if (match.Groups[1].Value != "")
             {
-                throw new InvalidOperationException(
-                    $"Could not parse numeric value from the beginning of {text.Substring(i)}");
+                // Captured text with the decimal separator
+                return NumericParameter.Create(Convert.ToDouble(match.Value));
             }
-            i += match.Value.Length;
             return NumericParameter.Create(Convert.ToInt32(match.Value));
         }
         

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e3c7453f/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs
index 0d0dc49..83060c7 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs
@@ -52,7 +52,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             return Tokens != null ? Tokens.GetHashCode() : 0;
         }
 
-        public object GetValue()
+        public object GetValue(IDictionary<string, object> contextParameterValues)
         {
             var type = typeof(P);
             object instance = null;
@@ -65,7 +65,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
                 {
                     throw new InvalidOperationException($"Predicate (P) method '{token}' not found for testing");
                 }
-                instance = method.Invoke(instance, new object[] {token.Parameters.Select(p => p.GetValue()).ToArray()});
+                instance = method.Invoke(instance,
+                    new object[] {token.Parameters.Select(p => p.GetValue(contextParameterValues)).ToArray()});
             }
             return instance;
         }