#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.Structure;

// THIS IS A GENERATED FILE - DO NOT MODIFY THIS FILE DIRECTLY - see pom.xml
namespace Gremlin.Net.Process.Traversal
{
    /// <summary>
    ///     An anonymous <see cref="GraphTraversal{SType, EType}" />.
    /// </summary>
    public static class __
    {
        /// <summary>
        ///     Starts an empty <see cref="GraphTraversal{SType, EType}" />.
        /// </summary>
        public static GraphTraversal<object, object> Start()
        {
            return new GraphTraversal<object, object>();
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the V step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> V(params object[] vertexIdsOrElements)
        {
            return vertexIdsOrElements.Length == 0
                ? new GraphTraversal<object, Vertex>().V()
                : new GraphTraversal<object, Vertex>().V(vertexIdsOrElements);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the addE step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Edge> AddE(string edgeLabel)
        {
            return new GraphTraversal<object, Edge>().AddE(edgeLabel);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the addE step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Edge> AddE(ITraversal edgeLabelTraversal)
        {
            return new GraphTraversal<object, Edge>().AddE(edgeLabelTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the addV step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> AddV()
        {
            return new GraphTraversal<object, Vertex>().AddV();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the addV step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> AddV(string vertexLabel)
        {
            return new GraphTraversal<object, Vertex>().AddV(vertexLabel);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the addV step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> AddV(ITraversal vertexLabelTraversal)
        {
            return new GraphTraversal<object, Vertex>().AddV(vertexLabelTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the aggregate step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Aggregate(string sideEffectKey)
        {
            return new GraphTraversal<object, object>().Aggregate(sideEffectKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the and step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> And(params ITraversal[] andTraversals)
        {
            return andTraversals.Length == 0
                ? new GraphTraversal<object, object>().And()
                : new GraphTraversal<object, object>().And(andTraversals);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the as step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> As(string label, params string[] labels)
        {
            return labels.Length == 0
                ? new GraphTraversal<object, object>().As(label)
                : new GraphTraversal<object, object>().As(label, labels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the barrier step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Barrier()
        {
            return new GraphTraversal<object, object>().Barrier();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the barrier step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Barrier(IConsumer barrierConsumer)
        {
            return new GraphTraversal<object, object>().Barrier(barrierConsumer);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the barrier step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Barrier(int maxBarrierSize)
        {
            return new GraphTraversal<object, object>().Barrier(maxBarrierSize);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the both step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> Both(params string[] edgeLabels)
        {
            return edgeLabels.Length == 0
                ? new GraphTraversal<object, Vertex>().Both()
                : new GraphTraversal<object, Vertex>().Both(edgeLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the bothE step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Edge> BothE(params string[] edgeLabels)
        {
            return edgeLabels.Length == 0
                ? new GraphTraversal<object, Edge>().BothE()
                : new GraphTraversal<object, Edge>().BothE(edgeLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the bothV step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> BothV()
        {
            return new GraphTraversal<object, Vertex>().BothV();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the branch step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Branch<E2>(IFunction function)
        {
            return new GraphTraversal<object, E2>().Branch<E2>(function);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the branch step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Branch<E2>(ITraversal traversalFunction)
        {
            return new GraphTraversal<object, E2>().Branch<E2>(traversalFunction);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the cap step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Cap<E2>(string sideEffectKey, params string[] sideEffectKeys)
        {
            return sideEffectKeys.Length == 0
                ? new GraphTraversal<object, E2>().Cap<E2>(sideEffectKey)
                : new GraphTraversal<object, E2>().Cap<E2>(sideEffectKey, sideEffectKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the choose step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Choose<E2>(IFunction choiceFunction)
        {
            return new GraphTraversal<object, E2>().Choose<E2>(choiceFunction);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the choose step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Choose<E2>(IPredicate choosePredicate, ITraversal trueChoice)
        {
            return new GraphTraversal<object, E2>().Choose<E2>(choosePredicate, trueChoice);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the choose step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Choose<E2>(IPredicate choosePredicate, ITraversal trueChoice, ITraversal falseChoice)
        {
            return new GraphTraversal<object, E2>().Choose<E2>(choosePredicate, trueChoice, falseChoice);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the choose step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Choose<E2>(ITraversal traversalFunction)
        {
            return new GraphTraversal<object, E2>().Choose<E2>(traversalFunction);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the choose step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Choose<E2>(ITraversal traversalPredicate, ITraversal trueChoice)
        {
            return new GraphTraversal<object, E2>().Choose<E2>(traversalPredicate, trueChoice);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the choose step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Choose<E2>(ITraversal traversalPredicate, ITraversal trueChoice, ITraversal falseChoice)
        {
            return new GraphTraversal<object, E2>().Choose<E2>(traversalPredicate, trueChoice, falseChoice);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the coalesce step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Coalesce<E2>(params ITraversal[] traversals)
        {
            return traversals.Length == 0
                ? new GraphTraversal<object, E2>().Coalesce<E2>()
                : new GraphTraversal<object, E2>().Coalesce<E2>(traversals);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the coin step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Coin(double probability)
        {
            return new GraphTraversal<object, object>().Coin(probability);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the constant step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Constant<E2>(E2 a)
        {
            return new GraphTraversal<object, E2>().Constant<E2>(a);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the count step to that traversal.
        /// </summary>
        public static GraphTraversal<object, long> Count()
        {
            return new GraphTraversal<object, long>().Count();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the count step to that traversal.
        /// </summary>
        public static GraphTraversal<object, long> Count(Scope scope)
        {
            return new GraphTraversal<object, long>().Count(scope);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the cyclicPath step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> CyclicPath()
        {
            return new GraphTraversal<object, object>().CyclicPath();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the dedup step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Dedup(Scope scope, params string[] dedupLabels)
        {
            return dedupLabels.Length == 0
                ? new GraphTraversal<object, object>().Dedup(scope)
                : new GraphTraversal<object, object>().Dedup(scope, dedupLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the dedup step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Dedup(params string[] dedupLabels)
        {
            return dedupLabels.Length == 0
                ? new GraphTraversal<object, object>().Dedup()
                : new GraphTraversal<object, object>().Dedup(dedupLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the drop step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Drop()
        {
            return new GraphTraversal<object, object>().Drop();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the emit step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Emit()
        {
            return new GraphTraversal<object, object>().Emit();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the emit step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Emit(IPredicate emitPredicate)
        {
            return new GraphTraversal<object, object>().Emit(emitPredicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the emit step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Emit(ITraversal emitTraversal)
        {
            return new GraphTraversal<object, object>().Emit(emitTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the filter step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Filter(IPredicate predicate)
        {
            return new GraphTraversal<object, object>().Filter(predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the filter step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Filter(ITraversal filterTraversal)
        {
            return new GraphTraversal<object, object>().Filter(filterTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the flatMap step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> FlatMap<E2>(IFunction function)
        {
            return new GraphTraversal<object, E2>().FlatMap<E2>(function);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the flatMap step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> FlatMap<E2>(ITraversal flatMapTraversal)
        {
            return new GraphTraversal<object, E2>().FlatMap<E2>(flatMapTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the fold step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IList<E2>> Fold<E2>()
        {
            return new GraphTraversal<object, E2>().Fold();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the fold step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Fold<E2>(E2 seed, IBiFunction foldFunction)
        {
            return new GraphTraversal<object, E2>().Fold<E2>(seed, foldFunction);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the group step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<K, V>> Group<K, V>()
        {
            return new GraphTraversal<object, IDictionary<K, V>>().Group<K, V>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the group step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Group(string sideEffectKey)
        {
            return new GraphTraversal<object, object>().Group(sideEffectKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the groupCount step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<K, long>> GroupCount<K>()
        {
            return new GraphTraversal<object, IDictionary<K, long>>().GroupCount<K>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the groupCount step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> GroupCount(string sideEffectKey)
        {
            return new GraphTraversal<object, object>().GroupCount(sideEffectKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(string propertyKey)
        {
            return new GraphTraversal<object, object>().Has(propertyKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(string propertyKey, object value)
        {
            return new GraphTraversal<object, object>().Has(propertyKey, value);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(string propertyKey, P predicate)
        {
            return new GraphTraversal<object, object>().Has(propertyKey, predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(string label, string propertyKey, object value)
        {
            return new GraphTraversal<object, object>().Has(label, propertyKey, value);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(string label, string propertyKey, P predicate)
        {
            return new GraphTraversal<object, object>().Has(label, propertyKey, predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(string propertyKey, ITraversal propertyTraversal)
        {
            return new GraphTraversal<object, object>().Has(propertyKey, propertyTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(T accessor, object value)
        {
            return new GraphTraversal<object, object>().Has(accessor, value);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(T accessor, P predicate)
        {
            return new GraphTraversal<object, object>().Has(accessor, predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Has(T accessor, ITraversal propertyTraversal)
        {
            return new GraphTraversal<object, object>().Has(accessor, propertyTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasId step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasId(object id, params object[] otherIds)
        {
            return otherIds.Length == 0
                ? new GraphTraversal<object, object>().HasId(id)
                : new GraphTraversal<object, object>().HasId(id, otherIds);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasId step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasId(P predicate)
        {
            return new GraphTraversal<object, object>().HasId(predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasKey step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasKey(P predicate)
        {
            return new GraphTraversal<object, object>().HasKey(predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasKey step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasKey(string label, params string[] otherLabels)
        {
            return otherLabels.Length == 0
                ? new GraphTraversal<object, object>().HasKey(label)
                : new GraphTraversal<object, object>().HasKey(label, otherLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasLabel step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasLabel(P predicate)
        {
            return new GraphTraversal<object, object>().HasLabel(predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasLabel step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasLabel(string label, params string[] otherLabels)
        {
            return otherLabels.Length == 0
                ? new GraphTraversal<object, object>().HasLabel(label)
                : new GraphTraversal<object, object>().HasLabel(label, otherLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasNot step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasNot(string propertyKey)
        {
            return new GraphTraversal<object, object>().HasNot(propertyKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasValue step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasValue(object value, params object[] values)
        {
            return values.Length == 0
                ? new GraphTraversal<object, object>().HasValue(value)
                : new GraphTraversal<object, object>().HasValue(value, values);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasValue step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> HasValue(P predicate)
        {
            return new GraphTraversal<object, object>().HasValue(predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the id step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Id()
        {
            return new GraphTraversal<object, object>().Id();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the identity step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Identity()
        {
            return new GraphTraversal<object, object>().Identity();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the in step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> In(params string[] edgeLabels)
        {
            return edgeLabels.Length == 0
                ? new GraphTraversal<object, Vertex>().In()
                : new GraphTraversal<object, Vertex>().In(edgeLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the inE step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Edge> InE(params string[] edgeLabels)
        {
            return edgeLabels.Length == 0
                ? new GraphTraversal<object, Edge>().InE()
                : new GraphTraversal<object, Edge>().InE(edgeLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the inV step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> InV()
        {
            return new GraphTraversal<object, Vertex>().InV();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the inject step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Inject(params object[] injections)
        {
            return injections.Length == 0
                ? new GraphTraversal<object, object>().Inject()
                : new GraphTraversal<object, object>().Inject(injections);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the is step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Is(object value)
        {
            return new GraphTraversal<object, object>().Is(value);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the is step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Is(P predicate)
        {
            return new GraphTraversal<object, object>().Is(predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the key step to that traversal.
        /// </summary>
        public static GraphTraversal<object, string> Key()
        {
            return new GraphTraversal<object, string>().Key();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the label step to that traversal.
        /// </summary>
        public static GraphTraversal<object, string> Label()
        {
            return new GraphTraversal<object, string>().Label();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the limit step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Limit<E2>(Scope scope, long limit)
        {
            return new GraphTraversal<object, E2>().Limit<E2>(scope, limit);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the limit step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Limit<E2>(long limit)
        {
            return new GraphTraversal<object, E2>().Limit<E2>(limit);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the local step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Local<E2>(ITraversal localTraversal)
        {
            return new GraphTraversal<object, E2>().Local<E2>(localTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the loops step to that traversal.
        /// </summary>
        public static GraphTraversal<object, int> Loops()
        {
            return new GraphTraversal<object, int>().Loops();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the map step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Map<E2>(IFunction function)
        {
            return new GraphTraversal<object, E2>().Map<E2>(function);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the map step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Map<E2>(ITraversal mapTraversal)
        {
            return new GraphTraversal<object, E2>().Map<E2>(mapTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the match step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<string, E2>> Match<E2>(params ITraversal[] matchTraversals)
        {
            return matchTraversals.Length == 0
                ? new GraphTraversal<object, IDictionary<string, E2>>().Match<E2>()
                : new GraphTraversal<object, IDictionary<string, E2>>().Match<E2>(matchTraversals);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the math step to that traversal.
        /// </summary>
        public static GraphTraversal<object, double> Math(string expression)
        {
            return new GraphTraversal<object, double>().Math(expression);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the max step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Max<E2>()
        {
            return new GraphTraversal<object, E2>().Max<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the max step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Max<E2>(Scope scope)
        {
            return new GraphTraversal<object, E2>().Max<E2>(scope);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the mean step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Mean<E2>()
        {
            return new GraphTraversal<object, E2>().Mean<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the mean step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Mean<E2>(Scope scope)
        {
            return new GraphTraversal<object, E2>().Mean<E2>(scope);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the min step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Min<E2>()
        {
            return new GraphTraversal<object, E2>().Min<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the min step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Min<E2>(Scope scope)
        {
            return new GraphTraversal<object, E2>().Min<E2>(scope);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the not step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Not(ITraversal notTraversal)
        {
            return new GraphTraversal<object, object>().Not(notTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the optional step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Optional<E2>(ITraversal optionalTraversal)
        {
            return new GraphTraversal<object, E2>().Optional<E2>(optionalTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the or step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Or(params ITraversal[] orTraversals)
        {
            return orTraversals.Length == 0
                ? new GraphTraversal<object, object>().Or()
                : new GraphTraversal<object, object>().Or(orTraversals);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the order step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Order()
        {
            return new GraphTraversal<object, object>().Order();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the order step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Order(Scope scope)
        {
            return new GraphTraversal<object, object>().Order(scope);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the otherV step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> OtherV()
        {
            return new GraphTraversal<object, Vertex>().OtherV();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the out step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> Out(params string[] edgeLabels)
        {
            return edgeLabels.Length == 0
                ? new GraphTraversal<object, Vertex>().Out()
                : new GraphTraversal<object, Vertex>().Out(edgeLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the outE step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Edge> OutE(params string[] edgeLabels)
        {
            return edgeLabels.Length == 0
                ? new GraphTraversal<object, Edge>().OutE()
                : new GraphTraversal<object, Edge>().OutE(edgeLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the outV step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> OutV()
        {
            return new GraphTraversal<object, Vertex>().OutV();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the path step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Path> Path()
        {
            return new GraphTraversal<object, Path>().Path();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the project step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<string, E2>> Project<E2>(string projectKey, params string[] projectKeys)
        {
            return projectKeys.Length == 0
                ? new GraphTraversal<object, IDictionary<string, E2>>().Project<E2>(projectKey)
                : new GraphTraversal<object, IDictionary<string, E2>>().Project<E2>(projectKey, projectKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the properties step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Properties<E2>(params string[] propertyKeys)
        {
            return propertyKeys.Length == 0
                ? new GraphTraversal<object, E2>().Properties<E2>()
                : new GraphTraversal<object, E2>().Properties<E2>(propertyKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the property step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Property(Cardinality cardinality, object key, object value, params object[] keyValues)
        {
            return keyValues.Length == 0
                ? new GraphTraversal<object, object>().Property(cardinality, key, value)
                : new GraphTraversal<object, object>().Property(cardinality, key, value, keyValues);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the property step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Property(object key, object value, params object[] keyValues)
        {
            return keyValues.Length == 0
                ? new GraphTraversal<object, object>().Property(key, value)
                : new GraphTraversal<object, object>().Property(key, value, keyValues);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the propertyMap step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<string, E2>> PropertyMap<E2>(params string[] propertyKeys)
        {
            return propertyKeys.Length == 0
                ? new GraphTraversal<object, IDictionary<string, E2>>().PropertyMap<E2>()
                : new GraphTraversal<object, IDictionary<string, E2>>().PropertyMap<E2>(propertyKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the range step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Range<E2>(Scope scope, long low, long high)
        {
            return new GraphTraversal<object, E2>().Range<E2>(scope, low, high);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the range step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Range<E2>(long low, long high)
        {
            return new GraphTraversal<object, E2>().Range<E2>(low, high);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the repeat step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Repeat(ITraversal traversal)
        {
            return new GraphTraversal<object, object>().Repeat(traversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the sack step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Sack<E2>()
        {
            return new GraphTraversal<object, E2>().Sack<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the sack step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Sack(IBiFunction sackOperator)
        {
            return new GraphTraversal<object, object>().Sack(sackOperator);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the sample step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Sample(Scope scope, int amountToSample)
        {
            return new GraphTraversal<object, object>().Sample(scope, amountToSample);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the sample step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Sample(int amountToSample)
        {
            return new GraphTraversal<object, object>().Sample(amountToSample);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the select step to that traversal.
        /// </summary>
        public static GraphTraversal<object, ICollection<E2>> Select<E2>(Column column)
        {
            return new GraphTraversal<object, ICollection<E2>>().Select<E2>(column);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the select step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Select<E2>(Pop pop, string selectKey)
        {
            return new GraphTraversal<object, E2>().Select<E2>(pop, selectKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the select step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<string, E2>> Select<E2>(Pop pop, string selectKey1, string selectKey2, params string[] otherSelectKeys)
        {
            return otherSelectKeys.Length == 0
                ? new GraphTraversal<object, IDictionary<string, E2>>().Select<E2>(pop, selectKey1, selectKey2)
                : new GraphTraversal<object, IDictionary<string, E2>>().Select<E2>(pop, selectKey1, selectKey2, otherSelectKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the select step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Select<E2>(Pop pop, ITraversal keyTraversal)
        {
            return new GraphTraversal<object, E2>().Select<E2>(pop, keyTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the select step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Select<E2>(string selectKey)
        {
            return new GraphTraversal<object, E2>().Select<E2>(selectKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the select step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<string, E2>> Select<E2>(string selectKey1, string selectKey2, params string[] otherSelectKeys)
        {
            return otherSelectKeys.Length == 0
                ? new GraphTraversal<object, IDictionary<string, E2>>().Select<E2>(selectKey1, selectKey2)
                : new GraphTraversal<object, IDictionary<string, E2>>().Select<E2>(selectKey1, selectKey2, otherSelectKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the select step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Select<E2>(ITraversal keyTraversal)
        {
            return new GraphTraversal<object, E2>().Select<E2>(keyTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the sideEffect step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> SideEffect(IConsumer consumer)
        {
            return new GraphTraversal<object, object>().SideEffect(consumer);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the sideEffect step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> SideEffect(ITraversal sideEffectTraversal)
        {
            return new GraphTraversal<object, object>().SideEffect(sideEffectTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the simplePath step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> SimplePath()
        {
            return new GraphTraversal<object, object>().SimplePath();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the skip step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Skip<E2>(Scope scope, long skip)
        {
            return new GraphTraversal<object, E2>().Skip<E2>(scope, skip);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the skip step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Skip<E2>(long skip)
        {
            return new GraphTraversal<object, E2>().Skip<E2>(skip);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the store step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Store(string sideEffectKey)
        {
            return new GraphTraversal<object, object>().Store(sideEffectKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the subgraph step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Edge> Subgraph(string sideEffectKey)
        {
            return new GraphTraversal<object, Edge>().Subgraph(sideEffectKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the sum step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Sum<E2>()
        {
            return new GraphTraversal<object, E2>().Sum<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the sum step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Sum<E2>(Scope scope)
        {
            return new GraphTraversal<object, E2>().Sum<E2>(scope);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the tail step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Tail<E2>()
        {
            return new GraphTraversal<object, E2>().Tail<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the tail step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Tail<E2>(Scope scope)
        {
            return new GraphTraversal<object, E2>().Tail<E2>(scope);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the tail step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Tail<E2>(Scope scope, long limit)
        {
            return new GraphTraversal<object, E2>().Tail<E2>(scope, limit);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the tail step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Tail<E2>(long limit)
        {
            return new GraphTraversal<object, E2>().Tail<E2>(limit);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the timeLimit step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> TimeLimit(long timeLimit)
        {
            return new GraphTraversal<object, object>().TimeLimit(timeLimit);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the times step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Times(int maxLoops)
        {
            return new GraphTraversal<object, object>().Times(maxLoops);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the to step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> To(Direction direction, params string[] edgeLabels)
        {
            return edgeLabels.Length == 0
                ? new GraphTraversal<object, Vertex>().To(direction)
                : new GraphTraversal<object, Vertex>().To(direction, edgeLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the toE step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Edge> ToE(Direction direction, params string[] edgeLabels)
        {
            return edgeLabels.Length == 0
                ? new GraphTraversal<object, Edge>().ToE(direction)
                : new GraphTraversal<object, Edge>().ToE(direction, edgeLabels);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the toV step to that traversal.
        /// </summary>
        public static GraphTraversal<object, Vertex> ToV(Direction direction)
        {
            return new GraphTraversal<object, Vertex>().ToV(direction);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the tree step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Tree<E2>()
        {
            return new GraphTraversal<object, E2>().Tree<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the tree step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Tree(string sideEffectKey)
        {
            return new GraphTraversal<object, object>().Tree(sideEffectKey);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the unfold step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Unfold<E2>()
        {
            return new GraphTraversal<object, E2>().Unfold<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the union step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Union<E2>(params ITraversal[] traversals)
        {
            return traversals.Length == 0
                ? new GraphTraversal<object, E2>().Union<E2>()
                : new GraphTraversal<object, E2>().Union<E2>(traversals);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the until step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Until(IPredicate untilPredicate)
        {
            return new GraphTraversal<object, object>().Until(untilPredicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the until step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Until(ITraversal untilTraversal)
        {
            return new GraphTraversal<object, object>().Until(untilTraversal);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the value step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Value<E2>()
        {
            return new GraphTraversal<object, E2>().Value<E2>();            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the valueMap step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<TKey, TValue>> ValueMap<TKey, TValue>(params string[] propertyKeys)
        {
            return propertyKeys.Length == 0
                ? new GraphTraversal<object, IDictionary<TKey, TValue>>().ValueMap<TKey, TValue>()
                : new GraphTraversal<object, IDictionary<TKey, TValue>>().ValueMap<TKey, TValue>(propertyKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the valueMap step to that traversal.
        /// </summary>
        public static GraphTraversal<object, IDictionary<TKey, TValue>> ValueMap<TKey, TValue>(bool includeTokens, params string[] propertyKeys)
        {
            return propertyKeys.Length == 0
                ? new GraphTraversal<object, IDictionary<TKey, TValue>>().ValueMap<TKey, TValue>(includeTokens)
                : new GraphTraversal<object, IDictionary<TKey, TValue>>().ValueMap<TKey, TValue>(includeTokens, propertyKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the values step to that traversal.
        /// </summary>
        public static GraphTraversal<object, E2> Values<E2>(params string[] propertyKeys)
        {
            return propertyKeys.Length == 0
                ? new GraphTraversal<object, E2>().Values<E2>()
                : new GraphTraversal<object, E2>().Values<E2>(propertyKeys);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the where step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Where(P predicate)
        {
            return new GraphTraversal<object, object>().Where(predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the where step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Where(string startKey, P predicate)
        {
            return new GraphTraversal<object, object>().Where(startKey, predicate);            
        }

        /// <summary>
        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the where step to that traversal.
        /// </summary>
        public static GraphTraversal<object, object> Where(ITraversal whereTraversal)
        {
            return new GraphTraversal<object, object>().Where(whereTraversal);            
        }

    }
}