private async Task CreateParameterPassingTest(bool useTypedTable)
        {
            Log("### Parameter passing test - " + (useTypedTable ? "typed" : "untyped") + " tables");

            var client = this.GetClient();
            var typed = client.GetTable<ParamsTestTableItem>();
            var untyped = client.GetTable("ParamsTestTable");
            var dict = new Dictionary<string, string>
                {
                    { "item", "simple" },
                    { "empty", "" },
                    { "spaces", "with spaces" },
                    { "specialChars", "`!@#$%^&*()-=[]\\;',./~_+{}|:\"<>?" },
                    { "latin", "ãéìôü ÇñÑ" },
                    { "arabic", "الكتاب على الطاولة" },
                    { "chinese", "这本书在桌子上" },
                    { "japanese", "本は机の上に" },
                    { "hebrew", "הספר הוא על השולחן" },
                    { "name+with special&chars", "should just work" }
                };

            var expectedParameters = new JObject();
            foreach (var key in dict.Keys)
            {
                expectedParameters.Add(key, dict[key]);
            }

            bool testPassed = true;

            ParamsTestTableItem typedItem = new ParamsTestTableItem();
            var untypedItem = new JObject();
            JObject actualParameters;

            dict["operation"] = "insert";
            expectedParameters.Add("operation", "insert");
            if (useTypedTable)
            {
                await typed.InsertAsync(typedItem, dict);
                actualParameters = JObject.Parse(typedItem.parameters);
            }
            else
            {
                var inserted = await untyped.InsertAsync(untypedItem, dict);
                untypedItem = inserted as JObject;
                actualParameters = JObject.Parse(untypedItem["parameters"].Value<string>());
            }

            testPassed = testPassed && ValidateParameters("insert", expectedParameters, actualParameters);

            dict["operation"] = "update";
            expectedParameters["operation"] = "update";
            if (useTypedTable)
            {
                await typed.UpdateAsync(typedItem, dict);
                actualParameters = JObject.Parse(typedItem.parameters);
            }
            else
            {
                var updated = await untyped.UpdateAsync(untypedItem, dict);
                actualParameters = JObject.Parse(updated["parameters"].Value<string>());
            }

            testPassed = testPassed && ValidateParameters("update", expectedParameters, actualParameters);

            dict["operation"] = "lookup";
            expectedParameters["operation"] = "lookup";
            if (useTypedTable)
            {
                var temp = await typed.LookupAsync(1, dict);
                actualParameters = JObject.Parse(temp.parameters);
            }
            else
            {
                var temp = await untyped.LookupAsync(1, dict);
                actualParameters = JObject.Parse(temp["parameters"].Value<string>());
            }

            testPassed = testPassed && ValidateParameters("lookup", expectedParameters, actualParameters);

            dict["operation"] = "read";
            expectedParameters["operation"] = "read";
            if (useTypedTable)
            {
                var temp = await typed.Where(t => t.Id >= 1).WithParameters(dict).ToListAsync();
                actualParameters = JObject.Parse(temp[0].parameters);
            }
            else
            {
                var temp = await untyped.ReadAsync("$filter=id ge 1", dict);
                actualParameters = JObject.Parse(temp[0]["parameters"].Value<string>());
            }

            testPassed = testPassed && ValidateParameters("read", expectedParameters, actualParameters);

            if (useTypedTable)
            {
                // Refresh operation only exists for typed tables
                dict["operation"] = "read";
                expectedParameters["operation"] = "read";
                typedItem.Id = 1;
                typedItem.parameters = "";
                await typed.RefreshAsync(typedItem, dict);
                actualParameters = JObject.Parse(typedItem.parameters);
                testPassed = testPassed && ValidateParameters("refresh", expectedParameters, actualParameters);
            }

            // Delete operation doesn't populate the object with the response, so we'll use a filter to capture that
            var handler = new HandlerToCaptureHttpTraffic();
            var filteredClient = new MobileServiceClient(client.MobileAppUri, handler);
            typed = filteredClient.GetTable<ParamsTestTableItem>();
            untyped = filteredClient.GetTable("ParamsTestTable");

            dict["operation"] = "delete";
            expectedParameters["operation"] = "delete";
            if (useTypedTable)
            {
                await typed.DeleteAsync(typedItem, dict);
            }
            else
            {
                await untyped.DeleteAsync(untypedItem, dict);
            }

            JObject response = JObject.Parse(handler.ResponseBody);
            actualParameters = JObject.Parse(response["parameters"].Value<string>());

            testPassed = testPassed && ValidateParameters("delete", expectedParameters, actualParameters);

            if (!testPassed)
            {
                Assert.Fail("");
            }
        }
        private async Task CreateParameterPassingTest(bool useTypedTable)
        {
            Log("### Parameter passing test - " + (useTypedTable ? "typed" : "untyped") + " tables");

            var client  = this.GetClient();
            var typed   = client.GetTable <ParamsTestTableItem>();
            var untyped = client.GetTable("ParamsTestTable");
            var dict    = new Dictionary <string, string>
            {
                { "item", "simple" },
                { "empty", "" },
                { "spaces", "with spaces" },
                { "specialChars", "`!@#$%^&*()-=[]\\;',./~_+{}|:\"<>?" },
                { "latin", "ãéìôü ÇñÑ" },
                { "arabic", "الكتاب على الطاولة" },
                { "chinese", "这本书在桌子上" },
                { "japanese", "本は机の上に" },
                { "hebrew", "הספר הוא על השולחן" },
                { "name+with special&chars", "should just work" }
            };

            var expectedParameters = new JObject();

            foreach (var key in dict.Keys)
            {
                expectedParameters.Add(key, dict[key]);
            }

            bool testPassed = true;

            ParamsTestTableItem typedItem = new ParamsTestTableItem();
            var     untypedItem           = new JObject();
            JObject actualParameters;

            dict["operation"] = "insert";
            expectedParameters.Add("operation", "insert");
            if (useTypedTable)
            {
                await typed.InsertAsync(typedItem, dict);

                actualParameters = JObject.Parse(typedItem.parameters);
            }
            else
            {
                var inserted = await untyped.InsertAsync(untypedItem, dict);

                untypedItem      = inserted as JObject;
                actualParameters = JObject.Parse(untypedItem["parameters"].Value <string>());
            }

            testPassed = testPassed && ValidateParameters("insert", expectedParameters, actualParameters);

            dict["operation"] = "update";
            expectedParameters["operation"] = "update";
            if (useTypedTable)
            {
                await typed.UpdateAsync(typedItem, dict);

                actualParameters = JObject.Parse(typedItem.parameters);
            }
            else
            {
                var updated = await untyped.UpdateAsync(untypedItem, dict);

                actualParameters = JObject.Parse(updated["parameters"].Value <string>());
            }

            testPassed = testPassed && ValidateParameters("update", expectedParameters, actualParameters);

            dict["operation"] = "lookup";
            expectedParameters["operation"] = "lookup";
            if (useTypedTable)
            {
                var temp = await typed.LookupAsync(1, dict);

                actualParameters = JObject.Parse(temp.parameters);
            }
            else
            {
                var temp = await untyped.LookupAsync(1, dict);

                actualParameters = JObject.Parse(temp["parameters"].Value <string>());
            }

            testPassed = testPassed && ValidateParameters("lookup", expectedParameters, actualParameters);

            dict["operation"] = "read";
            expectedParameters["operation"] = "read";
            if (useTypedTable)
            {
                var temp = await typed.Where(t => t.Id >= 1).WithParameters(dict).ToListAsync();

                actualParameters = JObject.Parse(temp[0].parameters);
            }
            else
            {
                var temp = await untyped.ReadAsync("$filter=id ge 1", dict);

                actualParameters = JObject.Parse(temp[0]["parameters"].Value <string>());
            }

            testPassed = testPassed && ValidateParameters("read", expectedParameters, actualParameters);

            if (useTypedTable)
            {
                // Refresh operation only exists for typed tables
                dict["operation"] = "read";
                expectedParameters["operation"] = "read";
                typedItem.Id         = 1;
                typedItem.parameters = "";
                await typed.RefreshAsync(typedItem, dict);

                actualParameters = JObject.Parse(typedItem.parameters);
                testPassed       = testPassed && ValidateParameters("refresh", expectedParameters, actualParameters);
            }

            // Delete operation doesn't populate the object with the response, so we'll use a filter to capture that
            var handler        = new HandlerToCaptureHttpTraffic();
            var filteredClient = new MobileServiceClient(client.ApplicationUri, client.ApplicationKey, handler);

            typed   = filteredClient.GetTable <ParamsTestTableItem>();
            untyped = filteredClient.GetTable("ParamsTestTable");

            dict["operation"] = "delete";
            expectedParameters["operation"] = "delete";
            if (useTypedTable)
            {
                await typed.DeleteAsync(typedItem, dict);
            }
            else
            {
                await untyped.DeleteAsync(untypedItem, dict);
            }

            JObject response = JObject.Parse(handler.ResponseBody);

            actualParameters = JObject.Parse(response["parameters"].Value <string>());

            testPassed = testPassed && ValidateParameters("delete", expectedParameters, actualParameters);

            if (!testPassed)
            {
                Assert.Fail("");
            }
        }