private IList <Task <IDictionary <string, object> > > ExecuteBatchRequest(IList <object> requests,
                                                                                  string sessionToken,
                                                                                  CancellationToken cancellationToken)
        {
            var tasks     = new List <Task <IDictionary <string, object> > >();
            int batchSize = requests.Count;
            var tcss      = new List <TaskCompletionSource <IDictionary <string, object> > >();

            for (int i = 0; i < batchSize; ++i)
            {
                var tcs = new TaskCompletionSource <IDictionary <string, object> >();
                tcss.Add(tcs);
                tasks.Add(tcs.Task);
            }

            var command = new AVCommand("/batch",
                                        method: "POST",
                                        sessionToken: sessionToken,
                                        data: new Dictionary <string, object> {
                { "requests", requests }
            });

            commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).ContinueWith(t => {
                if (t.IsFaulted || t.IsCanceled)
                {
                    foreach (var tcs in tcss)
                    {
                        if (t.IsFaulted)
                        {
                            tcs.TrySetException(t.Exception);
                        }
                        else if (t.IsCanceled)
                        {
                            tcs.TrySetCanceled();
                        }
                    }
                    return;
                }

                var resultsArray = AVClient.As <IList <object> >(t.Result.Item2["results"]);
                int resultLength = resultsArray.Count;
                if (resultLength != batchSize)
                {
                    foreach (var tcs in tcss)
                    {
                        tcs.TrySetException(new InvalidOperationException(
                                                "Batch command result count expected: " + batchSize + " but was: " + resultLength + "."));
                    }
                    return;
                }

                for (int i = 0; i < batchSize; ++i)
                {
                    var result = resultsArray[i] as Dictionary <string, object>;
                    var tcs    = tcss[i];

                    if (result.ContainsKey("success"))
                    {
                        tcs.TrySetResult(result["success"] as IDictionary <string, object>);
                    }
                    else if (result.ContainsKey("error"))
                    {
                        var error      = result["error"] as IDictionary <string, object>;
                        long errorCode = (long)error["code"];
                        tcs.TrySetException(new AVException((AVException.ErrorCode)errorCode, error["error"] as string));
                    }
                    else
                    {
                        tcs.TrySetException(new InvalidOperationException(
                                                "Invalid batch command response."));
                    }
                }
            });

            return(tasks);
        }