// <snippet508>
        public async Task<LogOnResult> LogOnAsync(string userId, string password)
        {
            using (var handler = new HttpClientHandler { CookieContainer = new CookieContainer() })
            {
                using (var client = new HttpClient(handler))
                {
                    client.AddCurrentCultureHeader();
                    // Ask the server for a password challenge string
                    var requestId = GenerateRequestId();
                    var response1 = await client.GetAsync(_clientBaseUrl + "GetPasswordChallenge?requestId=" + requestId);
                    response1.EnsureSuccessStatusCode();
                    var challengeEncoded = await response1.Content.ReadAsAsync<string>();
                    var challengeBuffer = CryptographicBuffer.DecodeFromHexString(challengeEncoded);

                    // Use HMAC_SHA512 hash to encode the challenge string using the password being authenticated as the key.
                    var provider = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha512);
                    var passwordBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
                    var hmacKey = provider.CreateKey(passwordBuffer);
                    var buffHmac = CryptographicEngine.Sign(hmacKey, challengeBuffer);
                    var hmacString = CryptographicBuffer.EncodeToHexString(buffHmac);

                    // Send the encoded challenge to the server for authentication (to avoid sending the password itself)
                    var response = await client.GetAsync(_clientBaseUrl + userId + "?requestID=" + requestId +"&passwordHash=" + hmacString);

                    // Raise exception if sign in failed
                    response.EnsureSuccessStatusCode();

                    // On success, return sign in results from the server response packet
                    var result = await response.Content.ReadAsAsync<UserInfo>();
                    var serverUri = new Uri(Constants.ServerAddress);
                    return new LogOnResult { ServerCookieHeader = handler.CookieContainer.GetCookieHeader(serverUri), UserInfo = result };
                }
            }
        }
 public async Task DeleteShoppingCartAsync(string shoppingCartId)
 {
     using (var shoppingCartClient = new HttpClient())
     {
         shoppingCartClient.AddCurrentCultureHeader();
         var response = await shoppingCartClient.DeleteAsync(_shoppingCartBaseUrl + shoppingCartId);
         response.EnsureSuccessStatusCode();
     }
 }
 public async Task MergeShoppingCartsAsync(string oldShoppingCartId, string newShoppingCartId)
 {
     using (var shoppingCartClient = new HttpClient())
     {
         shoppingCartClient.AddCurrentCultureHeader();
         string requestUrl = _shoppingCartBaseUrl + newShoppingCartId + "?oldShoppingCartId=" + oldShoppingCartId;
         var response = await shoppingCartClient.PostAsync(requestUrl, null);
         response.EnsureSuccessStatusCode();
     }
 }
 public async Task RemoveShoppingCartItemAsync(string shoppingCartId, string itemIdToRemove)
 {
     using (var shoppingCartClient = new HttpClient())
     {
         shoppingCartClient.AddCurrentCultureHeader();
         string requestUrl = _shoppingCartBaseUrl + shoppingCartId + "?itemIdToRemove=" + itemIdToRemove;
         var response = await shoppingCartClient.PutAsync(requestUrl, null);
         response.EnsureSuccessStatusCode();
     }
 }
 public async Task RemoveProductFromShoppingCartAsync(string shoppingCartId, string productIdToDecrement)
 {
     using (var shoppingCartClient = new HttpClient())
     {
         shoppingCartClient.AddCurrentCultureHeader();
         string requestUrl = _shoppingCartBaseUrl + shoppingCartId + "?productIdToDecrement=" + productIdToDecrement;
         var response = await shoppingCartClient.PostAsync(requestUrl, null);
         response.EnsureSuccessStatusCode();
     }
 }
 public async Task<IReadOnlyCollection<string>> GetStatesAsync()
 {
     using (var client = new HttpClient())
     {
         client.AddCurrentCultureHeader();
         var response = await client.GetAsync(_clientBaseUrl);
         response.EnsureSuccessStatusCode();
         var result = await response.Content.ReadAsAsync<ReadOnlyCollection<string>>();
         return result;
     }
 }
        public async Task<ShoppingCart> GetShoppingCartAsync(string shoppingCartId)
        {
            using (var shoppingCartClient = new HttpClient())
            {
                shoppingCartClient.AddCurrentCultureHeader();
                var response = await shoppingCartClient.GetAsync(_shoppingCartBaseUrl + shoppingCartId);
                response.EnsureSuccessStatusCode();
                var result = await response.Content.ReadAsAsync<ShoppingCart>();

                return result;
            }
        }
        public async Task<Category> GetCategoryAsync(int categoryId)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.AddCurrentCultureHeader();
                var response = await httpClient.GetAsync(_categoriesBaseUrl + categoryId.ToString());
                response.EnsureSuccessStatusCode();
                var result = await response.Content.ReadAsAsync<Category>();

                return result;
            }
        }
        // </snippet513>

        public async Task<ReadOnlyCollection<Category>> GetFilteredProductsAsync(string productsQueryString)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.AddCurrentCultureHeader();
                var response = await httpClient.GetAsync(string.Format("{0}?productsQueryString={1}", _categoriesBaseUrl, productsQueryString));
                response.EnsureSuccessStatusCode();
                var result = await response.Content.ReadAsAsync<ReadOnlyCollection<Category>>();

                return result;
            }
        }
        // <snippet513>
        public async Task<ReadOnlyCollection<Category>> GetCategoriesAsync(int maxAmountOfProducts)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.AddCurrentCultureHeader();
                var response = await httpClient.GetAsync(string.Format("{0}?maxAmountOfProducts={1}", _categoriesBaseUrl, maxAmountOfProducts));
                response.EnsureSuccessStatusCode();
                var result = await response.Content.ReadAsAsync<ReadOnlyCollection<Category>>();

                return result;
            }
        }
        public async Task<ReadOnlyCollection<Product>> GetProductsAsync(int categoryId)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.AddCurrentCultureHeader();
                var response =
                    await httpClient.GetAsync(string.Format("{0}?categoryId={1}", _productsBaseUrl, categoryId));
                response.EnsureSuccessStatusCode();
                var result = await response.Content.ReadAsAsync<ReadOnlyCollection<Product>>();

                return result;
            }
        }
        // </snippet508>

        public async Task<bool> VerifyActiveSessionAsync(string userId, string serverCookieHeader)
        {
            using (var handler = new HttpClientHandler { CookieContainer = new CookieContainer() })
            {
                using (var client = new HttpClient(handler))
                {
                    client.AddCurrentCultureHeader();
                    var serverUri = new Uri(Constants.ServerAddress);
                    handler.CookieContainer.SetCookies(serverUri, serverCookieHeader);
                    var response = await client.GetAsync(_clientBaseUrl + "GetIsValidSession");
                    if (response.StatusCode == HttpStatusCode.Unauthorized)
                        throw new SecurityException();
                    response.EnsureSuccessStatusCode();
                    return await response.Content.ReadAsAsync<bool>();
                }
            }
        }
        public async Task ProcessOrderAsync(Order order, string serverCookieHeader)
        {
            using (HttpClientHandler handler = new HttpClientHandler { CookieContainer = new CookieContainer() })
            {
                using (var orderClient = new HttpClient(handler))
                {
                    orderClient.AddCurrentCultureHeader();
                    Uri serverUri = new Uri(Constants.ServerAddress);
                    handler.CookieContainer.SetCookies(serverUri, serverCookieHeader);
                    orderClient.DefaultRequestHeaders.Add("Accept", "application/json");

                    string requestUrl = _clientBaseUrl + order.Id;
                    var response = await orderClient.PutAsJsonAsync<Order>(requestUrl, order);
                    await response.EnsureSuccessWithValidationSupportAsync();
                }
            }
        }
        public async Task<Product> GetProductAsync(string productNumber)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.AddCurrentCultureHeader();
                var response = await httpClient.GetAsync(_productsBaseUrl + productNumber);
                response.EnsureSuccessStatusCode();
                var result = await response.Content.ReadAsAsync<Product>();

                return result;
            }
        }