com.microsoft.azure.management.storage.StorageAccountOperationsImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.microsoft.azure.management.storage.StorageAccountOperationsImpl.java

Source

/**
 * 
 * Copyright (c) Microsoft and contributors.  All rights reserved.
 * 
 * Licensed 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.
 * 
 */

// Warning: This code was generated by a tool.
// 
// Changes to this file may cause incorrect behavior and will be lost if the
// code is regenerated.

package com.microsoft.azure.management.storage;

import com.microsoft.azure.management.storage.models.AccountStatus;
import com.microsoft.azure.management.storage.models.AccountType;
import com.microsoft.azure.management.storage.models.CheckNameAvailabilityResponse;
import com.microsoft.azure.management.storage.models.CustomDomain;
import com.microsoft.azure.management.storage.models.Endpoints;
import com.microsoft.azure.management.storage.models.ProvisioningState;
import com.microsoft.azure.management.storage.models.Reason;
import com.microsoft.azure.management.storage.models.StorageAccount;
import com.microsoft.azure.management.storage.models.StorageAccountCreateParameters;
import com.microsoft.azure.management.storage.models.StorageAccountCreateResponse;
import com.microsoft.azure.management.storage.models.StorageAccountGetPropertiesResponse;
import com.microsoft.azure.management.storage.models.StorageAccountKeys;
import com.microsoft.azure.management.storage.models.StorageAccountListKeysResponse;
import com.microsoft.azure.management.storage.models.StorageAccountListResponse;
import com.microsoft.azure.management.storage.models.StorageAccountRegenerateKeyResponse;
import com.microsoft.azure.management.storage.models.StorageAccountUpdateParameters;
import com.microsoft.azure.management.storage.models.StorageAccountUpdateResponse;
import com.microsoft.windowsazure.core.LazyCollection;
import com.microsoft.windowsazure.core.OperationResponse;
import com.microsoft.windowsazure.core.OperationStatus;
import com.microsoft.windowsazure.core.ServiceOperations;
import com.microsoft.windowsazure.core.pipeline.apache.CustomHttpDelete;
import com.microsoft.windowsazure.core.utils.CollectionStringBuilder;
import com.microsoft.windowsazure.core.utils.EnumUtility;
import com.microsoft.windowsazure.exception.ServiceException;
import com.microsoft.windowsazure.tracing.ClientRequestTrackingHandler;
import com.microsoft.windowsazure.tracing.CloudTracing;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.NullNode;
import org.codehaus.jackson.node.ObjectNode;

/**
* Operations for managing storage accounts.
*/
public class StorageAccountOperationsImpl
        implements ServiceOperations<StorageManagementClientImpl>, StorageAccountOperations {
    /**
    * Initializes a new instance of the StorageAccountOperationsImpl class.
    *
    * @param client Reference to the service client.
    */
    StorageAccountOperationsImpl(StorageManagementClientImpl client) {
        this.client = client;
    }

    private StorageManagementClientImpl client;

    /**
    * Gets a reference to the
    * microsoft.azure.management.storage.StorageManagementClientImpl.
    * @return The Client value.
    */
    public StorageManagementClientImpl getClient() {
        return this.client;
    }

    /**
    * Asynchronously creates a new storage account with the specified
    * parameters. Existing accounts cannot be updated with this API and should
    * instead use the Update Storage Account API. If an account is already
    * created and subsequent PUT request is issued with exact same set of
    * properties, then HTTP 200 would be returned.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @param parameters Required. The parameters to provide for the created
    * account.
    * @return The Create storage account operation response.
    */
    @Override
    public Future<StorageAccountCreateResponse> beginCreateAsync(final String resourceGroupName,
            final String accountName, final StorageAccountCreateParameters parameters) {
        return this.getClient().getExecutorService().submit(new Callable<StorageAccountCreateResponse>() {
            @Override
            public StorageAccountCreateResponse call() throws Exception {
                return beginCreate(resourceGroupName, accountName, parameters);
            }
        });
    }

    /**
    * Asynchronously creates a new storage account with the specified
    * parameters. Existing accounts cannot be updated with this API and should
    * instead use the Update Storage Account API. If an account is already
    * created and subsequent PUT request is issued with exact same set of
    * properties, then HTTP 200 would be returned.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @param parameters Required. The parameters to provide for the created
    * account.
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @throws URISyntaxException Thrown if there was an error parsing a URI in
    * the response.
    * @return The Create storage account operation response.
    */
    @Override
    public StorageAccountCreateResponse beginCreate(String resourceGroupName, String accountName,
            StorageAccountCreateParameters parameters) throws IOException, ServiceException, URISyntaxException {
        // Validate
        if (resourceGroupName == null) {
            throw new NullPointerException("resourceGroupName");
        }
        if (accountName == null) {
            throw new NullPointerException("accountName");
        }
        if (accountName.length() < 3) {
            throw new IllegalArgumentException("accountName");
        }
        if (accountName.length() > 24) {
            throw new IllegalArgumentException("accountName");
        }
        for (char accountNameChar : accountName.toCharArray()) {
            if (Character.isLowerCase(accountNameChar) == false && Character.isDigit(accountNameChar) == false) {
                throw new IllegalArgumentException("accountName");
            }
        }
        if (parameters == null) {
            throw new NullPointerException("parameters");
        }
        if (parameters.getAccountType() == null) {
            throw new NullPointerException("parameters.AccountType");
        }
        if (parameters.getLocation() == null) {
            throw new NullPointerException("parameters.Location");
        }

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("resourceGroupName", resourceGroupName);
            tracingParameters.put("accountName", accountName);
            tracingParameters.put("parameters", parameters);
            CloudTracing.enter(invocationId, this, "beginCreateAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/resourceGroups/";
        url = url + URLEncoder.encode(resourceGroupName, "UTF-8");
        url = url + "/providers/Microsoft.Storage/storageAccounts/";
        url = url + URLEncoder.encode(accountName, "UTF-8");
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        HttpPut httpRequest = new HttpPut(url);

        // Set Headers
        httpRequest.setHeader("Content-Type", "application/json");
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Serialize Request
        String requestContent = null;
        JsonNode requestDoc = null;

        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode storageAccountCreateParametersJsonValue = objectMapper.createObjectNode();
        requestDoc = storageAccountCreateParametersJsonValue;

        ((ObjectNode) storageAccountCreateParametersJsonValue).put("location", parameters.getLocation());

        if (parameters.getTags() != null) {
            if (parameters.getTags() instanceof LazyCollection == false
                    || ((LazyCollection) parameters.getTags()).isInitialized()) {
                ObjectNode tagsDictionary = objectMapper.createObjectNode();
                for (Map.Entry<String, String> entry : parameters.getTags().entrySet()) {
                    String tagsKey = entry.getKey();
                    String tagsValue = entry.getValue();
                    ((ObjectNode) tagsDictionary).put(tagsKey, tagsValue);
                }
                ((ObjectNode) storageAccountCreateParametersJsonValue).put("tags", tagsDictionary);
            }
        }

        ObjectNode propertiesValue = objectMapper.createObjectNode();
        ((ObjectNode) storageAccountCreateParametersJsonValue).put("properties", propertiesValue);

        ((ObjectNode) propertiesValue).put("accountType",
                StorageManagementClientImpl.accountTypeToString(parameters.getAccountType()));

        StringWriter stringWriter = new StringWriter();
        objectMapper.writeValue(stringWriter, requestDoc);
        requestContent = stringWriter.toString();
        StringEntity entity = new StringEntity(requestContent);
        httpRequest.setEntity(entity);
        httpRequest.setHeader("Content-Type", "application/json");

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_ACCEPTED) {
                ServiceException ex = ServiceException.createFromJson(httpRequest, requestContent, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            StorageAccountCreateResponse result = null;
            // Deserialize Response
            if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_ACCEPTED) {
                InputStream responseContent = httpResponse.getEntity().getContent();
                result = new StorageAccountCreateResponse();
                JsonNode responseDoc = null;
                String responseDocContent = IOUtils.toString(responseContent);
                if (responseDocContent == null == false && responseDocContent.length() > 0) {
                    responseDoc = objectMapper.readTree(responseDocContent);
                }

                if (responseDoc != null && responseDoc instanceof NullNode == false) {
                    StorageAccount storageAccountInstance = new StorageAccount();
                    result.setStorageAccount(storageAccountInstance);

                    JsonNode idValue = responseDoc.get("id");
                    if (idValue != null && idValue instanceof NullNode == false) {
                        String idInstance;
                        idInstance = idValue.getTextValue();
                        storageAccountInstance.setId(idInstance);
                    }

                    JsonNode nameValue = responseDoc.get("name");
                    if (nameValue != null && nameValue instanceof NullNode == false) {
                        String nameInstance;
                        nameInstance = nameValue.getTextValue();
                        storageAccountInstance.setName(nameInstance);
                    }

                    JsonNode typeValue = responseDoc.get("type");
                    if (typeValue != null && typeValue instanceof NullNode == false) {
                        String typeInstance;
                        typeInstance = typeValue.getTextValue();
                        storageAccountInstance.setType(typeInstance);
                    }

                    JsonNode locationValue = responseDoc.get("location");
                    if (locationValue != null && locationValue instanceof NullNode == false) {
                        String locationInstance;
                        locationInstance = locationValue.getTextValue();
                        storageAccountInstance.setLocation(locationInstance);
                    }

                    JsonNode tagsSequenceElement = ((JsonNode) responseDoc.get("tags"));
                    if (tagsSequenceElement != null && tagsSequenceElement instanceof NullNode == false) {
                        Iterator<Map.Entry<String, JsonNode>> itr = tagsSequenceElement.getFields();
                        while (itr.hasNext()) {
                            Map.Entry<String, JsonNode> property = itr.next();
                            String tagsKey2 = property.getKey();
                            String tagsValue2 = property.getValue().getTextValue();
                            storageAccountInstance.getTags().put(tagsKey2, tagsValue2);
                        }
                    }

                    JsonNode propertiesValue2 = responseDoc.get("properties");
                    if (propertiesValue2 != null && propertiesValue2 instanceof NullNode == false) {
                        JsonNode provisioningStateValue = propertiesValue2.get("provisioningState");
                        if (provisioningStateValue != null && provisioningStateValue instanceof NullNode == false) {
                            ProvisioningState provisioningStateInstance;
                            provisioningStateInstance = EnumUtility.fromString(ProvisioningState.class,
                                    provisioningStateValue.getTextValue());
                            storageAccountInstance.setProvisioningState(provisioningStateInstance);
                        }

                        JsonNode accountTypeValue = propertiesValue2.get("accountType");
                        if (accountTypeValue != null && accountTypeValue instanceof NullNode == false) {
                            AccountType accountTypeInstance;
                            accountTypeInstance = StorageManagementClientImpl
                                    .parseAccountType(accountTypeValue.getTextValue());
                            storageAccountInstance.setAccountType(accountTypeInstance);
                        }

                        JsonNode primaryEndpointsValue = propertiesValue2.get("primaryEndpoints");
                        if (primaryEndpointsValue != null && primaryEndpointsValue instanceof NullNode == false) {
                            Endpoints primaryEndpointsInstance = new Endpoints();
                            storageAccountInstance.setPrimaryEndpoints(primaryEndpointsInstance);

                            JsonNode blobValue = primaryEndpointsValue.get("blob");
                            if (blobValue != null && blobValue instanceof NullNode == false) {
                                URI blobInstance;
                                blobInstance = new URI(blobValue.getTextValue());
                                primaryEndpointsInstance.setBlob(blobInstance);
                            }

                            JsonNode queueValue = primaryEndpointsValue.get("queue");
                            if (queueValue != null && queueValue instanceof NullNode == false) {
                                URI queueInstance;
                                queueInstance = new URI(queueValue.getTextValue());
                                primaryEndpointsInstance.setQueue(queueInstance);
                            }

                            JsonNode tableValue = primaryEndpointsValue.get("table");
                            if (tableValue != null && tableValue instanceof NullNode == false) {
                                URI tableInstance;
                                tableInstance = new URI(tableValue.getTextValue());
                                primaryEndpointsInstance.setTable(tableInstance);
                            }

                            JsonNode fileValue = primaryEndpointsValue.get("file");
                            if (fileValue != null && fileValue instanceof NullNode == false) {
                                URI fileInstance;
                                fileInstance = new URI(fileValue.getTextValue());
                                primaryEndpointsInstance.setFile(fileInstance);
                            }
                        }

                        JsonNode primaryLocationValue = propertiesValue2.get("primaryLocation");
                        if (primaryLocationValue != null && primaryLocationValue instanceof NullNode == false) {
                            String primaryLocationInstance;
                            primaryLocationInstance = primaryLocationValue.getTextValue();
                            storageAccountInstance.setPrimaryLocation(primaryLocationInstance);
                        }

                        JsonNode statusOfPrimaryValue = propertiesValue2.get("statusOfPrimary");
                        if (statusOfPrimaryValue != null && statusOfPrimaryValue instanceof NullNode == false) {
                            AccountStatus statusOfPrimaryInstance;
                            statusOfPrimaryInstance = EnumUtility.fromString(AccountStatus.class,
                                    statusOfPrimaryValue.getTextValue());
                            storageAccountInstance.setStatusOfPrimary(statusOfPrimaryInstance);
                        }

                        JsonNode lastGeoFailoverTimeValue = propertiesValue2.get("lastGeoFailoverTime");
                        if (lastGeoFailoverTimeValue != null
                                && lastGeoFailoverTimeValue instanceof NullNode == false) {
                            Calendar lastGeoFailoverTimeInstance;
                            lastGeoFailoverTimeInstance = DatatypeConverter
                                    .parseDateTime(lastGeoFailoverTimeValue.getTextValue());
                            storageAccountInstance.setLastGeoFailoverTime(lastGeoFailoverTimeInstance);
                        }

                        JsonNode secondaryLocationValue = propertiesValue2.get("secondaryLocation");
                        if (secondaryLocationValue != null && secondaryLocationValue instanceof NullNode == false) {
                            String secondaryLocationInstance;
                            secondaryLocationInstance = secondaryLocationValue.getTextValue();
                            storageAccountInstance.setSecondaryLocation(secondaryLocationInstance);
                        }

                        JsonNode statusOfSecondaryValue = propertiesValue2.get("statusOfSecondary");
                        if (statusOfSecondaryValue != null && statusOfSecondaryValue instanceof NullNode == false) {
                            AccountStatus statusOfSecondaryInstance;
                            statusOfSecondaryInstance = EnumUtility.fromString(AccountStatus.class,
                                    statusOfSecondaryValue.getTextValue());
                            storageAccountInstance.setStatusOfSecondary(statusOfSecondaryInstance);
                        }

                        JsonNode creationTimeValue = propertiesValue2.get("creationTime");
                        if (creationTimeValue != null && creationTimeValue instanceof NullNode == false) {
                            Calendar creationTimeInstance;
                            creationTimeInstance = DatatypeConverter
                                    .parseDateTime(creationTimeValue.getTextValue());
                            storageAccountInstance.setCreationTime(creationTimeInstance);
                        }

                        JsonNode customDomainValue = propertiesValue2.get("customDomain");
                        if (customDomainValue != null && customDomainValue instanceof NullNode == false) {
                            CustomDomain customDomainInstance = new CustomDomain();
                            storageAccountInstance.setCustomDomain(customDomainInstance);

                            JsonNode nameValue2 = customDomainValue.get("name");
                            if (nameValue2 != null && nameValue2 instanceof NullNode == false) {
                                String nameInstance2;
                                nameInstance2 = nameValue2.getTextValue();
                                customDomainInstance.setName(nameInstance2);
                            }

                            JsonNode useSubDomainValue = customDomainValue.get("useSubDomain");
                            if (useSubDomainValue != null && useSubDomainValue instanceof NullNode == false) {
                                boolean useSubDomainInstance;
                                useSubDomainInstance = useSubDomainValue.getBooleanValue();
                                customDomainInstance.setUseSubDomain(useSubDomainInstance);
                            }
                        }

                        JsonNode secondaryEndpointsValue = propertiesValue2.get("secondaryEndpoints");
                        if (secondaryEndpointsValue != null
                                && secondaryEndpointsValue instanceof NullNode == false) {
                            Endpoints secondaryEndpointsInstance = new Endpoints();
                            storageAccountInstance.setSecondaryEndpoints(secondaryEndpointsInstance);

                            JsonNode blobValue2 = secondaryEndpointsValue.get("blob");
                            if (blobValue2 != null && blobValue2 instanceof NullNode == false) {
                                URI blobInstance2;
                                blobInstance2 = new URI(blobValue2.getTextValue());
                                secondaryEndpointsInstance.setBlob(blobInstance2);
                            }

                            JsonNode queueValue2 = secondaryEndpointsValue.get("queue");
                            if (queueValue2 != null && queueValue2 instanceof NullNode == false) {
                                URI queueInstance2;
                                queueInstance2 = new URI(queueValue2.getTextValue());
                                secondaryEndpointsInstance.setQueue(queueInstance2);
                            }

                            JsonNode tableValue2 = secondaryEndpointsValue.get("table");
                            if (tableValue2 != null && tableValue2 instanceof NullNode == false) {
                                URI tableInstance2;
                                tableInstance2 = new URI(tableValue2.getTextValue());
                                secondaryEndpointsInstance.setTable(tableInstance2);
                            }

                            JsonNode fileValue2 = secondaryEndpointsValue.get("file");
                            if (fileValue2 != null && fileValue2 instanceof NullNode == false) {
                                URI fileInstance2;
                                fileInstance2 = new URI(fileValue2.getTextValue());
                                secondaryEndpointsInstance.setFile(fileInstance2);
                            }
                        }
                    }
                }

            }
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("Location").length > 0) {
                result.setOperationStatusLink(httpResponse.getFirstHeader("Location").getValue());
            }
            if (httpResponse.getHeaders("Retry-After").length > 0) {
                result.setRetryAfter(
                        DatatypeConverter.parseInt(httpResponse.getFirstHeader("Retry-After").getValue()));
            }
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }
            if (statusCode == HttpStatus.SC_CONFLICT || statusCode == HttpStatus.SC_BAD_REQUEST) {
                result.setStatus(OperationStatus.Failed);
            }
            if (statusCode == HttpStatus.SC_OK) {
                result.setStatus(OperationStatus.Succeeded);
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }

    /**
    * Checks that account name is valid and is not in use.
    *
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @return The CheckNameAvailability operation response.
    */
    @Override
    public Future<CheckNameAvailabilityResponse> checkNameAvailabilityAsync(final String accountName) {
        return this.getClient().getExecutorService().submit(new Callable<CheckNameAvailabilityResponse>() {
            @Override
            public CheckNameAvailabilityResponse call() throws Exception {
                return checkNameAvailability(accountName);
            }
        });
    }

    /**
    * Checks that account name is valid and is not in use.
    *
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @return The CheckNameAvailability operation response.
    */
    @Override
    public CheckNameAvailabilityResponse checkNameAvailability(String accountName)
            throws IOException, ServiceException {
        // Validate
        if (accountName == null) {
            throw new NullPointerException("accountName");
        }

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("accountName", accountName);
            CloudTracing.enter(invocationId, this, "checkNameAvailabilityAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/providers/Microsoft.Storage/checkNameAvailability";
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        HttpPost httpRequest = new HttpPost(url);

        // Set Headers
        httpRequest.setHeader("Content-Type", "application/json");
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Serialize Request
        String requestContent = null;
        JsonNode requestDoc = null;

        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode storageAccountCheckNameAvailabilityParametersValue = objectMapper.createObjectNode();
        requestDoc = storageAccountCheckNameAvailabilityParametersValue;

        ((ObjectNode) storageAccountCheckNameAvailabilityParametersValue).put("name", accountName);

        ((ObjectNode) storageAccountCheckNameAvailabilityParametersValue).put("type",
                "Microsoft.Storage/storageAccounts");

        StringWriter stringWriter = new StringWriter();
        objectMapper.writeValue(stringWriter, requestDoc);
        requestContent = stringWriter.toString();
        StringEntity entity = new StringEntity(requestContent);
        httpRequest.setEntity(entity);
        httpRequest.setHeader("Content-Type", "application/json");

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                ServiceException ex = ServiceException.createFromJson(httpRequest, requestContent, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            CheckNameAvailabilityResponse result = null;
            // Deserialize Response
            if (statusCode == HttpStatus.SC_OK) {
                InputStream responseContent = httpResponse.getEntity().getContent();
                result = new CheckNameAvailabilityResponse();
                JsonNode responseDoc = null;
                String responseDocContent = IOUtils.toString(responseContent);
                if (responseDocContent == null == false && responseDocContent.length() > 0) {
                    responseDoc = objectMapper.readTree(responseDocContent);
                }

                if (responseDoc != null && responseDoc instanceof NullNode == false) {
                    JsonNode nameAvailableValue = responseDoc.get("nameAvailable");
                    if (nameAvailableValue != null && nameAvailableValue instanceof NullNode == false) {
                        boolean nameAvailableInstance;
                        nameAvailableInstance = nameAvailableValue.getBooleanValue();
                        result.setNameAvailable(nameAvailableInstance);
                    }

                    JsonNode reasonValue = responseDoc.get("reason");
                    if (reasonValue != null && reasonValue instanceof NullNode == false) {
                        Reason reasonInstance;
                        reasonInstance = EnumUtility.fromString(Reason.class, reasonValue.getTextValue());
                        result.setReason(reasonInstance);
                    }

                    JsonNode messageValue = responseDoc.get("message");
                    if (messageValue != null && messageValue instanceof NullNode == false) {
                        String messageInstance;
                        messageInstance = messageValue.getTextValue();
                        result.setMessage(messageInstance);
                    }
                }

            }
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }

    /**
    * Asynchronously creates a new storage account with the specified
    * parameters. Existing accounts cannot be updated with this API and should
    * instead use the Update Storage Account API. If an account is already
    * created and subsequent create request is issued with exact same set of
    * properties, the request succeeds.The max number of storage accounts that
    * can be created per subscription is limited to 100.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @param parameters Required. The parameters to provide for the created
    * account.
    * @return The Create storage account operation response.
    */
    @Override
    public Future<StorageAccountCreateResponse> createAsync(final String resourceGroupName,
            final String accountName, final StorageAccountCreateParameters parameters) {
        return this.getClient().getExecutorService().submit(new Callable<StorageAccountCreateResponse>() {
            @Override
            public StorageAccountCreateResponse call() throws Exception {
                return create(resourceGroupName, accountName, parameters);
            }
        });
    }

    /**
    * Asynchronously creates a new storage account with the specified
    * parameters. Existing accounts cannot be updated with this API and should
    * instead use the Update Storage Account API. If an account is already
    * created and subsequent create request is issued with exact same set of
    * properties, the request succeeds.The max number of storage accounts that
    * can be created per subscription is limited to 100.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @param parameters Required. The parameters to provide for the created
    * account.
    * @throws InterruptedException Thrown when a thread is waiting, sleeping,
    * or otherwise occupied, and the thread is interrupted, either before or
    * during the activity. Occasionally a method may wish to test whether the
    * current thread has been interrupted, and if so, to immediately throw
    * this exception. The following code can be used to achieve this effect:
    * @throws ExecutionException Thrown when attempting to retrieve the result
    * of a task that aborted by throwing an exception. This exception can be
    * inspected using the Throwable.getCause() method.
    * @throws IOException Thrown if there was an error setting up tracing for
    * the request.
    * @return The Create storage account operation response.
    */
    @Override
    public StorageAccountCreateResponse create(String resourceGroupName, String accountName,
            StorageAccountCreateParameters parameters)
            throws InterruptedException, ExecutionException, IOException {
        StorageManagementClient client2 = this.getClient();
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("resourceGroupName", resourceGroupName);
            tracingParameters.put("accountName", accountName);
            tracingParameters.put("parameters", parameters);
            CloudTracing.enter(invocationId, this, "createAsync", tracingParameters);
        }
        try {
            if (shouldTrace) {
                client2 = this.getClient().withRequestFilterLast(new ClientRequestTrackingHandler(invocationId))
                        .withResponseFilterLast(new ClientRequestTrackingHandler(invocationId));
            }

            StorageAccountCreateResponse response = client2.getStorageAccountsOperations()
                    .beginCreateAsync(resourceGroupName, accountName, parameters).get();
            if (response.getStatus() == OperationStatus.Succeeded) {
                return response;
            }
            StorageAccountCreateResponse result = client2
                    .getCreateOperationStatusAsync(response.getOperationStatusLink()).get();
            int delayInSeconds = response.getRetryAfter();
            if (delayInSeconds == 0) {
                delayInSeconds = 25;
            }
            if (client2.getLongRunningOperationInitialTimeout() >= 0) {
                delayInSeconds = client2.getLongRunningOperationInitialTimeout();
            }
            while (result.getStatus() != null && result.getStatus().equals(OperationStatus.InProgress)) {
                Thread.sleep(delayInSeconds * 1000);
                result = client2.getCreateOperationStatusAsync(response.getOperationStatusLink()).get();
                delayInSeconds = result.getRetryAfter();
                if (delayInSeconds == 0) {
                    delayInSeconds = 25;
                }
                if (client2.getLongRunningOperationRetryTimeout() >= 0) {
                    delayInSeconds = client2.getLongRunningOperationRetryTimeout();
                }
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }

            return result;
        } finally {
            if (client2 != null && shouldTrace) {
                client2.close();
            }
        }
    }

    /**
    * Deletes a storage account in Microsoft Azure.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @return A standard service response including an HTTP status code and
    * request ID.
    */
    @Override
    public Future<OperationResponse> deleteAsync(final String resourceGroupName, final String accountName) {
        return this.getClient().getExecutorService().submit(new Callable<OperationResponse>() {
            @Override
            public OperationResponse call() throws Exception {
                return delete(resourceGroupName, accountName);
            }
        });
    }

    /**
    * Deletes a storage account in Microsoft Azure.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @return A standard service response including an HTTP status code and
    * request ID.
    */
    @Override
    public OperationResponse delete(String resourceGroupName, String accountName)
            throws IOException, ServiceException {
        // Validate
        if (resourceGroupName == null) {
            throw new NullPointerException("resourceGroupName");
        }
        if (accountName == null) {
            throw new NullPointerException("accountName");
        }
        if (accountName.length() < 3) {
            throw new IllegalArgumentException("accountName");
        }
        if (accountName.length() > 24) {
            throw new IllegalArgumentException("accountName");
        }
        for (char accountNameChar : accountName.toCharArray()) {
            if (Character.isLowerCase(accountNameChar) == false && Character.isDigit(accountNameChar) == false) {
                throw new IllegalArgumentException("accountName");
            }
        }

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("resourceGroupName", resourceGroupName);
            tracingParameters.put("accountName", accountName);
            CloudTracing.enter(invocationId, this, "deleteAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/resourceGroups/";
        url = url + URLEncoder.encode(resourceGroupName, "UTF-8");
        url = url + "/providers/Microsoft.Storage/storageAccounts/";
        url = url + URLEncoder.encode(accountName, "UTF-8");
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        CustomHttpDelete httpRequest = new CustomHttpDelete(url);

        // Set Headers
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_NO_CONTENT) {
                ServiceException ex = ServiceException.createFromXml(httpRequest, null, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            OperationResponse result = null;
            // Deserialize Response
            result = new OperationResponse();
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }

    /**
    * Returns the properties for the specified storage account including but
    * not limited to name, account type, location, and account status. The
    * ListKeys operation should be used to retrieve storage keys.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @return The Get storage account operation response.
    */
    @Override
    public Future<StorageAccountGetPropertiesResponse> getPropertiesAsync(final String resourceGroupName,
            final String accountName) {
        return this.getClient().getExecutorService().submit(new Callable<StorageAccountGetPropertiesResponse>() {
            @Override
            public StorageAccountGetPropertiesResponse call() throws Exception {
                return getProperties(resourceGroupName, accountName);
            }
        });
    }

    /**
    * Returns the properties for the specified storage account including but
    * not limited to name, account type, location, and account status. The
    * ListKeys operation should be used to retrieve storage keys.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @throws URISyntaxException Thrown if there was an error parsing a URI in
    * the response.
    * @return The Get storage account operation response.
    */
    @Override
    public StorageAccountGetPropertiesResponse getProperties(String resourceGroupName, String accountName)
            throws IOException, ServiceException, URISyntaxException {
        // Validate
        if (resourceGroupName == null) {
            throw new NullPointerException("resourceGroupName");
        }
        if (accountName == null) {
            throw new NullPointerException("accountName");
        }
        if (accountName.length() < 3) {
            throw new IllegalArgumentException("accountName");
        }
        if (accountName.length() > 24) {
            throw new IllegalArgumentException("accountName");
        }
        for (char accountNameChar : accountName.toCharArray()) {
            if (Character.isLowerCase(accountNameChar) == false && Character.isDigit(accountNameChar) == false) {
                throw new IllegalArgumentException("accountName");
            }
        }

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("resourceGroupName", resourceGroupName);
            tracingParameters.put("accountName", accountName);
            CloudTracing.enter(invocationId, this, "getPropertiesAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/resourceGroups/";
        url = url + URLEncoder.encode(resourceGroupName, "UTF-8");
        url = url + "/providers/Microsoft.Storage/storageAccounts/";
        url = url + URLEncoder.encode(accountName, "UTF-8");
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        HttpGet httpRequest = new HttpGet(url);

        // Set Headers
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                ServiceException ex = ServiceException.createFromJson(httpRequest, null, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            StorageAccountGetPropertiesResponse result = null;
            // Deserialize Response
            if (statusCode == HttpStatus.SC_OK) {
                InputStream responseContent = httpResponse.getEntity().getContent();
                result = new StorageAccountGetPropertiesResponse();
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode responseDoc = null;
                String responseDocContent = IOUtils.toString(responseContent);
                if (responseDocContent == null == false && responseDocContent.length() > 0) {
                    responseDoc = objectMapper.readTree(responseDocContent);
                }

                if (responseDoc != null && responseDoc instanceof NullNode == false) {
                    StorageAccount storageAccountInstance = new StorageAccount();
                    result.setStorageAccount(storageAccountInstance);

                    JsonNode idValue = responseDoc.get("id");
                    if (idValue != null && idValue instanceof NullNode == false) {
                        String idInstance;
                        idInstance = idValue.getTextValue();
                        storageAccountInstance.setId(idInstance);
                    }

                    JsonNode nameValue = responseDoc.get("name");
                    if (nameValue != null && nameValue instanceof NullNode == false) {
                        String nameInstance;
                        nameInstance = nameValue.getTextValue();
                        storageAccountInstance.setName(nameInstance);
                    }

                    JsonNode typeValue = responseDoc.get("type");
                    if (typeValue != null && typeValue instanceof NullNode == false) {
                        String typeInstance;
                        typeInstance = typeValue.getTextValue();
                        storageAccountInstance.setType(typeInstance);
                    }

                    JsonNode locationValue = responseDoc.get("location");
                    if (locationValue != null && locationValue instanceof NullNode == false) {
                        String locationInstance;
                        locationInstance = locationValue.getTextValue();
                        storageAccountInstance.setLocation(locationInstance);
                    }

                    JsonNode tagsSequenceElement = ((JsonNode) responseDoc.get("tags"));
                    if (tagsSequenceElement != null && tagsSequenceElement instanceof NullNode == false) {
                        Iterator<Map.Entry<String, JsonNode>> itr = tagsSequenceElement.getFields();
                        while (itr.hasNext()) {
                            Map.Entry<String, JsonNode> property = itr.next();
                            String tagsKey = property.getKey();
                            String tagsValue = property.getValue().getTextValue();
                            storageAccountInstance.getTags().put(tagsKey, tagsValue);
                        }
                    }

                    JsonNode propertiesValue = responseDoc.get("properties");
                    if (propertiesValue != null && propertiesValue instanceof NullNode == false) {
                        JsonNode provisioningStateValue = propertiesValue.get("provisioningState");
                        if (provisioningStateValue != null && provisioningStateValue instanceof NullNode == false) {
                            ProvisioningState provisioningStateInstance;
                            provisioningStateInstance = EnumUtility.fromString(ProvisioningState.class,
                                    provisioningStateValue.getTextValue());
                            storageAccountInstance.setProvisioningState(provisioningStateInstance);
                        }

                        JsonNode accountTypeValue = propertiesValue.get("accountType");
                        if (accountTypeValue != null && accountTypeValue instanceof NullNode == false) {
                            AccountType accountTypeInstance;
                            accountTypeInstance = StorageManagementClientImpl
                                    .parseAccountType(accountTypeValue.getTextValue());
                            storageAccountInstance.setAccountType(accountTypeInstance);
                        }

                        JsonNode primaryEndpointsValue = propertiesValue.get("primaryEndpoints");
                        if (primaryEndpointsValue != null && primaryEndpointsValue instanceof NullNode == false) {
                            Endpoints primaryEndpointsInstance = new Endpoints();
                            storageAccountInstance.setPrimaryEndpoints(primaryEndpointsInstance);

                            JsonNode blobValue = primaryEndpointsValue.get("blob");
                            if (blobValue != null && blobValue instanceof NullNode == false) {
                                URI blobInstance;
                                blobInstance = new URI(blobValue.getTextValue());
                                primaryEndpointsInstance.setBlob(blobInstance);
                            }

                            JsonNode queueValue = primaryEndpointsValue.get("queue");
                            if (queueValue != null && queueValue instanceof NullNode == false) {
                                URI queueInstance;
                                queueInstance = new URI(queueValue.getTextValue());
                                primaryEndpointsInstance.setQueue(queueInstance);
                            }

                            JsonNode tableValue = primaryEndpointsValue.get("table");
                            if (tableValue != null && tableValue instanceof NullNode == false) {
                                URI tableInstance;
                                tableInstance = new URI(tableValue.getTextValue());
                                primaryEndpointsInstance.setTable(tableInstance);
                            }

                            JsonNode fileValue = primaryEndpointsValue.get("file");
                            if (fileValue != null && fileValue instanceof NullNode == false) {
                                URI fileInstance;
                                fileInstance = new URI(fileValue.getTextValue());
                                primaryEndpointsInstance.setFile(fileInstance);
                            }
                        }

                        JsonNode primaryLocationValue = propertiesValue.get("primaryLocation");
                        if (primaryLocationValue != null && primaryLocationValue instanceof NullNode == false) {
                            String primaryLocationInstance;
                            primaryLocationInstance = primaryLocationValue.getTextValue();
                            storageAccountInstance.setPrimaryLocation(primaryLocationInstance);
                        }

                        JsonNode statusOfPrimaryValue = propertiesValue.get("statusOfPrimary");
                        if (statusOfPrimaryValue != null && statusOfPrimaryValue instanceof NullNode == false) {
                            AccountStatus statusOfPrimaryInstance;
                            statusOfPrimaryInstance = EnumUtility.fromString(AccountStatus.class,
                                    statusOfPrimaryValue.getTextValue());
                            storageAccountInstance.setStatusOfPrimary(statusOfPrimaryInstance);
                        }

                        JsonNode lastGeoFailoverTimeValue = propertiesValue.get("lastGeoFailoverTime");
                        if (lastGeoFailoverTimeValue != null
                                && lastGeoFailoverTimeValue instanceof NullNode == false) {
                            Calendar lastGeoFailoverTimeInstance;
                            lastGeoFailoverTimeInstance = DatatypeConverter
                                    .parseDateTime(lastGeoFailoverTimeValue.getTextValue());
                            storageAccountInstance.setLastGeoFailoverTime(lastGeoFailoverTimeInstance);
                        }

                        JsonNode secondaryLocationValue = propertiesValue.get("secondaryLocation");
                        if (secondaryLocationValue != null && secondaryLocationValue instanceof NullNode == false) {
                            String secondaryLocationInstance;
                            secondaryLocationInstance = secondaryLocationValue.getTextValue();
                            storageAccountInstance.setSecondaryLocation(secondaryLocationInstance);
                        }

                        JsonNode statusOfSecondaryValue = propertiesValue.get("statusOfSecondary");
                        if (statusOfSecondaryValue != null && statusOfSecondaryValue instanceof NullNode == false) {
                            AccountStatus statusOfSecondaryInstance;
                            statusOfSecondaryInstance = EnumUtility.fromString(AccountStatus.class,
                                    statusOfSecondaryValue.getTextValue());
                            storageAccountInstance.setStatusOfSecondary(statusOfSecondaryInstance);
                        }

                        JsonNode creationTimeValue = propertiesValue.get("creationTime");
                        if (creationTimeValue != null && creationTimeValue instanceof NullNode == false) {
                            Calendar creationTimeInstance;
                            creationTimeInstance = DatatypeConverter
                                    .parseDateTime(creationTimeValue.getTextValue());
                            storageAccountInstance.setCreationTime(creationTimeInstance);
                        }

                        JsonNode customDomainValue = propertiesValue.get("customDomain");
                        if (customDomainValue != null && customDomainValue instanceof NullNode == false) {
                            CustomDomain customDomainInstance = new CustomDomain();
                            storageAccountInstance.setCustomDomain(customDomainInstance);

                            JsonNode nameValue2 = customDomainValue.get("name");
                            if (nameValue2 != null && nameValue2 instanceof NullNode == false) {
                                String nameInstance2;
                                nameInstance2 = nameValue2.getTextValue();
                                customDomainInstance.setName(nameInstance2);
                            }

                            JsonNode useSubDomainValue = customDomainValue.get("useSubDomain");
                            if (useSubDomainValue != null && useSubDomainValue instanceof NullNode == false) {
                                boolean useSubDomainInstance;
                                useSubDomainInstance = useSubDomainValue.getBooleanValue();
                                customDomainInstance.setUseSubDomain(useSubDomainInstance);
                            }
                        }

                        JsonNode secondaryEndpointsValue = propertiesValue.get("secondaryEndpoints");
                        if (secondaryEndpointsValue != null
                                && secondaryEndpointsValue instanceof NullNode == false) {
                            Endpoints secondaryEndpointsInstance = new Endpoints();
                            storageAccountInstance.setSecondaryEndpoints(secondaryEndpointsInstance);

                            JsonNode blobValue2 = secondaryEndpointsValue.get("blob");
                            if (blobValue2 != null && blobValue2 instanceof NullNode == false) {
                                URI blobInstance2;
                                blobInstance2 = new URI(blobValue2.getTextValue());
                                secondaryEndpointsInstance.setBlob(blobInstance2);
                            }

                            JsonNode queueValue2 = secondaryEndpointsValue.get("queue");
                            if (queueValue2 != null && queueValue2 instanceof NullNode == false) {
                                URI queueInstance2;
                                queueInstance2 = new URI(queueValue2.getTextValue());
                                secondaryEndpointsInstance.setQueue(queueInstance2);
                            }

                            JsonNode tableValue2 = secondaryEndpointsValue.get("table");
                            if (tableValue2 != null && tableValue2 instanceof NullNode == false) {
                                URI tableInstance2;
                                tableInstance2 = new URI(tableValue2.getTextValue());
                                secondaryEndpointsInstance.setTable(tableInstance2);
                            }

                            JsonNode fileValue2 = secondaryEndpointsValue.get("file");
                            if (fileValue2 != null && fileValue2 instanceof NullNode == false) {
                                URI fileInstance2;
                                fileInstance2 = new URI(fileValue2.getTextValue());
                                secondaryEndpointsInstance.setFile(fileInstance2);
                            }
                        }
                    }
                }

            }
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }

    /**
    * Lists all the storage accounts available under the subscription. Note
    * that storage keys are not returned; use the ListKeys operation for this.
    *
    * @return The list storage accounts operation response.
    */
    @Override
    public Future<StorageAccountListResponse> listAsync() {
        return this.getClient().getExecutorService().submit(new Callable<StorageAccountListResponse>() {
            @Override
            public StorageAccountListResponse call() throws Exception {
                return list();
            }
        });
    }

    /**
    * Lists all the storage accounts available under the subscription. Note
    * that storage keys are not returned; use the ListKeys operation for this.
    *
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @throws URISyntaxException Thrown if there was an error parsing a URI in
    * the response.
    * @return The list storage accounts operation response.
    */
    @Override
    public StorageAccountListResponse list() throws IOException, ServiceException, URISyntaxException {
        // Validate

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            CloudTracing.enter(invocationId, this, "listAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/providers/Microsoft.Storage/storageAccounts";
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        HttpGet httpRequest = new HttpGet(url);

        // Set Headers
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                ServiceException ex = ServiceException.createFromJson(httpRequest, null, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            StorageAccountListResponse result = null;
            // Deserialize Response
            if (statusCode == HttpStatus.SC_OK) {
                InputStream responseContent = httpResponse.getEntity().getContent();
                result = new StorageAccountListResponse();
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode responseDoc = null;
                String responseDocContent = IOUtils.toString(responseContent);
                if (responseDocContent == null == false && responseDocContent.length() > 0) {
                    responseDoc = objectMapper.readTree(responseDocContent);
                }

                if (responseDoc != null && responseDoc instanceof NullNode == false) {
                    JsonNode valueArray = responseDoc.get("value");
                    if (valueArray != null && valueArray instanceof NullNode == false) {
                        for (JsonNode valueValue : ((ArrayNode) valueArray)) {
                            StorageAccount storageAccountJsonInstance = new StorageAccount();
                            result.getStorageAccounts().add(storageAccountJsonInstance);

                            JsonNode idValue = valueValue.get("id");
                            if (idValue != null && idValue instanceof NullNode == false) {
                                String idInstance;
                                idInstance = idValue.getTextValue();
                                storageAccountJsonInstance.setId(idInstance);
                            }

                            JsonNode nameValue = valueValue.get("name");
                            if (nameValue != null && nameValue instanceof NullNode == false) {
                                String nameInstance;
                                nameInstance = nameValue.getTextValue();
                                storageAccountJsonInstance.setName(nameInstance);
                            }

                            JsonNode typeValue = valueValue.get("type");
                            if (typeValue != null && typeValue instanceof NullNode == false) {
                                String typeInstance;
                                typeInstance = typeValue.getTextValue();
                                storageAccountJsonInstance.setType(typeInstance);
                            }

                            JsonNode locationValue = valueValue.get("location");
                            if (locationValue != null && locationValue instanceof NullNode == false) {
                                String locationInstance;
                                locationInstance = locationValue.getTextValue();
                                storageAccountJsonInstance.setLocation(locationInstance);
                            }

                            JsonNode tagsSequenceElement = ((JsonNode) valueValue.get("tags"));
                            if (tagsSequenceElement != null && tagsSequenceElement instanceof NullNode == false) {
                                Iterator<Map.Entry<String, JsonNode>> itr = tagsSequenceElement.getFields();
                                while (itr.hasNext()) {
                                    Map.Entry<String, JsonNode> property = itr.next();
                                    String tagsKey = property.getKey();
                                    String tagsValue = property.getValue().getTextValue();
                                    storageAccountJsonInstance.getTags().put(tagsKey, tagsValue);
                                }
                            }

                            JsonNode propertiesValue = valueValue.get("properties");
                            if (propertiesValue != null && propertiesValue instanceof NullNode == false) {
                                JsonNode provisioningStateValue = propertiesValue.get("provisioningState");
                                if (provisioningStateValue != null
                                        && provisioningStateValue instanceof NullNode == false) {
                                    ProvisioningState provisioningStateInstance;
                                    provisioningStateInstance = EnumUtility.fromString(ProvisioningState.class,
                                            provisioningStateValue.getTextValue());
                                    storageAccountJsonInstance.setProvisioningState(provisioningStateInstance);
                                }

                                JsonNode accountTypeValue = propertiesValue.get("accountType");
                                if (accountTypeValue != null && accountTypeValue instanceof NullNode == false) {
                                    AccountType accountTypeInstance;
                                    accountTypeInstance = StorageManagementClientImpl
                                            .parseAccountType(accountTypeValue.getTextValue());
                                    storageAccountJsonInstance.setAccountType(accountTypeInstance);
                                }

                                JsonNode primaryEndpointsValue = propertiesValue.get("primaryEndpoints");
                                if (primaryEndpointsValue != null
                                        && primaryEndpointsValue instanceof NullNode == false) {
                                    Endpoints primaryEndpointsInstance = new Endpoints();
                                    storageAccountJsonInstance.setPrimaryEndpoints(primaryEndpointsInstance);

                                    JsonNode blobValue = primaryEndpointsValue.get("blob");
                                    if (blobValue != null && blobValue instanceof NullNode == false) {
                                        URI blobInstance;
                                        blobInstance = new URI(blobValue.getTextValue());
                                        primaryEndpointsInstance.setBlob(blobInstance);
                                    }

                                    JsonNode queueValue = primaryEndpointsValue.get("queue");
                                    if (queueValue != null && queueValue instanceof NullNode == false) {
                                        URI queueInstance;
                                        queueInstance = new URI(queueValue.getTextValue());
                                        primaryEndpointsInstance.setQueue(queueInstance);
                                    }

                                    JsonNode tableValue = primaryEndpointsValue.get("table");
                                    if (tableValue != null && tableValue instanceof NullNode == false) {
                                        URI tableInstance;
                                        tableInstance = new URI(tableValue.getTextValue());
                                        primaryEndpointsInstance.setTable(tableInstance);
                                    }

                                    JsonNode fileValue = primaryEndpointsValue.get("file");
                                    if (fileValue != null && fileValue instanceof NullNode == false) {
                                        URI fileInstance;
                                        fileInstance = new URI(fileValue.getTextValue());
                                        primaryEndpointsInstance.setFile(fileInstance);
                                    }
                                }

                                JsonNode primaryLocationValue = propertiesValue.get("primaryLocation");
                                if (primaryLocationValue != null
                                        && primaryLocationValue instanceof NullNode == false) {
                                    String primaryLocationInstance;
                                    primaryLocationInstance = primaryLocationValue.getTextValue();
                                    storageAccountJsonInstance.setPrimaryLocation(primaryLocationInstance);
                                }

                                JsonNode statusOfPrimaryValue = propertiesValue.get("statusOfPrimary");
                                if (statusOfPrimaryValue != null
                                        && statusOfPrimaryValue instanceof NullNode == false) {
                                    AccountStatus statusOfPrimaryInstance;
                                    statusOfPrimaryInstance = EnumUtility.fromString(AccountStatus.class,
                                            statusOfPrimaryValue.getTextValue());
                                    storageAccountJsonInstance.setStatusOfPrimary(statusOfPrimaryInstance);
                                }

                                JsonNode lastGeoFailoverTimeValue = propertiesValue.get("lastGeoFailoverTime");
                                if (lastGeoFailoverTimeValue != null
                                        && lastGeoFailoverTimeValue instanceof NullNode == false) {
                                    Calendar lastGeoFailoverTimeInstance;
                                    lastGeoFailoverTimeInstance = DatatypeConverter
                                            .parseDateTime(lastGeoFailoverTimeValue.getTextValue());
                                    storageAccountJsonInstance.setLastGeoFailoverTime(lastGeoFailoverTimeInstance);
                                }

                                JsonNode secondaryLocationValue = propertiesValue.get("secondaryLocation");
                                if (secondaryLocationValue != null
                                        && secondaryLocationValue instanceof NullNode == false) {
                                    String secondaryLocationInstance;
                                    secondaryLocationInstance = secondaryLocationValue.getTextValue();
                                    storageAccountJsonInstance.setSecondaryLocation(secondaryLocationInstance);
                                }

                                JsonNode statusOfSecondaryValue = propertiesValue.get("statusOfSecondary");
                                if (statusOfSecondaryValue != null
                                        && statusOfSecondaryValue instanceof NullNode == false) {
                                    AccountStatus statusOfSecondaryInstance;
                                    statusOfSecondaryInstance = EnumUtility.fromString(AccountStatus.class,
                                            statusOfSecondaryValue.getTextValue());
                                    storageAccountJsonInstance.setStatusOfSecondary(statusOfSecondaryInstance);
                                }

                                JsonNode creationTimeValue = propertiesValue.get("creationTime");
                                if (creationTimeValue != null && creationTimeValue instanceof NullNode == false) {
                                    Calendar creationTimeInstance;
                                    creationTimeInstance = DatatypeConverter
                                            .parseDateTime(creationTimeValue.getTextValue());
                                    storageAccountJsonInstance.setCreationTime(creationTimeInstance);
                                }

                                JsonNode customDomainValue = propertiesValue.get("customDomain");
                                if (customDomainValue != null && customDomainValue instanceof NullNode == false) {
                                    CustomDomain customDomainInstance = new CustomDomain();
                                    storageAccountJsonInstance.setCustomDomain(customDomainInstance);

                                    JsonNode nameValue2 = customDomainValue.get("name");
                                    if (nameValue2 != null && nameValue2 instanceof NullNode == false) {
                                        String nameInstance2;
                                        nameInstance2 = nameValue2.getTextValue();
                                        customDomainInstance.setName(nameInstance2);
                                    }

                                    JsonNode useSubDomainValue = customDomainValue.get("useSubDomain");
                                    if (useSubDomainValue != null
                                            && useSubDomainValue instanceof NullNode == false) {
                                        boolean useSubDomainInstance;
                                        useSubDomainInstance = useSubDomainValue.getBooleanValue();
                                        customDomainInstance.setUseSubDomain(useSubDomainInstance);
                                    }
                                }

                                JsonNode secondaryEndpointsValue = propertiesValue.get("secondaryEndpoints");
                                if (secondaryEndpointsValue != null
                                        && secondaryEndpointsValue instanceof NullNode == false) {
                                    Endpoints secondaryEndpointsInstance = new Endpoints();
                                    storageAccountJsonInstance.setSecondaryEndpoints(secondaryEndpointsInstance);

                                    JsonNode blobValue2 = secondaryEndpointsValue.get("blob");
                                    if (blobValue2 != null && blobValue2 instanceof NullNode == false) {
                                        URI blobInstance2;
                                        blobInstance2 = new URI(blobValue2.getTextValue());
                                        secondaryEndpointsInstance.setBlob(blobInstance2);
                                    }

                                    JsonNode queueValue2 = secondaryEndpointsValue.get("queue");
                                    if (queueValue2 != null && queueValue2 instanceof NullNode == false) {
                                        URI queueInstance2;
                                        queueInstance2 = new URI(queueValue2.getTextValue());
                                        secondaryEndpointsInstance.setQueue(queueInstance2);
                                    }

                                    JsonNode tableValue2 = secondaryEndpointsValue.get("table");
                                    if (tableValue2 != null && tableValue2 instanceof NullNode == false) {
                                        URI tableInstance2;
                                        tableInstance2 = new URI(tableValue2.getTextValue());
                                        secondaryEndpointsInstance.setTable(tableInstance2);
                                    }

                                    JsonNode fileValue2 = secondaryEndpointsValue.get("file");
                                    if (fileValue2 != null && fileValue2 instanceof NullNode == false) {
                                        URI fileInstance2;
                                        fileInstance2 = new URI(fileValue2.getTextValue());
                                        secondaryEndpointsInstance.setFile(fileInstance2);
                                    }
                                }
                            }
                        }
                    }
                }

            }
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }

    /**
    * Lists all the storage accounts available under the given resource group.
    * Note that storage keys are not returned; use the ListKeys operation for
    * this.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @return The list storage accounts operation response.
    */
    @Override
    public Future<StorageAccountListResponse> listByResourceGroupAsync(final String resourceGroupName) {
        return this.getClient().getExecutorService().submit(new Callable<StorageAccountListResponse>() {
            @Override
            public StorageAccountListResponse call() throws Exception {
                return listByResourceGroup(resourceGroupName);
            }
        });
    }

    /**
    * Lists all the storage accounts available under the given resource group.
    * Note that storage keys are not returned; use the ListKeys operation for
    * this.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @throws URISyntaxException Thrown if there was an error parsing a URI in
    * the response.
    * @return The list storage accounts operation response.
    */
    @Override
    public StorageAccountListResponse listByResourceGroup(String resourceGroupName)
            throws IOException, ServiceException, URISyntaxException {
        // Validate
        if (resourceGroupName == null) {
            throw new NullPointerException("resourceGroupName");
        }

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("resourceGroupName", resourceGroupName);
            CloudTracing.enter(invocationId, this, "listByResourceGroupAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/resourceGroups/";
        url = url + URLEncoder.encode(resourceGroupName, "UTF-8");
        url = url + "/providers/Microsoft.Storage/storageAccounts";
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        HttpGet httpRequest = new HttpGet(url);

        // Set Headers
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                ServiceException ex = ServiceException.createFromJson(httpRequest, null, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            StorageAccountListResponse result = null;
            // Deserialize Response
            if (statusCode == HttpStatus.SC_OK) {
                InputStream responseContent = httpResponse.getEntity().getContent();
                result = new StorageAccountListResponse();
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode responseDoc = null;
                String responseDocContent = IOUtils.toString(responseContent);
                if (responseDocContent == null == false && responseDocContent.length() > 0) {
                    responseDoc = objectMapper.readTree(responseDocContent);
                }

                if (responseDoc != null && responseDoc instanceof NullNode == false) {
                    JsonNode valueArray = responseDoc.get("value");
                    if (valueArray != null && valueArray instanceof NullNode == false) {
                        for (JsonNode valueValue : ((ArrayNode) valueArray)) {
                            StorageAccount storageAccountJsonInstance = new StorageAccount();
                            result.getStorageAccounts().add(storageAccountJsonInstance);

                            JsonNode idValue = valueValue.get("id");
                            if (idValue != null && idValue instanceof NullNode == false) {
                                String idInstance;
                                idInstance = idValue.getTextValue();
                                storageAccountJsonInstance.setId(idInstance);
                            }

                            JsonNode nameValue = valueValue.get("name");
                            if (nameValue != null && nameValue instanceof NullNode == false) {
                                String nameInstance;
                                nameInstance = nameValue.getTextValue();
                                storageAccountJsonInstance.setName(nameInstance);
                            }

                            JsonNode typeValue = valueValue.get("type");
                            if (typeValue != null && typeValue instanceof NullNode == false) {
                                String typeInstance;
                                typeInstance = typeValue.getTextValue();
                                storageAccountJsonInstance.setType(typeInstance);
                            }

                            JsonNode locationValue = valueValue.get("location");
                            if (locationValue != null && locationValue instanceof NullNode == false) {
                                String locationInstance;
                                locationInstance = locationValue.getTextValue();
                                storageAccountJsonInstance.setLocation(locationInstance);
                            }

                            JsonNode tagsSequenceElement = ((JsonNode) valueValue.get("tags"));
                            if (tagsSequenceElement != null && tagsSequenceElement instanceof NullNode == false) {
                                Iterator<Map.Entry<String, JsonNode>> itr = tagsSequenceElement.getFields();
                                while (itr.hasNext()) {
                                    Map.Entry<String, JsonNode> property = itr.next();
                                    String tagsKey = property.getKey();
                                    String tagsValue = property.getValue().getTextValue();
                                    storageAccountJsonInstance.getTags().put(tagsKey, tagsValue);
                                }
                            }

                            JsonNode propertiesValue = valueValue.get("properties");
                            if (propertiesValue != null && propertiesValue instanceof NullNode == false) {
                                JsonNode provisioningStateValue = propertiesValue.get("provisioningState");
                                if (provisioningStateValue != null
                                        && provisioningStateValue instanceof NullNode == false) {
                                    ProvisioningState provisioningStateInstance;
                                    provisioningStateInstance = EnumUtility.fromString(ProvisioningState.class,
                                            provisioningStateValue.getTextValue());
                                    storageAccountJsonInstance.setProvisioningState(provisioningStateInstance);
                                }

                                JsonNode accountTypeValue = propertiesValue.get("accountType");
                                if (accountTypeValue != null && accountTypeValue instanceof NullNode == false) {
                                    AccountType accountTypeInstance;
                                    accountTypeInstance = StorageManagementClientImpl
                                            .parseAccountType(accountTypeValue.getTextValue());
                                    storageAccountJsonInstance.setAccountType(accountTypeInstance);
                                }

                                JsonNode primaryEndpointsValue = propertiesValue.get("primaryEndpoints");
                                if (primaryEndpointsValue != null
                                        && primaryEndpointsValue instanceof NullNode == false) {
                                    Endpoints primaryEndpointsInstance = new Endpoints();
                                    storageAccountJsonInstance.setPrimaryEndpoints(primaryEndpointsInstance);

                                    JsonNode blobValue = primaryEndpointsValue.get("blob");
                                    if (blobValue != null && blobValue instanceof NullNode == false) {
                                        URI blobInstance;
                                        blobInstance = new URI(blobValue.getTextValue());
                                        primaryEndpointsInstance.setBlob(blobInstance);
                                    }

                                    JsonNode queueValue = primaryEndpointsValue.get("queue");
                                    if (queueValue != null && queueValue instanceof NullNode == false) {
                                        URI queueInstance;
                                        queueInstance = new URI(queueValue.getTextValue());
                                        primaryEndpointsInstance.setQueue(queueInstance);
                                    }

                                    JsonNode tableValue = primaryEndpointsValue.get("table");
                                    if (tableValue != null && tableValue instanceof NullNode == false) {
                                        URI tableInstance;
                                        tableInstance = new URI(tableValue.getTextValue());
                                        primaryEndpointsInstance.setTable(tableInstance);
                                    }

                                    JsonNode fileValue = primaryEndpointsValue.get("file");
                                    if (fileValue != null && fileValue instanceof NullNode == false) {
                                        URI fileInstance;
                                        fileInstance = new URI(fileValue.getTextValue());
                                        primaryEndpointsInstance.setFile(fileInstance);
                                    }
                                }

                                JsonNode primaryLocationValue = propertiesValue.get("primaryLocation");
                                if (primaryLocationValue != null
                                        && primaryLocationValue instanceof NullNode == false) {
                                    String primaryLocationInstance;
                                    primaryLocationInstance = primaryLocationValue.getTextValue();
                                    storageAccountJsonInstance.setPrimaryLocation(primaryLocationInstance);
                                }

                                JsonNode statusOfPrimaryValue = propertiesValue.get("statusOfPrimary");
                                if (statusOfPrimaryValue != null
                                        && statusOfPrimaryValue instanceof NullNode == false) {
                                    AccountStatus statusOfPrimaryInstance;
                                    statusOfPrimaryInstance = EnumUtility.fromString(AccountStatus.class,
                                            statusOfPrimaryValue.getTextValue());
                                    storageAccountJsonInstance.setStatusOfPrimary(statusOfPrimaryInstance);
                                }

                                JsonNode lastGeoFailoverTimeValue = propertiesValue.get("lastGeoFailoverTime");
                                if (lastGeoFailoverTimeValue != null
                                        && lastGeoFailoverTimeValue instanceof NullNode == false) {
                                    Calendar lastGeoFailoverTimeInstance;
                                    lastGeoFailoverTimeInstance = DatatypeConverter
                                            .parseDateTime(lastGeoFailoverTimeValue.getTextValue());
                                    storageAccountJsonInstance.setLastGeoFailoverTime(lastGeoFailoverTimeInstance);
                                }

                                JsonNode secondaryLocationValue = propertiesValue.get("secondaryLocation");
                                if (secondaryLocationValue != null
                                        && secondaryLocationValue instanceof NullNode == false) {
                                    String secondaryLocationInstance;
                                    secondaryLocationInstance = secondaryLocationValue.getTextValue();
                                    storageAccountJsonInstance.setSecondaryLocation(secondaryLocationInstance);
                                }

                                JsonNode statusOfSecondaryValue = propertiesValue.get("statusOfSecondary");
                                if (statusOfSecondaryValue != null
                                        && statusOfSecondaryValue instanceof NullNode == false) {
                                    AccountStatus statusOfSecondaryInstance;
                                    statusOfSecondaryInstance = EnumUtility.fromString(AccountStatus.class,
                                            statusOfSecondaryValue.getTextValue());
                                    storageAccountJsonInstance.setStatusOfSecondary(statusOfSecondaryInstance);
                                }

                                JsonNode creationTimeValue = propertiesValue.get("creationTime");
                                if (creationTimeValue != null && creationTimeValue instanceof NullNode == false) {
                                    Calendar creationTimeInstance;
                                    creationTimeInstance = DatatypeConverter
                                            .parseDateTime(creationTimeValue.getTextValue());
                                    storageAccountJsonInstance.setCreationTime(creationTimeInstance);
                                }

                                JsonNode customDomainValue = propertiesValue.get("customDomain");
                                if (customDomainValue != null && customDomainValue instanceof NullNode == false) {
                                    CustomDomain customDomainInstance = new CustomDomain();
                                    storageAccountJsonInstance.setCustomDomain(customDomainInstance);

                                    JsonNode nameValue2 = customDomainValue.get("name");
                                    if (nameValue2 != null && nameValue2 instanceof NullNode == false) {
                                        String nameInstance2;
                                        nameInstance2 = nameValue2.getTextValue();
                                        customDomainInstance.setName(nameInstance2);
                                    }

                                    JsonNode useSubDomainValue = customDomainValue.get("useSubDomain");
                                    if (useSubDomainValue != null
                                            && useSubDomainValue instanceof NullNode == false) {
                                        boolean useSubDomainInstance;
                                        useSubDomainInstance = useSubDomainValue.getBooleanValue();
                                        customDomainInstance.setUseSubDomain(useSubDomainInstance);
                                    }
                                }

                                JsonNode secondaryEndpointsValue = propertiesValue.get("secondaryEndpoints");
                                if (secondaryEndpointsValue != null
                                        && secondaryEndpointsValue instanceof NullNode == false) {
                                    Endpoints secondaryEndpointsInstance = new Endpoints();
                                    storageAccountJsonInstance.setSecondaryEndpoints(secondaryEndpointsInstance);

                                    JsonNode blobValue2 = secondaryEndpointsValue.get("blob");
                                    if (blobValue2 != null && blobValue2 instanceof NullNode == false) {
                                        URI blobInstance2;
                                        blobInstance2 = new URI(blobValue2.getTextValue());
                                        secondaryEndpointsInstance.setBlob(blobInstance2);
                                    }

                                    JsonNode queueValue2 = secondaryEndpointsValue.get("queue");
                                    if (queueValue2 != null && queueValue2 instanceof NullNode == false) {
                                        URI queueInstance2;
                                        queueInstance2 = new URI(queueValue2.getTextValue());
                                        secondaryEndpointsInstance.setQueue(queueInstance2);
                                    }

                                    JsonNode tableValue2 = secondaryEndpointsValue.get("table");
                                    if (tableValue2 != null && tableValue2 instanceof NullNode == false) {
                                        URI tableInstance2;
                                        tableInstance2 = new URI(tableValue2.getTextValue());
                                        secondaryEndpointsInstance.setTable(tableInstance2);
                                    }

                                    JsonNode fileValue2 = secondaryEndpointsValue.get("file");
                                    if (fileValue2 != null && fileValue2 instanceof NullNode == false) {
                                        URI fileInstance2;
                                        fileInstance2 = new URI(fileValue2.getTextValue());
                                        secondaryEndpointsInstance.setFile(fileInstance2);
                                    }
                                }
                            }
                        }
                    }
                }

            }
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }

    /**
    * Lists the access keys for the specified storage account.
    *
    * @param resourceGroupName Required. The name of the resource group.
    * @param accountName Required. The name of the storage account.
    * @return The ListKeys operation response.
    */
    @Override
    public Future<StorageAccountListKeysResponse> listKeysAsync(final String resourceGroupName,
            final String accountName) {
        return this.getClient().getExecutorService().submit(new Callable<StorageAccountListKeysResponse>() {
            @Override
            public StorageAccountListKeysResponse call() throws Exception {
                return listKeys(resourceGroupName, accountName);
            }
        });
    }

    /**
    * Lists the access keys for the specified storage account.
    *
    * @param resourceGroupName Required. The name of the resource group.
    * @param accountName Required. The name of the storage account.
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @return The ListKeys operation response.
    */
    @Override
    public StorageAccountListKeysResponse listKeys(String resourceGroupName, String accountName)
            throws IOException, ServiceException {
        // Validate
        if (resourceGroupName == null) {
            throw new NullPointerException("resourceGroupName");
        }
        if (accountName == null) {
            throw new NullPointerException("accountName");
        }
        if (accountName.length() < 3) {
            throw new IllegalArgumentException("accountName");
        }
        if (accountName.length() > 24) {
            throw new IllegalArgumentException("accountName");
        }
        for (char accountNameChar : accountName.toCharArray()) {
            if (Character.isLowerCase(accountNameChar) == false && Character.isDigit(accountNameChar) == false) {
                throw new IllegalArgumentException("accountName");
            }
        }

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("resourceGroupName", resourceGroupName);
            tracingParameters.put("accountName", accountName);
            CloudTracing.enter(invocationId, this, "listKeysAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/resourceGroups/";
        url = url + URLEncoder.encode(resourceGroupName, "UTF-8");
        url = url + "/providers/Microsoft.Storage/storageAccounts/";
        url = url + URLEncoder.encode(accountName, "UTF-8");
        url = url + "/listKeys";
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        HttpPost httpRequest = new HttpPost(url);

        // Set Headers
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                ServiceException ex = ServiceException.createFromJson(httpRequest, null, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            StorageAccountListKeysResponse result = null;
            // Deserialize Response
            if (statusCode == HttpStatus.SC_OK) {
                InputStream responseContent = httpResponse.getEntity().getContent();
                result = new StorageAccountListKeysResponse();
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode responseDoc = null;
                String responseDocContent = IOUtils.toString(responseContent);
                if (responseDocContent == null == false && responseDocContent.length() > 0) {
                    responseDoc = objectMapper.readTree(responseDocContent);
                }

                if (responseDoc != null && responseDoc instanceof NullNode == false) {
                    StorageAccountKeys storageAccountKeysInstance = new StorageAccountKeys();
                    result.setStorageAccountKeys(storageAccountKeysInstance);

                    JsonNode key1Value = responseDoc.get("key1");
                    if (key1Value != null && key1Value instanceof NullNode == false) {
                        String key1Instance;
                        key1Instance = key1Value.getTextValue();
                        storageAccountKeysInstance.setKey1(key1Instance);
                    }

                    JsonNode key2Value = responseDoc.get("key2");
                    if (key2Value != null && key2Value instanceof NullNode == false) {
                        String key2Instance;
                        key2Instance = key2Value.getTextValue();
                        storageAccountKeysInstance.setKey2(key2Instance);
                    }
                }

            }
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }

    /**
    * Regenerates the access keys for the specified storage account.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @param regenerateKey Required. Specifies name of the key which should be
    * regenerated. key1 or key2 for the default keys
    * @return The RegenerateKey operation response.
    */
    @Override
    public Future<StorageAccountRegenerateKeyResponse> regenerateKeyAsync(final String resourceGroupName,
            final String accountName, final String regenerateKey) {
        return this.getClient().getExecutorService().submit(new Callable<StorageAccountRegenerateKeyResponse>() {
            @Override
            public StorageAccountRegenerateKeyResponse call() throws Exception {
                return regenerateKey(resourceGroupName, accountName, regenerateKey);
            }
        });
    }

    /**
    * Regenerates the access keys for the specified storage account.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @param regenerateKey Required. Specifies name of the key which should be
    * regenerated. key1 or key2 for the default keys
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @return The RegenerateKey operation response.
    */
    @Override
    public StorageAccountRegenerateKeyResponse regenerateKey(String resourceGroupName, String accountName,
            String regenerateKey) throws IOException, ServiceException {
        // Validate
        if (resourceGroupName == null) {
            throw new NullPointerException("resourceGroupName");
        }
        if (accountName == null) {
            throw new NullPointerException("accountName");
        }
        if (accountName.length() < 3) {
            throw new IllegalArgumentException("accountName");
        }
        if (accountName.length() > 24) {
            throw new IllegalArgumentException("accountName");
        }
        for (char accountNameChar : accountName.toCharArray()) {
            if (Character.isLowerCase(accountNameChar) == false && Character.isDigit(accountNameChar) == false) {
                throw new IllegalArgumentException("accountName");
            }
        }
        if (regenerateKey == null) {
            throw new NullPointerException("regenerateKey");
        }

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("resourceGroupName", resourceGroupName);
            tracingParameters.put("accountName", accountName);
            tracingParameters.put("regenerateKey", regenerateKey);
            CloudTracing.enter(invocationId, this, "regenerateKeyAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/resourceGroups/";
        url = url + URLEncoder.encode(resourceGroupName, "UTF-8");
        url = url + "/providers/Microsoft.Storage/storageAccounts/";
        url = url + URLEncoder.encode(accountName, "UTF-8");
        url = url + "/regenerateKey";
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        HttpPost httpRequest = new HttpPost(url);

        // Set Headers
        httpRequest.setHeader("Content-Type", "application/json");
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Serialize Request
        String requestContent = null;
        JsonNode requestDoc = null;

        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode storageAccountRegenerateKeyParametersValue = objectMapper.createObjectNode();
        requestDoc = storageAccountRegenerateKeyParametersValue;

        ((ObjectNode) storageAccountRegenerateKeyParametersValue).put("keyName", regenerateKey);

        StringWriter stringWriter = new StringWriter();
        objectMapper.writeValue(stringWriter, requestDoc);
        requestContent = stringWriter.toString();
        StringEntity entity = new StringEntity(requestContent);
        httpRequest.setEntity(entity);
        httpRequest.setHeader("Content-Type", "application/json");

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                ServiceException ex = ServiceException.createFromJson(httpRequest, requestContent, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            StorageAccountRegenerateKeyResponse result = null;
            // Deserialize Response
            if (statusCode == HttpStatus.SC_OK) {
                InputStream responseContent = httpResponse.getEntity().getContent();
                result = new StorageAccountRegenerateKeyResponse();
                JsonNode responseDoc = null;
                String responseDocContent = IOUtils.toString(responseContent);
                if (responseDocContent == null == false && responseDocContent.length() > 0) {
                    responseDoc = objectMapper.readTree(responseDocContent);
                }

                if (responseDoc != null && responseDoc instanceof NullNode == false) {
                    StorageAccountKeys storageAccountKeysInstance = new StorageAccountKeys();
                    result.setStorageAccountKeys(storageAccountKeysInstance);

                    JsonNode key1Value = responseDoc.get("key1");
                    if (key1Value != null && key1Value instanceof NullNode == false) {
                        String key1Instance;
                        key1Instance = key1Value.getTextValue();
                        storageAccountKeysInstance.setKey1(key1Instance);
                    }

                    JsonNode key2Value = responseDoc.get("key2");
                    if (key2Value != null && key2Value instanceof NullNode == false) {
                        String key2Instance;
                        key2Instance = key2Value.getTextValue();
                        storageAccountKeysInstance.setKey2(key2Instance);
                    }
                }

            }
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }

    /**
    * Updates the account type or tags for a storage account. It can also be
    * used to add a custom domain (note that custom domains cannot be added
    * via the Create operation). Only one custom domain is supported per
    * storage account. In order to replace a custom domain, the old value must
    * be cleared before a new value may be set. To clear a custom domain,
    * simply update the custom domain with empty string. Then call update
    * again with the new cutsom domain name. The update API can only be used
    * to update one of tags, accountType, or customDomain per call. To update
    * multiple of these properties, call the API multiple times with one
    * change per call. This call does not change the storage keys for the
    * account. If you want to change storage account keys, use the
    * RegenerateKey operation. The location and name of the storage account
    * cannot be changed after creation.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @param parameters Required. The parameters to update on the account. Note
    * that only one property can be changed at a time using this API.
    * @return The Update storage account operation response.
    */
    @Override
    public Future<StorageAccountUpdateResponse> updateAsync(final String resourceGroupName,
            final String accountName, final StorageAccountUpdateParameters parameters) {
        return this.getClient().getExecutorService().submit(new Callable<StorageAccountUpdateResponse>() {
            @Override
            public StorageAccountUpdateResponse call() throws Exception {
                return update(resourceGroupName, accountName, parameters);
            }
        });
    }

    /**
    * Updates the account type or tags for a storage account. It can also be
    * used to add a custom domain (note that custom domains cannot be added
    * via the Create operation). Only one custom domain is supported per
    * storage account. In order to replace a custom domain, the old value must
    * be cleared before a new value may be set. To clear a custom domain,
    * simply update the custom domain with empty string. Then call update
    * again with the new cutsom domain name. The update API can only be used
    * to update one of tags, accountType, or customDomain per call. To update
    * multiple of these properties, call the API multiple times with one
    * change per call. This call does not change the storage keys for the
    * account. If you want to change storage account keys, use the
    * RegenerateKey operation. The location and name of the storage account
    * cannot be changed after creation.
    *
    * @param resourceGroupName Required. The name of the resource group within
    * the user's subscription.
    * @param accountName Required. The name of the storage account within the
    * specified resource group. Storage account names must be between 3 and 24
    * characters in length and use numbers and lower-case letters only.
    * @param parameters Required. The parameters to update on the account. Note
    * that only one property can be changed at a time using this API.
    * @throws IOException Signals that an I/O exception of some sort has
    * occurred. This class is the general class of exceptions produced by
    * failed or interrupted I/O operations.
    * @throws ServiceException Thrown if an unexpected response is found.
    * @throws URISyntaxException Thrown if there was an error parsing a URI in
    * the response.
    * @return The Update storage account operation response.
    */
    @Override
    public StorageAccountUpdateResponse update(String resourceGroupName, String accountName,
            StorageAccountUpdateParameters parameters) throws IOException, ServiceException, URISyntaxException {
        // Validate
        if (resourceGroupName == null) {
            throw new NullPointerException("resourceGroupName");
        }
        if (accountName == null) {
            throw new NullPointerException("accountName");
        }
        if (accountName.length() < 3) {
            throw new IllegalArgumentException("accountName");
        }
        if (accountName.length() > 24) {
            throw new IllegalArgumentException("accountName");
        }
        for (char accountNameChar : accountName.toCharArray()) {
            if (Character.isLowerCase(accountNameChar) == false && Character.isDigit(accountNameChar) == false) {
                throw new IllegalArgumentException("accountName");
            }
        }
        if (parameters == null) {
            throw new NullPointerException("parameters");
        }
        if (parameters.getCustomDomain() != null) {
            if (parameters.getCustomDomain().getName() == null) {
                throw new NullPointerException("parameters.CustomDomain.Name");
            }
        }

        // Tracing
        boolean shouldTrace = CloudTracing.getIsEnabled();
        String invocationId = null;
        if (shouldTrace) {
            invocationId = Long.toString(CloudTracing.getNextInvocationId());
            HashMap<String, Object> tracingParameters = new HashMap<String, Object>();
            tracingParameters.put("resourceGroupName", resourceGroupName);
            tracingParameters.put("accountName", accountName);
            tracingParameters.put("parameters", parameters);
            CloudTracing.enter(invocationId, this, "updateAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/subscriptions/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/resourceGroups/";
        url = url + URLEncoder.encode(resourceGroupName, "UTF-8");
        url = url + "/providers/Microsoft.Storage/storageAccounts/";
        url = url + URLEncoder.encode(accountName, "UTF-8");
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("api-version=" + "2015-06-15");
        if (queryParameters.size() > 0) {
            url = url + "?" + CollectionStringBuilder.join(queryParameters, "&");
        }
        String baseUrl = this.getClient().getBaseUri().toString();
        // Trim '/' character from the end of baseUrl and beginning of url.
        if (baseUrl.charAt(baseUrl.length() - 1) == '/') {
            baseUrl = baseUrl.substring(0, (baseUrl.length() - 1) + 0);
        }
        if (url.charAt(0) == '/') {
            url = url.substring(1);
        }
        url = baseUrl + "/" + url;
        url = url.replace(" ", "%20");

        // Create HTTP transport objects
        HttpPatch httpRequest = new HttpPatch(url);

        // Set Headers
        httpRequest.setHeader("Content-Type", "application/json");
        httpRequest.setHeader("x-ms-client-request-id", UUID.randomUUID().toString());

        // Serialize Request
        String requestContent = null;
        JsonNode requestDoc = null;

        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode storageAccountUpdateParametersJsonValue = objectMapper.createObjectNode();
        requestDoc = storageAccountUpdateParametersJsonValue;

        if (parameters.getTags() != null) {
            if (parameters.getTags() instanceof LazyCollection == false
                    || ((LazyCollection) parameters.getTags()).isInitialized()) {
                ObjectNode tagsDictionary = objectMapper.createObjectNode();
                for (Map.Entry<String, String> entry : parameters.getTags().entrySet()) {
                    String tagsKey = entry.getKey();
                    String tagsValue = entry.getValue();
                    ((ObjectNode) tagsDictionary).put(tagsKey, tagsValue);
                }
                ((ObjectNode) storageAccountUpdateParametersJsonValue).put("tags", tagsDictionary);
            }
        }

        ObjectNode propertiesValue = objectMapper.createObjectNode();
        ((ObjectNode) storageAccountUpdateParametersJsonValue).put("properties", propertiesValue);

        if (parameters.getAccountType() != null) {
            ((ObjectNode) propertiesValue).put("accountType",
                    StorageManagementClientImpl.accountTypeToString(parameters.getAccountType()));
        }

        if (parameters.getCustomDomain() != null) {
            ObjectNode customDomainValue = objectMapper.createObjectNode();
            ((ObjectNode) propertiesValue).put("customDomain", customDomainValue);

            ((ObjectNode) customDomainValue).put("name", parameters.getCustomDomain().getName());

            if (parameters.getCustomDomain().isUseSubDomain() != null) {
                ((ObjectNode) customDomainValue).put("useSubDomain", parameters.getCustomDomain().isUseSubDomain());
            }
        }

        StringWriter stringWriter = new StringWriter();
        objectMapper.writeValue(stringWriter, requestDoc);
        requestContent = stringWriter.toString();
        StringEntity entity = new StringEntity(requestContent);
        httpRequest.setEntity(entity);
        httpRequest.setHeader("Content-Type", "application/json");

        // Send Request
        HttpResponse httpResponse = null;
        try {
            if (shouldTrace) {
                CloudTracing.sendRequest(invocationId, httpRequest);
            }
            httpResponse = this.getClient().getHttpClient().execute(httpRequest);
            if (shouldTrace) {
                CloudTracing.receiveResponse(invocationId, httpResponse);
            }
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                ServiceException ex = ServiceException.createFromJson(httpRequest, requestContent, httpResponse,
                        httpResponse.getEntity());
                if (shouldTrace) {
                    CloudTracing.error(invocationId, ex);
                }
                throw ex;
            }

            // Create Result
            StorageAccountUpdateResponse result = null;
            // Deserialize Response
            if (statusCode == HttpStatus.SC_OK) {
                InputStream responseContent = httpResponse.getEntity().getContent();
                result = new StorageAccountUpdateResponse();
                JsonNode responseDoc = null;
                String responseDocContent = IOUtils.toString(responseContent);
                if (responseDocContent == null == false && responseDocContent.length() > 0) {
                    responseDoc = objectMapper.readTree(responseDocContent);
                }

                if (responseDoc != null && responseDoc instanceof NullNode == false) {
                    StorageAccount storageAccountInstance = new StorageAccount();
                    result.setStorageAccount(storageAccountInstance);

                    JsonNode idValue = responseDoc.get("id");
                    if (idValue != null && idValue instanceof NullNode == false) {
                        String idInstance;
                        idInstance = idValue.getTextValue();
                        storageAccountInstance.setId(idInstance);
                    }

                    JsonNode nameValue = responseDoc.get("name");
                    if (nameValue != null && nameValue instanceof NullNode == false) {
                        String nameInstance;
                        nameInstance = nameValue.getTextValue();
                        storageAccountInstance.setName(nameInstance);
                    }

                    JsonNode typeValue = responseDoc.get("type");
                    if (typeValue != null && typeValue instanceof NullNode == false) {
                        String typeInstance;
                        typeInstance = typeValue.getTextValue();
                        storageAccountInstance.setType(typeInstance);
                    }

                    JsonNode locationValue = responseDoc.get("location");
                    if (locationValue != null && locationValue instanceof NullNode == false) {
                        String locationInstance;
                        locationInstance = locationValue.getTextValue();
                        storageAccountInstance.setLocation(locationInstance);
                    }

                    JsonNode tagsSequenceElement = ((JsonNode) responseDoc.get("tags"));
                    if (tagsSequenceElement != null && tagsSequenceElement instanceof NullNode == false) {
                        Iterator<Map.Entry<String, JsonNode>> itr = tagsSequenceElement.getFields();
                        while (itr.hasNext()) {
                            Map.Entry<String, JsonNode> property = itr.next();
                            String tagsKey2 = property.getKey();
                            String tagsValue2 = property.getValue().getTextValue();
                            storageAccountInstance.getTags().put(tagsKey2, tagsValue2);
                        }
                    }

                    JsonNode propertiesValue2 = responseDoc.get("properties");
                    if (propertiesValue2 != null && propertiesValue2 instanceof NullNode == false) {
                        JsonNode provisioningStateValue = propertiesValue2.get("provisioningState");
                        if (provisioningStateValue != null && provisioningStateValue instanceof NullNode == false) {
                            ProvisioningState provisioningStateInstance;
                            provisioningStateInstance = EnumUtility.fromString(ProvisioningState.class,
                                    provisioningStateValue.getTextValue());
                            storageAccountInstance.setProvisioningState(provisioningStateInstance);
                        }

                        JsonNode accountTypeValue = propertiesValue2.get("accountType");
                        if (accountTypeValue != null && accountTypeValue instanceof NullNode == false) {
                            AccountType accountTypeInstance;
                            accountTypeInstance = StorageManagementClientImpl
                                    .parseAccountType(accountTypeValue.getTextValue());
                            storageAccountInstance.setAccountType(accountTypeInstance);
                        }

                        JsonNode primaryEndpointsValue = propertiesValue2.get("primaryEndpoints");
                        if (primaryEndpointsValue != null && primaryEndpointsValue instanceof NullNode == false) {
                            Endpoints primaryEndpointsInstance = new Endpoints();
                            storageAccountInstance.setPrimaryEndpoints(primaryEndpointsInstance);

                            JsonNode blobValue = primaryEndpointsValue.get("blob");
                            if (blobValue != null && blobValue instanceof NullNode == false) {
                                URI blobInstance;
                                blobInstance = new URI(blobValue.getTextValue());
                                primaryEndpointsInstance.setBlob(blobInstance);
                            }

                            JsonNode queueValue = primaryEndpointsValue.get("queue");
                            if (queueValue != null && queueValue instanceof NullNode == false) {
                                URI queueInstance;
                                queueInstance = new URI(queueValue.getTextValue());
                                primaryEndpointsInstance.setQueue(queueInstance);
                            }

                            JsonNode tableValue = primaryEndpointsValue.get("table");
                            if (tableValue != null && tableValue instanceof NullNode == false) {
                                URI tableInstance;
                                tableInstance = new URI(tableValue.getTextValue());
                                primaryEndpointsInstance.setTable(tableInstance);
                            }

                            JsonNode fileValue = primaryEndpointsValue.get("file");
                            if (fileValue != null && fileValue instanceof NullNode == false) {
                                URI fileInstance;
                                fileInstance = new URI(fileValue.getTextValue());
                                primaryEndpointsInstance.setFile(fileInstance);
                            }
                        }

                        JsonNode primaryLocationValue = propertiesValue2.get("primaryLocation");
                        if (primaryLocationValue != null && primaryLocationValue instanceof NullNode == false) {
                            String primaryLocationInstance;
                            primaryLocationInstance = primaryLocationValue.getTextValue();
                            storageAccountInstance.setPrimaryLocation(primaryLocationInstance);
                        }

                        JsonNode statusOfPrimaryValue = propertiesValue2.get("statusOfPrimary");
                        if (statusOfPrimaryValue != null && statusOfPrimaryValue instanceof NullNode == false) {
                            AccountStatus statusOfPrimaryInstance;
                            statusOfPrimaryInstance = EnumUtility.fromString(AccountStatus.class,
                                    statusOfPrimaryValue.getTextValue());
                            storageAccountInstance.setStatusOfPrimary(statusOfPrimaryInstance);
                        }

                        JsonNode lastGeoFailoverTimeValue = propertiesValue2.get("lastGeoFailoverTime");
                        if (lastGeoFailoverTimeValue != null
                                && lastGeoFailoverTimeValue instanceof NullNode == false) {
                            Calendar lastGeoFailoverTimeInstance;
                            lastGeoFailoverTimeInstance = DatatypeConverter
                                    .parseDateTime(lastGeoFailoverTimeValue.getTextValue());
                            storageAccountInstance.setLastGeoFailoverTime(lastGeoFailoverTimeInstance);
                        }

                        JsonNode secondaryLocationValue = propertiesValue2.get("secondaryLocation");
                        if (secondaryLocationValue != null && secondaryLocationValue instanceof NullNode == false) {
                            String secondaryLocationInstance;
                            secondaryLocationInstance = secondaryLocationValue.getTextValue();
                            storageAccountInstance.setSecondaryLocation(secondaryLocationInstance);
                        }

                        JsonNode statusOfSecondaryValue = propertiesValue2.get("statusOfSecondary");
                        if (statusOfSecondaryValue != null && statusOfSecondaryValue instanceof NullNode == false) {
                            AccountStatus statusOfSecondaryInstance;
                            statusOfSecondaryInstance = EnumUtility.fromString(AccountStatus.class,
                                    statusOfSecondaryValue.getTextValue());
                            storageAccountInstance.setStatusOfSecondary(statusOfSecondaryInstance);
                        }

                        JsonNode creationTimeValue = propertiesValue2.get("creationTime");
                        if (creationTimeValue != null && creationTimeValue instanceof NullNode == false) {
                            Calendar creationTimeInstance;
                            creationTimeInstance = DatatypeConverter
                                    .parseDateTime(creationTimeValue.getTextValue());
                            storageAccountInstance.setCreationTime(creationTimeInstance);
                        }

                        JsonNode customDomainValue2 = propertiesValue2.get("customDomain");
                        if (customDomainValue2 != null && customDomainValue2 instanceof NullNode == false) {
                            CustomDomain customDomainInstance = new CustomDomain();
                            storageAccountInstance.setCustomDomain(customDomainInstance);

                            JsonNode nameValue2 = customDomainValue2.get("name");
                            if (nameValue2 != null && nameValue2 instanceof NullNode == false) {
                                String nameInstance2;
                                nameInstance2 = nameValue2.getTextValue();
                                customDomainInstance.setName(nameInstance2);
                            }

                            JsonNode useSubDomainValue = customDomainValue2.get("useSubDomain");
                            if (useSubDomainValue != null && useSubDomainValue instanceof NullNode == false) {
                                boolean useSubDomainInstance;
                                useSubDomainInstance = useSubDomainValue.getBooleanValue();
                                customDomainInstance.setUseSubDomain(useSubDomainInstance);
                            }
                        }

                        JsonNode secondaryEndpointsValue = propertiesValue2.get("secondaryEndpoints");
                        if (secondaryEndpointsValue != null
                                && secondaryEndpointsValue instanceof NullNode == false) {
                            Endpoints secondaryEndpointsInstance = new Endpoints();
                            storageAccountInstance.setSecondaryEndpoints(secondaryEndpointsInstance);

                            JsonNode blobValue2 = secondaryEndpointsValue.get("blob");
                            if (blobValue2 != null && blobValue2 instanceof NullNode == false) {
                                URI blobInstance2;
                                blobInstance2 = new URI(blobValue2.getTextValue());
                                secondaryEndpointsInstance.setBlob(blobInstance2);
                            }

                            JsonNode queueValue2 = secondaryEndpointsValue.get("queue");
                            if (queueValue2 != null && queueValue2 instanceof NullNode == false) {
                                URI queueInstance2;
                                queueInstance2 = new URI(queueValue2.getTextValue());
                                secondaryEndpointsInstance.setQueue(queueInstance2);
                            }

                            JsonNode tableValue2 = secondaryEndpointsValue.get("table");
                            if (tableValue2 != null && tableValue2 instanceof NullNode == false) {
                                URI tableInstance2;
                                tableInstance2 = new URI(tableValue2.getTextValue());
                                secondaryEndpointsInstance.setTable(tableInstance2);
                            }

                            JsonNode fileValue2 = secondaryEndpointsValue.get("file");
                            if (fileValue2 != null && fileValue2 instanceof NullNode == false) {
                                URI fileInstance2;
                                fileInstance2 = new URI(fileValue2.getTextValue());
                                secondaryEndpointsInstance.setFile(fileInstance2);
                            }
                        }
                    }
                }

            }
            result.setStatusCode(statusCode);
            if (httpResponse.getHeaders("x-ms-request-id").length > 0) {
                result.setRequestId(httpResponse.getFirstHeader("x-ms-request-id").getValue());
            }

            if (shouldTrace) {
                CloudTracing.exit(invocationId, result);
            }
            return result;
        } finally {
            if (httpResponse != null && httpResponse.getEntity() != null) {
                httpResponse.getEntity().getContent().close();
            }
        }
    }
}