/// <summary>
        /// Execute a SQL statement against the graph database.
        /// Forward the request to the SQL Client with a JObject type and then convert the resulting graphson documents into our entity using the serialization helper.
        /// </summary>
        /// <param name="query">Query to execute</param>
        /// <param name="pagedResults">true to return only one page of the result set, false(Default) to return all results. </param>
        /// <param name="continuationToken">token to pass into the query iterator to resume from a specific page. Should be present when using pageResults = true</param>
        /// <param name="cancellationToken">cancellatinToken used to cancel an operation in progress.</param>
        /// <returns><see cref="CosmosResponse"/> that encapsulates the result of the query and tracks success status along with various performance parameters.</returns>
        public async Task <CosmosResponse <IEnumerable <T> > > ExecuteSQL <T>(string query, bool pagedResults = false, string continuationToken = "", CancellationToken cancellationToken = default(CancellationToken))
        {
            EnsureCosmosSqlClient();
            if (CosmosEntitySerializer.IsTypeDirectlySerializableToGraph(typeof(T)))
            {
                return(await CosmosSqlClient.ExecuteSQL <T>(query, pagedResults, continuationToken, cancellationToken));
            }

            var res = await CosmosSqlClient.ExecuteSQL <JObject>(query, pagedResults, continuationToken, cancellationToken);

            var cosmosResult = res.Clone <IEnumerable <T> >();

            if (typeof(T) == typeof(JObject) || typeof(T) == typeof(object))
            {
                return(cosmosResult);
            }

            if (!res.IsSuccessful)
            {
                return(cosmosResult);
            }

            cosmosResult.Result = res.Result.Select(CosmosSerializer.FromGraphson <T>).ToArray();

            return(cosmosResult);
        }
        /// <summary>
        /// Executes a Gremlin traversal.
        /// When the type of the result is unknown (using steps like tree() or path(), send T as JObject and manually deserialize
        /// </summary>
        /// <typeparam name="T">Type to convert the results to</typeparam>
        /// <param name="queryString">Gremlin traversal</param>
        /// <param name="bindings">[Optional] Collection of parameters and their values to be sent to the gremlin server along with the query.</param>
        /// <example>
        /// <![CDATA[
        /// await cosmosGraphClient.ExecuteGremlin<Movie>("g.V().hasLabel('Movie').has('Language', 'en').has('Budget', gt(1000000))");
        /// await cosmosGraphClient.ExecuteGremlin<Movie>("g.V().hasLabel('Movie').has('Language',lang).has('Budget',gt(budget))", new Dictionary<string, object> { { "lang", "en" }, { "budget", 1000000 } });
        /// ]]>
        /// </example>
        /// <returns>CosmosResponse wrapped Array of results.</returns>
        public async Task <CosmosResponse <IEnumerable <T> > > ExecuteGremlin <T>(string queryString, Dictionary <string, object> bindings = null)
        {
            try
            {
                using (var gremlinClient = GetGremlinClient())
                {
                    var start       = DateTime.Now;
                    var graphResult = await gremlinClient.SubmitAsync <dynamic>(queryString, bindings);

                    var graphResultString = JsonConvert.SerializeObject(graphResult);

                    var res = new CosmosResponse <IEnumerable <T> >
                    {
                        StatusCode    = System.Net.HttpStatusCode.OK,
                        RequestCharge = Helpers.GetValueOrDefault <double>(graphResult.StatusAttributes, RESULTSET_ATTRIBUTE_RU),
                        ExecutionTime = DateTime.Now.Subtract(start)
                    };

                    if (CosmosEntitySerializer.IsTypeDirectlySerializableToGraph(typeof(T)))
                    {
                        res.Result = JsonConvert.DeserializeObject <IEnumerable <T> >(graphResultString).ToArray();
                    }
                    else
                    {
                        var graphResultJObject = JsonConvert.DeserializeObject <IEnumerable <JObject> >(graphResultString).ToArray();
                        res.Result = (typeof(T) == typeof(JObject) || typeof(T) == typeof(object))
                                        ? graphResultJObject.Cast <T>()
                                        : graphResultJObject.Select(CosmosSerializer.FromGraphson <T>).ToArray();
                    }

                    return(res);
                }
            }
            catch (ResponseException e)
            {
                return(new CosmosResponse <IEnumerable <T> >
                {
                    Result = null,
                    Error = e,
                    RequestCharge = Helpers.GetValueOrDefault <double>(e.StatusAttributes, RESULTSET_ATTRIBUTE_RU),
                    RetryAfter = TimeSpan.FromMilliseconds(Helpers.GetValueOrDefault <int>(e.StatusAttributes, RESULTSET_ATTRIBUTE_RETRYAFTER)),
                    ActivityId = Helpers.GetValueOrDefault <string>(e.StatusAttributes, RESULTSET_ATTRIBUTE_ACTIVITYID),
                });
            }
            catch (Exception e)
            {
                return(new CosmosResponse <IEnumerable <T> >
                {
                    Result = null,
                    Error = e,
                    RequestCharge = -1
                });
            }
        }