com.microsoft.windowsazure.management.compute.ExtensionImageOperationsImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.microsoft.windowsazure.management.compute.ExtensionImageOperationsImpl.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.windowsazure.management.compute;

import com.microsoft.windowsazure.core.LazyCollection;
import com.microsoft.windowsazure.core.OperationResponse;
import com.microsoft.windowsazure.core.OperationStatus;
import com.microsoft.windowsazure.core.OperationStatusResponse;
import com.microsoft.windowsazure.core.ServiceOperations;
import com.microsoft.windowsazure.core.pipeline.apache.CustomHttpDelete;
import com.microsoft.windowsazure.core.utils.Base64;
import com.microsoft.windowsazure.core.utils.CollectionStringBuilder;
import com.microsoft.windowsazure.exception.CloudError;
import com.microsoft.windowsazure.exception.ServiceException;
import com.microsoft.windowsazure.management.compute.models.ExtensionEndpointConfiguration;
import com.microsoft.windowsazure.management.compute.models.ExtensionImageRegisterParameters;
import com.microsoft.windowsazure.management.compute.models.ExtensionImageUpdateParameters;
import com.microsoft.windowsazure.management.compute.models.ExtensionLocalResourceConfiguration;
import com.microsoft.windowsazure.tracing.ClientRequestTrackingHandler;
import com.microsoft.windowsazure.tracing.CloudTracing;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.TimeZone;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
* The Service Management API includes operations for managing the service and
* virtual machine extension images in your publisher subscription.
*/
public class ExtensionImageOperationsImpl
        implements ServiceOperations<ComputeManagementClientImpl>, ExtensionImageOperations {
    /**
    * Initializes a new instance of the ExtensionImageOperationsImpl class.
    *
    * @param client Reference to the service client.
    */
    ExtensionImageOperationsImpl(ComputeManagementClientImpl client) {
        this.client = client;
    }

    private ComputeManagementClientImpl client;

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

    /**
    * Register a new extension. An extension is identified by the combination
    * of its ProviderNamespace and Type (case-sensitive string). It is not
    * allowed to register an extension with the same identity (i.e.
    * combination of ProviderNamespace and Type) of an already-registered
    * extension. To register new version of an existing extension, the Update
    * Extension API should be used.
    *
    * @param parameters Required. Parameters supplied to the Register Virtual
    * Machine Extension Image operation.
    * @return A standard service response including an HTTP status code and
    * request ID.
    */
    @Override
    public Future<OperationResponse> beginRegisteringAsync(final ExtensionImageRegisterParameters parameters) {
        return this.getClient().getExecutorService().submit(new Callable<OperationResponse>() {
            @Override
            public OperationResponse call() throws Exception {
                return beginRegistering(parameters);
            }
        });
    }

    /**
    * Register a new extension. An extension is identified by the combination
    * of its ProviderNamespace and Type (case-sensitive string). It is not
    * allowed to register an extension with the same identity (i.e.
    * combination of ProviderNamespace and Type) of an already-registered
    * extension. To register new version of an existing extension, the Update
    * Extension API should be used.
    *
    * @param parameters Required. Parameters supplied to the Register Virtual
    * Machine Extension Image operation.
    * @throws ParserConfigurationException Thrown if there was an error
    * configuring the parser for the response body.
    * @throws SAXException Thrown if there was an error parsing the response
    * body.
    * @throws TransformerException Thrown if there was an error creating the
    * DOM transformer.
    * @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 beginRegistering(ExtensionImageRegisterParameters parameters)
            throws ParserConfigurationException, SAXException, TransformerException, IOException, ServiceException {
        // Validate
        if (parameters == null) {
            throw new NullPointerException("parameters");
        }
        if (parameters.getCertificate() != null) {
            if (parameters.getCertificate().getStoreLocation() == null) {
                throw new NullPointerException("parameters.Certificate.StoreLocation");
            }
        }
        if (parameters.getExtensionEndpoints() != null) {
            if (parameters.getExtensionEndpoints().getInputEndpoints() != null) {
                for (ExtensionEndpointConfiguration.InputEndpoint inputEndpointsParameterItem : parameters
                        .getExtensionEndpoints().getInputEndpoints()) {
                    if (inputEndpointsParameterItem.getLocalPort() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InputEndpoints.LocalPort");
                    }
                    if (inputEndpointsParameterItem.getName() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InputEndpoints.Name");
                    }
                    if (inputEndpointsParameterItem.getProtocol() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InputEndpoints.Protocol");
                    }
                }
            }
            if (parameters.getExtensionEndpoints().getInstanceInputEndpoints() != null) {
                for (ExtensionEndpointConfiguration.InstanceInputEndpoint instanceInputEndpointsParameterItem : parameters
                        .getExtensionEndpoints().getInstanceInputEndpoints()) {
                    if (instanceInputEndpointsParameterItem.getLocalPort() == null) {
                        throw new NullPointerException(
                                "parameters.ExtensionEndpoints.InstanceInputEndpoints.LocalPort");
                    }
                    if (instanceInputEndpointsParameterItem.getName() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InstanceInputEndpoints.Name");
                    }
                    if (instanceInputEndpointsParameterItem.getProtocol() == null) {
                        throw new NullPointerException(
                                "parameters.ExtensionEndpoints.InstanceInputEndpoints.Protocol");
                    }
                }
            }
            if (parameters.getExtensionEndpoints().getInternalEndpoints() != null) {
                for (ExtensionEndpointConfiguration.InternalEndpoint internalEndpointsParameterItem : parameters
                        .getExtensionEndpoints().getInternalEndpoints()) {
                    if (internalEndpointsParameterItem.getName() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InternalEndpoints.Name");
                    }
                    if (internalEndpointsParameterItem.getProtocol() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InternalEndpoints.Protocol");
                    }
                }
            }
        }
        if (parameters.getLocalResources() != null) {
            for (ExtensionLocalResourceConfiguration localResourcesParameterItem : parameters.getLocalResources()) {
                if (localResourcesParameterItem.getName() == null) {
                    throw new NullPointerException("parameters.LocalResources.Name");
                }
            }
        }
        if (parameters.getProviderNameSpace() == null) {
            throw new NullPointerException("parameters.ProviderNameSpace");
        }
        if (parameters.getType() == null) {
            throw new NullPointerException("parameters.Type");
        }
        if (parameters.getVersion() == null) {
            throw new NullPointerException("parameters.Version");
        }

        // 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("parameters", parameters);
            CloudTracing.enter(invocationId, this, "beginRegisteringAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/services/extensions";
        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/xml");
        httpRequest.setHeader("x-ms-version", "2015-04-01");

        // Serialize Request
        String requestContent = null;
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document requestDoc = documentBuilder.newDocument();

        Element extensionImageElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                "ExtensionImage");
        requestDoc.appendChild(extensionImageElement);

        Element providerNameSpaceElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                "ProviderNameSpace");
        providerNameSpaceElement.appendChild(requestDoc.createTextNode(parameters.getProviderNameSpace()));
        extensionImageElement.appendChild(providerNameSpaceElement);

        Element typeElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure", "Type");
        typeElement.appendChild(requestDoc.createTextNode(parameters.getType()));
        extensionImageElement.appendChild(typeElement);

        Element versionElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure", "Version");
        versionElement.appendChild(requestDoc.createTextNode(parameters.getVersion()));
        extensionImageElement.appendChild(versionElement);

        if (parameters.getLabel() != null) {
            Element labelElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure", "Label");
            labelElement.appendChild(requestDoc.createTextNode(parameters.getLabel()));
            extensionImageElement.appendChild(labelElement);
        }

        if (parameters.getHostingResources() != null) {
            Element hostingResourcesElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "HostingResources");
            hostingResourcesElement.appendChild(requestDoc.createTextNode(parameters.getHostingResources()));
            extensionImageElement.appendChild(hostingResourcesElement);
        }

        if (parameters.getMediaLink() != null) {
            Element mediaLinkElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "MediaLink");
            mediaLinkElement.appendChild(requestDoc.createTextNode(parameters.getMediaLink().toString()));
            extensionImageElement.appendChild(mediaLinkElement);
        }

        if (parameters.getCertificate() != null) {
            Element certificateElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "Certificate");
            extensionImageElement.appendChild(certificateElement);

            Element storeLocationElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "StoreLocation");
            storeLocationElement
                    .appendChild(requestDoc.createTextNode(parameters.getCertificate().getStoreLocation()));
            certificateElement.appendChild(storeLocationElement);

            if (parameters.getCertificate().getStoreName() != null) {
                Element storeNameElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                        "StoreName");
                storeNameElement.appendChild(requestDoc.createTextNode(parameters.getCertificate().getStoreName()));
                certificateElement.appendChild(storeNameElement);
            }

            if (parameters.getCertificate().isThumbprintRequired() != null) {
                Element thumbprintRequiredElement = requestDoc
                        .createElementNS("http://schemas.microsoft.com/windowsazure", "ThumbprintRequired");
                thumbprintRequiredElement.appendChild(requestDoc.createTextNode(
                        Boolean.toString(parameters.getCertificate().isThumbprintRequired()).toLowerCase()));
                certificateElement.appendChild(thumbprintRequiredElement);
            }

            if (parameters.getCertificate().getThumbprintAlgorithm() != null) {
                Element thumbprintAlgorithmElement = requestDoc
                        .createElementNS("http://schemas.microsoft.com/windowsazure", "ThumbprintAlgorithm");
                thumbprintAlgorithmElement.appendChild(
                        requestDoc.createTextNode(parameters.getCertificate().getThumbprintAlgorithm()));
                certificateElement.appendChild(thumbprintAlgorithmElement);
            }
        }

        if (parameters.getExtensionEndpoints() != null) {
            Element endpointsElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "Endpoints");
            extensionImageElement.appendChild(endpointsElement);

            if (parameters.getExtensionEndpoints().getInputEndpoints() != null) {
                if (parameters.getExtensionEndpoints().getInputEndpoints() instanceof LazyCollection == false
                        || ((LazyCollection) parameters.getExtensionEndpoints().getInputEndpoints())
                                .isInitialized()) {
                    Element inputEndpointsSequenceElement = requestDoc
                            .createElementNS("http://schemas.microsoft.com/windowsazure", "InputEndpoints");
                    for (ExtensionEndpointConfiguration.InputEndpoint inputEndpointsItem : parameters
                            .getExtensionEndpoints().getInputEndpoints()) {
                        Element inputEndpointElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "InputEndpoint");
                        inputEndpointsSequenceElement.appendChild(inputEndpointElement);

                        Element nameElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Name");
                        nameElement.appendChild(requestDoc.createTextNode(inputEndpointsItem.getName()));
                        inputEndpointElement.appendChild(nameElement);

                        Element protocolElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Protocol");
                        protocolElement.appendChild(requestDoc.createTextNode(inputEndpointsItem.getProtocol()));
                        inputEndpointElement.appendChild(protocolElement);

                        Element portElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Port");
                        portElement.appendChild(
                                requestDoc.createTextNode(Integer.toString(inputEndpointsItem.getPort())));
                        inputEndpointElement.appendChild(portElement);

                        Element localPortElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "LocalPort");
                        localPortElement.appendChild(requestDoc.createTextNode(inputEndpointsItem.getLocalPort()));
                        inputEndpointElement.appendChild(localPortElement);
                    }
                    endpointsElement.appendChild(inputEndpointsSequenceElement);
                }
            }

            if (parameters.getExtensionEndpoints().getInternalEndpoints() != null) {
                if (parameters.getExtensionEndpoints().getInternalEndpoints() instanceof LazyCollection == false
                        || ((LazyCollection) parameters.getExtensionEndpoints().getInternalEndpoints())
                                .isInitialized()) {
                    Element internalEndpointsSequenceElement = requestDoc
                            .createElementNS("http://schemas.microsoft.com/windowsazure", "InternalEndpoints");
                    for (ExtensionEndpointConfiguration.InternalEndpoint internalEndpointsItem : parameters
                            .getExtensionEndpoints().getInternalEndpoints()) {
                        Element internalEndpointElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "InternalEndpoint");
                        internalEndpointsSequenceElement.appendChild(internalEndpointElement);

                        Element nameElement2 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Name");
                        nameElement2.appendChild(requestDoc.createTextNode(internalEndpointsItem.getName()));
                        internalEndpointElement.appendChild(nameElement2);

                        Element protocolElement2 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Protocol");
                        protocolElement2
                                .appendChild(requestDoc.createTextNode(internalEndpointsItem.getProtocol()));
                        internalEndpointElement.appendChild(protocolElement2);

                        Element portElement2 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Port");
                        portElement2.appendChild(
                                requestDoc.createTextNode(Integer.toString(internalEndpointsItem.getPort())));
                        internalEndpointElement.appendChild(portElement2);
                    }
                    endpointsElement.appendChild(internalEndpointsSequenceElement);
                }
            }

            if (parameters.getExtensionEndpoints().getInstanceInputEndpoints() != null) {
                if (parameters.getExtensionEndpoints()
                        .getInstanceInputEndpoints() instanceof LazyCollection == false
                        || ((LazyCollection) parameters.getExtensionEndpoints().getInstanceInputEndpoints())
                                .isInitialized()) {
                    Element instanceInputEndpointsSequenceElement = requestDoc
                            .createElementNS("http://schemas.microsoft.com/windowsazure", "InstanceInputEndpoints");
                    for (ExtensionEndpointConfiguration.InstanceInputEndpoint instanceInputEndpointsItem : parameters
                            .getExtensionEndpoints().getInstanceInputEndpoints()) {
                        Element instanceInputEndpointElement = requestDoc.createElementNS(
                                "http://schemas.microsoft.com/windowsazure", "InstanceInputEndpoint");
                        instanceInputEndpointsSequenceElement.appendChild(instanceInputEndpointElement);

                        Element nameElement3 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Name");
                        nameElement3.appendChild(requestDoc.createTextNode(instanceInputEndpointsItem.getName()));
                        instanceInputEndpointElement.appendChild(nameElement3);

                        Element protocolElement3 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Protocol");
                        protocolElement3
                                .appendChild(requestDoc.createTextNode(instanceInputEndpointsItem.getProtocol()));
                        instanceInputEndpointElement.appendChild(protocolElement3);

                        Element localPortElement2 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "LocalPort");
                        localPortElement2
                                .appendChild(requestDoc.createTextNode(instanceInputEndpointsItem.getLocalPort()));
                        instanceInputEndpointElement.appendChild(localPortElement2);

                        Element fixedPortMinElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "FixedPortMin");
                        fixedPortMinElement.appendChild(requestDoc
                                .createTextNode(Integer.toString(instanceInputEndpointsItem.getFixedPortMin())));
                        instanceInputEndpointElement.appendChild(fixedPortMinElement);

                        Element fixedPortMaxElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "FixedPortMax");
                        fixedPortMaxElement.appendChild(requestDoc
                                .createTextNode(Integer.toString(instanceInputEndpointsItem.getFixedPortMax())));
                        instanceInputEndpointElement.appendChild(fixedPortMaxElement);
                    }
                    endpointsElement.appendChild(instanceInputEndpointsSequenceElement);
                }
            }
        }

        if (parameters.getPublicConfigurationSchema() != null) {
            Element publicConfigurationSchemaElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "PublicConfigurationSchema");
            publicConfigurationSchemaElement.appendChild(
                    requestDoc.createTextNode(Base64.encode(parameters.getPublicConfigurationSchema().getBytes())));
            extensionImageElement.appendChild(publicConfigurationSchemaElement);
        }

        if (parameters.getPrivateConfigurationSchema() != null) {
            Element privateConfigurationSchemaElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "PrivateConfigurationSchema");
            privateConfigurationSchemaElement.appendChild(requestDoc
                    .createTextNode(Base64.encode(parameters.getPrivateConfigurationSchema().getBytes())));
            extensionImageElement.appendChild(privateConfigurationSchemaElement);
        }

        if (parameters.getDescription() != null) {
            Element descriptionElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "Description");
            descriptionElement.appendChild(requestDoc.createTextNode(parameters.getDescription()));
            extensionImageElement.appendChild(descriptionElement);
        }

        if (parameters.getPublisherName() != null) {
            Element publisherNameElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "PublisherName");
            publisherNameElement.appendChild(requestDoc.createTextNode(parameters.getPublisherName()));
            extensionImageElement.appendChild(publisherNameElement);
        }

        if (parameters.getPublishedDate() != null) {
            Element publishedDateElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "PublishedDate");
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
            simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
            publishedDateElement.appendChild(
                    requestDoc.createTextNode(simpleDateFormat.format(parameters.getPublishedDate().getTime())));
            extensionImageElement.appendChild(publishedDateElement);
        }

        if (parameters.getLocalResources() != null) {
            Element localResourcesSequenceElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "LocalResources");
            for (ExtensionLocalResourceConfiguration localResourcesItem : parameters.getLocalResources()) {
                Element localResourceElement = requestDoc
                        .createElementNS("http://schemas.microsoft.com/windowsazure", "LocalResource");
                localResourcesSequenceElement.appendChild(localResourceElement);

                Element nameElement4 = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                        "Name");
                nameElement4.appendChild(requestDoc.createTextNode(localResourcesItem.getName()));
                localResourceElement.appendChild(nameElement4);

                if (localResourcesItem.getSizeInMB() != null) {
                    Element sizeInMBElement = requestDoc
                            .createElementNS("http://schemas.microsoft.com/windowsazure", "SizeInMB");
                    sizeInMBElement.appendChild(
                            requestDoc.createTextNode(Integer.toString(localResourcesItem.getSizeInMB())));
                    localResourceElement.appendChild(sizeInMBElement);
                }
            }
            extensionImageElement.appendChild(localResourcesSequenceElement);
        }

        if (parameters.isBlockRoleUponFailure() != null) {
            Element blockRoleUponFailureElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "BlockRoleUponFailure");
            blockRoleUponFailureElement.appendChild(
                    requestDoc.createTextNode(Boolean.toString(parameters.isBlockRoleUponFailure()).toLowerCase()));
            extensionImageElement.appendChild(blockRoleUponFailureElement);
        }

        if (parameters.isInternalExtension() != null) {
            Element isInternalExtensionElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "IsInternalExtension");
            isInternalExtensionElement.appendChild(
                    requestDoc.createTextNode(Boolean.toString(parameters.isInternalExtension()).toLowerCase()));
            extensionImageElement.appendChild(isInternalExtensionElement);
        }

        if (parameters.getSampleConfig() != null) {
            Element sampleConfigElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "SampleConfig");
            sampleConfigElement
                    .appendChild(requestDoc.createTextNode(Base64.encode(parameters.getSampleConfig().getBytes())));
            extensionImageElement.appendChild(sampleConfigElement);
        }

        if (parameters.isReplicationCompleted() != null) {
            Element replicationCompletedElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "ReplicationCompleted");
            replicationCompletedElement.appendChild(
                    requestDoc.createTextNode(Boolean.toString(parameters.isReplicationCompleted()).toLowerCase()));
            extensionImageElement.appendChild(replicationCompletedElement);
        }

        if (parameters.getEula() != null) {
            Element eulaElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure", "Eula");
            eulaElement.appendChild(requestDoc.createTextNode(parameters.getEula().toString()));
            extensionImageElement.appendChild(eulaElement);
        }

        if (parameters.getPrivacyUri() != null) {
            Element privacyUriElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "PrivacyUri");
            privacyUriElement.appendChild(requestDoc.createTextNode(parameters.getPrivacyUri().toString()));
            extensionImageElement.appendChild(privacyUriElement);
        }

        if (parameters.getHomepageUri() != null) {
            Element homepageUriElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "HomepageUri");
            homepageUriElement.appendChild(requestDoc.createTextNode(parameters.getHomepageUri().toString()));
            extensionImageElement.appendChild(homepageUriElement);
        }

        if (parameters.isJsonExtension() != null) {
            Element isJsonExtensionElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "IsJsonExtension");
            isJsonExtensionElement.appendChild(
                    requestDoc.createTextNode(Boolean.toString(parameters.isJsonExtension()).toLowerCase()));
            extensionImageElement.appendChild(isJsonExtensionElement);
        }

        if (parameters.isDisallowMajorVersionUpgrade() != null) {
            Element disallowMajorVersionUpgradeElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "DisallowMajorVersionUpgrade");
            disallowMajorVersionUpgradeElement.appendChild(requestDoc
                    .createTextNode(Boolean.toString(parameters.isDisallowMajorVersionUpgrade()).toLowerCase()));
            extensionImageElement.appendChild(disallowMajorVersionUpgradeElement);
        }

        if (parameters.getSupportedOS() != null) {
            Element supportedOSElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "SupportedOS");
            supportedOSElement.appendChild(requestDoc.createTextNode(parameters.getSupportedOS()));
            extensionImageElement.appendChild(supportedOSElement);
        }

        if (parameters.getCompanyName() != null) {
            Element companyNameElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "CompanyName");
            companyNameElement.appendChild(requestDoc.createTextNode(parameters.getCompanyName()));
            extensionImageElement.appendChild(companyNameElement);
        }

        if (parameters.getRegions() != null) {
            Element regionsElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "Regions");
            regionsElement.appendChild(requestDoc.createTextNode(parameters.getRegions()));
            extensionImageElement.appendChild(regionsElement);
        }

        DOMSource domSource = new DOMSource(requestDoc);
        StringWriter stringWriter = new StringWriter();
        StreamResult streamResult = new StreamResult(stringWriter);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.transform(domSource, streamResult);
        requestContent = stringWriter.toString();
        StringEntity entity = new StringEntity(requestContent);
        httpRequest.setEntity(entity);
        httpRequest.setHeader("Content-Type", "application/xml");

        // 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_ACCEPTED) {
                ServiceException ex = ServiceException.createFromXml(httpRequest, requestContent, 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();
            }
        }
    }

    /**
    * Unregister a version of an extension that was previously registered using
    * either the Register Extension or Update Extension APIs. An extension
    * version is identified by the combination of its ProviderNamespace, Type
    * and Version which are specified when registering the extension.
    * Unregistering is only allowed for internal extensions, that is, the
    * extensions for which the IsInternalExtension field is set to 'true'
    * during registration or during an update. There is a quota (15) on the
    * number of extensions that can be registered per subscription. If your
    * subscription runs out of quota, you will wither need to unregister some
    * of the internal extensions or contact Azure (same email used to become a
    * publisher)  to increase the quota.
    *
    * @param providerNamespace Required. The provider namespace of the
    * extension image to unregister.
    * @param type Required. The type of the extension image to unregister.
    * @param version Required. The version of the extension image to unregister.
    * @return A standard service response including an HTTP status code and
    * request ID.
    */
    @Override
    public Future<OperationResponse> beginUnregisteringAsync(final String providerNamespace, final String type,
            final String version) {
        return this.getClient().getExecutorService().submit(new Callable<OperationResponse>() {
            @Override
            public OperationResponse call() throws Exception {
                return beginUnregistering(providerNamespace, type, version);
            }
        });
    }

    /**
    * Unregister a version of an extension that was previously registered using
    * either the Register Extension or Update Extension APIs. An extension
    * version is identified by the combination of its ProviderNamespace, Type
    * and Version which are specified when registering the extension.
    * Unregistering is only allowed for internal extensions, that is, the
    * extensions for which the IsInternalExtension field is set to 'true'
    * during registration or during an update. There is a quota (15) on the
    * number of extensions that can be registered per subscription. If your
    * subscription runs out of quota, you will wither need to unregister some
    * of the internal extensions or contact Azure (same email used to become a
    * publisher)  to increase the quota.
    *
    * @param providerNamespace Required. The provider namespace of the
    * extension image to unregister.
    * @param type Required. The type of the extension image to unregister.
    * @param version Required. The version of the extension image to unregister.
    * @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 beginUnregistering(String providerNamespace, String type, String version)
            throws IOException, ServiceException {
        // Validate
        if (providerNamespace == null) {
            throw new NullPointerException("providerNamespace");
        }
        if (type == null) {
            throw new NullPointerException("type");
        }
        if (version == null) {
            throw new NullPointerException("version");
        }

        // 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("providerNamespace", providerNamespace);
            tracingParameters.put("type", type);
            tracingParameters.put("version", version);
            CloudTracing.enter(invocationId, this, "beginUnregisteringAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/services/extensions/";
        url = url + URLEncoder.encode(providerNamespace, "UTF-8");
        url = url + "/";
        url = url + URLEncoder.encode(type, "UTF-8");
        url = url + "/";
        url = url + URLEncoder.encode(version, "UTF-8");
        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("Content-Type", "application/xml");
        httpRequest.setHeader("x-ms-version", "2015-04-01");

        // 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_ACCEPTED) {
                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();
            }
        }
    }

    /**
    * Update a new extension. It is allowed to update an extension which had
    * already been registered with the same identity (i.e. combination of
    * ProviderNamespace and Type) but with different version. It will fail if
    * the extension to update has an identity that has not been registered
    * before, or there is already an extension with the same identity and same
    * version.
    *
    * @param parameters Required. Parameters supplied to the Update Virtual
    * Machine Extension Image operation.
    * @return A standard service response including an HTTP status code and
    * request ID.
    */
    @Override
    public Future<OperationResponse> beginUpdatingAsync(final ExtensionImageUpdateParameters parameters) {
        return this.getClient().getExecutorService().submit(new Callable<OperationResponse>() {
            @Override
            public OperationResponse call() throws Exception {
                return beginUpdating(parameters);
            }
        });
    }

    /**
    * Update a new extension. It is allowed to update an extension which had
    * already been registered with the same identity (i.e. combination of
    * ProviderNamespace and Type) but with different version. It will fail if
    * the extension to update has an identity that has not been registered
    * before, or there is already an extension with the same identity and same
    * version.
    *
    * @param parameters Required. Parameters supplied to the Update Virtual
    * Machine Extension Image operation.
    * @throws ParserConfigurationException Thrown if there was an error
    * configuring the parser for the response body.
    * @throws SAXException Thrown if there was an error parsing the response
    * body.
    * @throws TransformerException Thrown if there was an error creating the
    * DOM transformer.
    * @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 beginUpdating(ExtensionImageUpdateParameters parameters)
            throws ParserConfigurationException, SAXException, TransformerException, IOException, ServiceException {
        // Validate
        if (parameters == null) {
            throw new NullPointerException("parameters");
        }
        if (parameters.getCertificate() != null) {
            if (parameters.getCertificate().getStoreLocation() == null) {
                throw new NullPointerException("parameters.Certificate.StoreLocation");
            }
        }
        if (parameters.getExtensionEndpoints() != null) {
            if (parameters.getExtensionEndpoints().getInputEndpoints() != null) {
                for (ExtensionEndpointConfiguration.InputEndpoint inputEndpointsParameterItem : parameters
                        .getExtensionEndpoints().getInputEndpoints()) {
                    if (inputEndpointsParameterItem.getLocalPort() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InputEndpoints.LocalPort");
                    }
                    if (inputEndpointsParameterItem.getName() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InputEndpoints.Name");
                    }
                    if (inputEndpointsParameterItem.getProtocol() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InputEndpoints.Protocol");
                    }
                }
            }
            if (parameters.getExtensionEndpoints().getInstanceInputEndpoints() != null) {
                for (ExtensionEndpointConfiguration.InstanceInputEndpoint instanceInputEndpointsParameterItem : parameters
                        .getExtensionEndpoints().getInstanceInputEndpoints()) {
                    if (instanceInputEndpointsParameterItem.getLocalPort() == null) {
                        throw new NullPointerException(
                                "parameters.ExtensionEndpoints.InstanceInputEndpoints.LocalPort");
                    }
                    if (instanceInputEndpointsParameterItem.getName() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InstanceInputEndpoints.Name");
                    }
                    if (instanceInputEndpointsParameterItem.getProtocol() == null) {
                        throw new NullPointerException(
                                "parameters.ExtensionEndpoints.InstanceInputEndpoints.Protocol");
                    }
                }
            }
            if (parameters.getExtensionEndpoints().getInternalEndpoints() != null) {
                for (ExtensionEndpointConfiguration.InternalEndpoint internalEndpointsParameterItem : parameters
                        .getExtensionEndpoints().getInternalEndpoints()) {
                    if (internalEndpointsParameterItem.getName() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InternalEndpoints.Name");
                    }
                    if (internalEndpointsParameterItem.getProtocol() == null) {
                        throw new NullPointerException("parameters.ExtensionEndpoints.InternalEndpoints.Protocol");
                    }
                }
            }
        }
        if (parameters.getLocalResources() != null) {
            for (ExtensionLocalResourceConfiguration localResourcesParameterItem : parameters.getLocalResources()) {
                if (localResourcesParameterItem.getName() == null) {
                    throw new NullPointerException("parameters.LocalResources.Name");
                }
            }
        }
        if (parameters.getProviderNameSpace() == null) {
            throw new NullPointerException("parameters.ProviderNameSpace");
        }
        if (parameters.getType() == null) {
            throw new NullPointerException("parameters.Type");
        }
        if (parameters.getVersion() == null) {
            throw new NullPointerException("parameters.Version");
        }

        // 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("parameters", parameters);
            CloudTracing.enter(invocationId, this, "beginUpdatingAsync", tracingParameters);
        }

        // Construct URL
        String url = "";
        url = url + "/";
        if (this.getClient().getCredentials().getSubscriptionId() != null) {
            url = url + URLEncoder.encode(this.getClient().getCredentials().getSubscriptionId(), "UTF-8");
        }
        url = url + "/services/extensions";
        ArrayList<String> queryParameters = new ArrayList<String>();
        queryParameters.add("action=update");
        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/xml");
        httpRequest.setHeader("x-ms-version", "2015-04-01");

        // Serialize Request
        String requestContent = null;
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document requestDoc = documentBuilder.newDocument();

        Element extensionImageElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                "ExtensionImage");
        requestDoc.appendChild(extensionImageElement);

        Element providerNameSpaceElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                "ProviderNameSpace");
        providerNameSpaceElement.appendChild(requestDoc.createTextNode(parameters.getProviderNameSpace()));
        extensionImageElement.appendChild(providerNameSpaceElement);

        Element typeElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure", "Type");
        typeElement.appendChild(requestDoc.createTextNode(parameters.getType()));
        extensionImageElement.appendChild(typeElement);

        Element versionElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure", "Version");
        versionElement.appendChild(requestDoc.createTextNode(parameters.getVersion()));
        extensionImageElement.appendChild(versionElement);

        if (parameters.getLabel() != null) {
            Element labelElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure", "Label");
            labelElement.appendChild(requestDoc.createTextNode(parameters.getLabel()));
            extensionImageElement.appendChild(labelElement);
        }

        if (parameters.getHostingResources() != null) {
            Element hostingResourcesElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "HostingResources");
            hostingResourcesElement.appendChild(requestDoc.createTextNode(parameters.getHostingResources()));
            extensionImageElement.appendChild(hostingResourcesElement);
        }

        if (parameters.getMediaLink() != null) {
            Element mediaLinkElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "MediaLink");
            mediaLinkElement.appendChild(requestDoc.createTextNode(parameters.getMediaLink().toString()));
            extensionImageElement.appendChild(mediaLinkElement);
        }

        if (parameters.getCertificate() != null) {
            Element certificateElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "Certificate");
            extensionImageElement.appendChild(certificateElement);

            Element storeLocationElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "StoreLocation");
            storeLocationElement
                    .appendChild(requestDoc.createTextNode(parameters.getCertificate().getStoreLocation()));
            certificateElement.appendChild(storeLocationElement);

            if (parameters.getCertificate().getStoreName() != null) {
                Element storeNameElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                        "StoreName");
                storeNameElement.appendChild(requestDoc.createTextNode(parameters.getCertificate().getStoreName()));
                certificateElement.appendChild(storeNameElement);
            }

            if (parameters.getCertificate().isThumbprintRequired() != null) {
                Element thumbprintRequiredElement = requestDoc
                        .createElementNS("http://schemas.microsoft.com/windowsazure", "ThumbprintRequired");
                thumbprintRequiredElement.appendChild(requestDoc.createTextNode(
                        Boolean.toString(parameters.getCertificate().isThumbprintRequired()).toLowerCase()));
                certificateElement.appendChild(thumbprintRequiredElement);
            }

            if (parameters.getCertificate().getThumbprintAlgorithm() != null) {
                Element thumbprintAlgorithmElement = requestDoc
                        .createElementNS("http://schemas.microsoft.com/windowsazure", "ThumbprintAlgorithm");
                thumbprintAlgorithmElement.appendChild(
                        requestDoc.createTextNode(parameters.getCertificate().getThumbprintAlgorithm()));
                certificateElement.appendChild(thumbprintAlgorithmElement);
            }
        }

        if (parameters.getExtensionEndpoints() != null) {
            Element endpointsElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "Endpoints");
            extensionImageElement.appendChild(endpointsElement);

            if (parameters.getExtensionEndpoints().getInputEndpoints() != null) {
                if (parameters.getExtensionEndpoints().getInputEndpoints() instanceof LazyCollection == false
                        || ((LazyCollection) parameters.getExtensionEndpoints().getInputEndpoints())
                                .isInitialized()) {
                    Element inputEndpointsSequenceElement = requestDoc
                            .createElementNS("http://schemas.microsoft.com/windowsazure", "InputEndpoints");
                    for (ExtensionEndpointConfiguration.InputEndpoint inputEndpointsItem : parameters
                            .getExtensionEndpoints().getInputEndpoints()) {
                        Element inputEndpointElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "InputEndpoint");
                        inputEndpointsSequenceElement.appendChild(inputEndpointElement);

                        Element nameElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Name");
                        nameElement.appendChild(requestDoc.createTextNode(inputEndpointsItem.getName()));
                        inputEndpointElement.appendChild(nameElement);

                        Element protocolElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Protocol");
                        protocolElement.appendChild(requestDoc.createTextNode(inputEndpointsItem.getProtocol()));
                        inputEndpointElement.appendChild(protocolElement);

                        Element portElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Port");
                        portElement.appendChild(
                                requestDoc.createTextNode(Integer.toString(inputEndpointsItem.getPort())));
                        inputEndpointElement.appendChild(portElement);

                        Element localPortElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "LocalPort");
                        localPortElement.appendChild(requestDoc.createTextNode(inputEndpointsItem.getLocalPort()));
                        inputEndpointElement.appendChild(localPortElement);
                    }
                    endpointsElement.appendChild(inputEndpointsSequenceElement);
                }
            }

            if (parameters.getExtensionEndpoints().getInternalEndpoints() != null) {
                if (parameters.getExtensionEndpoints().getInternalEndpoints() instanceof LazyCollection == false
                        || ((LazyCollection) parameters.getExtensionEndpoints().getInternalEndpoints())
                                .isInitialized()) {
                    Element internalEndpointsSequenceElement = requestDoc
                            .createElementNS("http://schemas.microsoft.com/windowsazure", "InternalEndpoints");
                    for (ExtensionEndpointConfiguration.InternalEndpoint internalEndpointsItem : parameters
                            .getExtensionEndpoints().getInternalEndpoints()) {
                        Element internalEndpointElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "InternalEndpoint");
                        internalEndpointsSequenceElement.appendChild(internalEndpointElement);

                        Element nameElement2 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Name");
                        nameElement2.appendChild(requestDoc.createTextNode(internalEndpointsItem.getName()));
                        internalEndpointElement.appendChild(nameElement2);

                        Element protocolElement2 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Protocol");
                        protocolElement2
                                .appendChild(requestDoc.createTextNode(internalEndpointsItem.getProtocol()));
                        internalEndpointElement.appendChild(protocolElement2);

                        Element portElement2 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Port");
                        portElement2.appendChild(
                                requestDoc.createTextNode(Integer.toString(internalEndpointsItem.getPort())));
                        internalEndpointElement.appendChild(portElement2);
                    }
                    endpointsElement.appendChild(internalEndpointsSequenceElement);
                }
            }

            if (parameters.getExtensionEndpoints().getInstanceInputEndpoints() != null) {
                if (parameters.getExtensionEndpoints()
                        .getInstanceInputEndpoints() instanceof LazyCollection == false
                        || ((LazyCollection) parameters.getExtensionEndpoints().getInstanceInputEndpoints())
                                .isInitialized()) {
                    Element instanceInputEndpointsSequenceElement = requestDoc
                            .createElementNS("http://schemas.microsoft.com/windowsazure", "InstanceInputEndpoints");
                    for (ExtensionEndpointConfiguration.InstanceInputEndpoint instanceInputEndpointsItem : parameters
                            .getExtensionEndpoints().getInstanceInputEndpoints()) {
                        Element instanceInputEndpointElement = requestDoc.createElementNS(
                                "http://schemas.microsoft.com/windowsazure", "InstanceInputEndpoint");
                        instanceInputEndpointsSequenceElement.appendChild(instanceInputEndpointElement);

                        Element nameElement3 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Name");
                        nameElement3.appendChild(requestDoc.createTextNode(instanceInputEndpointsItem.getName()));
                        instanceInputEndpointElement.appendChild(nameElement3);

                        Element protocolElement3 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "Protocol");
                        protocolElement3
                                .appendChild(requestDoc.createTextNode(instanceInputEndpointsItem.getProtocol()));
                        instanceInputEndpointElement.appendChild(protocolElement3);

                        Element localPortElement2 = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "LocalPort");
                        localPortElement2
                                .appendChild(requestDoc.createTextNode(instanceInputEndpointsItem.getLocalPort()));
                        instanceInputEndpointElement.appendChild(localPortElement2);

                        Element fixedPortMinElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "FixedPortMin");
                        fixedPortMinElement.appendChild(requestDoc
                                .createTextNode(Integer.toString(instanceInputEndpointsItem.getFixedPortMin())));
                        instanceInputEndpointElement.appendChild(fixedPortMinElement);

                        Element fixedPortMaxElement = requestDoc
                                .createElementNS("http://schemas.microsoft.com/windowsazure", "FixedPortMax");
                        fixedPortMaxElement.appendChild(requestDoc
                                .createTextNode(Integer.toString(instanceInputEndpointsItem.getFixedPortMax())));
                        instanceInputEndpointElement.appendChild(fixedPortMaxElement);
                    }
                    endpointsElement.appendChild(instanceInputEndpointsSequenceElement);
                }
            }
        }

        if (parameters.getPublicConfigurationSchema() != null) {
            Element publicConfigurationSchemaElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "PublicConfigurationSchema");
            publicConfigurationSchemaElement.appendChild(
                    requestDoc.createTextNode(Base64.encode(parameters.getPublicConfigurationSchema().getBytes())));
            extensionImageElement.appendChild(publicConfigurationSchemaElement);
        }

        if (parameters.getPrivateConfigurationSchema() != null) {
            Element privateConfigurationSchemaElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "PrivateConfigurationSchema");
            privateConfigurationSchemaElement.appendChild(requestDoc
                    .createTextNode(Base64.encode(parameters.getPrivateConfigurationSchema().getBytes())));
            extensionImageElement.appendChild(privateConfigurationSchemaElement);
        }

        if (parameters.getDescription() != null) {
            Element descriptionElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "Description");
            descriptionElement.appendChild(requestDoc.createTextNode(parameters.getDescription()));
            extensionImageElement.appendChild(descriptionElement);
        }

        if (parameters.getPublisherName() != null) {
            Element publisherNameElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "PublisherName");
            publisherNameElement.appendChild(requestDoc.createTextNode(parameters.getPublisherName()));
            extensionImageElement.appendChild(publisherNameElement);
        }

        if (parameters.getPublishedDate() != null) {
            Element publishedDateElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "PublishedDate");
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
            simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
            publishedDateElement.appendChild(
                    requestDoc.createTextNode(simpleDateFormat.format(parameters.getPublishedDate().getTime())));
            extensionImageElement.appendChild(publishedDateElement);
        }

        if (parameters.getLocalResources() != null) {
            Element localResourcesSequenceElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "LocalResources");
            for (ExtensionLocalResourceConfiguration localResourcesItem : parameters.getLocalResources()) {
                Element localResourceElement = requestDoc
                        .createElementNS("http://schemas.microsoft.com/windowsazure", "LocalResource");
                localResourcesSequenceElement.appendChild(localResourceElement);

                Element nameElement4 = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                        "Name");
                nameElement4.appendChild(requestDoc.createTextNode(localResourcesItem.getName()));
                localResourceElement.appendChild(nameElement4);

                if (localResourcesItem.getSizeInMB() != null) {
                    Element sizeInMBElement = requestDoc
                            .createElementNS("http://schemas.microsoft.com/windowsazure", "SizeInMB");
                    sizeInMBElement.appendChild(
                            requestDoc.createTextNode(Integer.toString(localResourcesItem.getSizeInMB())));
                    localResourceElement.appendChild(sizeInMBElement);
                }
            }
            extensionImageElement.appendChild(localResourcesSequenceElement);
        }

        if (parameters.isBlockRoleUponFailure() != null) {
            Element blockRoleUponFailureElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "BlockRoleUponFailure");
            blockRoleUponFailureElement.appendChild(
                    requestDoc.createTextNode(Boolean.toString(parameters.isBlockRoleUponFailure()).toLowerCase()));
            extensionImageElement.appendChild(blockRoleUponFailureElement);
        }

        if (parameters.isInternalExtension() != null) {
            Element isInternalExtensionElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "IsInternalExtension");
            isInternalExtensionElement.appendChild(
                    requestDoc.createTextNode(Boolean.toString(parameters.isInternalExtension()).toLowerCase()));
            extensionImageElement.appendChild(isInternalExtensionElement);
        }

        if (parameters.getSampleConfig() != null) {
            Element sampleConfigElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "SampleConfig");
            sampleConfigElement
                    .appendChild(requestDoc.createTextNode(Base64.encode(parameters.getSampleConfig().getBytes())));
            extensionImageElement.appendChild(sampleConfigElement);
        }

        if (parameters.isReplicationCompleted() != null) {
            Element replicationCompletedElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "ReplicationCompleted");
            replicationCompletedElement.appendChild(
                    requestDoc.createTextNode(Boolean.toString(parameters.isReplicationCompleted()).toLowerCase()));
            extensionImageElement.appendChild(replicationCompletedElement);
        }

        if (parameters.getEula() != null) {
            Element eulaElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure", "Eula");
            eulaElement.appendChild(requestDoc.createTextNode(parameters.getEula().toString()));
            extensionImageElement.appendChild(eulaElement);
        }

        if (parameters.getPrivacyUri() != null) {
            Element privacyUriElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "PrivacyUri");
            privacyUriElement.appendChild(requestDoc.createTextNode(parameters.getPrivacyUri().toString()));
            extensionImageElement.appendChild(privacyUriElement);
        }

        if (parameters.getHomepageUri() != null) {
            Element homepageUriElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "HomepageUri");
            homepageUriElement.appendChild(requestDoc.createTextNode(parameters.getHomepageUri().toString()));
            extensionImageElement.appendChild(homepageUriElement);
        }

        if (parameters.isJsonExtension() != null) {
            Element isJsonExtensionElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "IsJsonExtension");
            isJsonExtensionElement.appendChild(
                    requestDoc.createTextNode(Boolean.toString(parameters.isJsonExtension()).toLowerCase()));
            extensionImageElement.appendChild(isJsonExtensionElement);
        }

        if (parameters.isDisallowMajorVersionUpgrade() != null) {
            Element disallowMajorVersionUpgradeElement = requestDoc
                    .createElementNS("http://schemas.microsoft.com/windowsazure", "DisallowMajorVersionUpgrade");
            disallowMajorVersionUpgradeElement.appendChild(requestDoc
                    .createTextNode(Boolean.toString(parameters.isDisallowMajorVersionUpgrade()).toLowerCase()));
            extensionImageElement.appendChild(disallowMajorVersionUpgradeElement);
        }

        if (parameters.getSupportedOS() != null) {
            Element supportedOSElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "SupportedOS");
            supportedOSElement.appendChild(requestDoc.createTextNode(parameters.getSupportedOS()));
            extensionImageElement.appendChild(supportedOSElement);
        }

        if (parameters.getCompanyName() != null) {
            Element companyNameElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "CompanyName");
            companyNameElement.appendChild(requestDoc.createTextNode(parameters.getCompanyName()));
            extensionImageElement.appendChild(companyNameElement);
        }

        if (parameters.getRegions() != null) {
            Element regionsElement = requestDoc.createElementNS("http://schemas.microsoft.com/windowsazure",
                    "Regions");
            regionsElement.appendChild(requestDoc.createTextNode(parameters.getRegions()));
            extensionImageElement.appendChild(regionsElement);
        }

        DOMSource domSource = new DOMSource(requestDoc);
        StringWriter stringWriter = new StringWriter();
        StreamResult streamResult = new StreamResult(stringWriter);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.transform(domSource, streamResult);
        requestContent = stringWriter.toString();
        StringEntity entity = new StringEntity(requestContent);
        httpRequest.setEntity(entity);
        httpRequest.setHeader("Content-Type", "application/xml");

        // 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_ACCEPTED) {
                ServiceException ex = ServiceException.createFromXml(httpRequest, requestContent, 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();
            }
        }
    }

    /**
    * Register a new extension. An extension is identified by the combination
    * of its ProviderNamespace and Type (case-sensitive string). It is not
    * allowed to register an extension with the same identity (i.e.
    * combination of ProviderNamespace and Type) of an already-registered
    * extension. To register new version of an existing extension, the Update
    * Extension API should be used.
    *
    * @param parameters Required. Parameters supplied to the Register Virtual
    * Machine Extension Image operation.
    * @return The response body contains the status of the specified
    * asynchronous operation, indicating whether it has succeeded, is
    * inprogress, or has failed. Note that this status is distinct from the
    * HTTP status code returned for the Get Operation Status operation itself.
    * If the asynchronous operation succeeded, the response body includes the
    * HTTP status code for the successful request. If the asynchronous
    * operation failed, the response body includes the HTTP status code for
    * the failed request and error information regarding the failure.
    */
    @Override
    public Future<OperationStatusResponse> registerAsync(final ExtensionImageRegisterParameters parameters) {
        return this.getClient().getExecutorService().submit(new Callable<OperationStatusResponse>() {
            @Override
            public OperationStatusResponse call() throws Exception {
                return register(parameters);
            }
        });
    }

    /**
    * Register a new extension. An extension is identified by the combination
    * of its ProviderNamespace and Type (case-sensitive string). It is not
    * allowed to register an extension with the same identity (i.e.
    * combination of ProviderNamespace and Type) of an already-registered
    * extension. To register new version of an existing extension, the Update
    * Extension API should be used.
    *
    * @param parameters Required. Parameters supplied to the Register Virtual
    * Machine Extension Image operation.
    * @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 ServiceException Thrown if the server returned an error for the
    * request.
    * @throws IOException Thrown if there was an error setting up tracing for
    * the request.
    * @return The response body contains the status of the specified
    * asynchronous operation, indicating whether it has succeeded, is
    * inprogress, or has failed. Note that this status is distinct from the
    * HTTP status code returned for the Get Operation Status operation itself.
    * If the asynchronous operation succeeded, the response body includes the
    * HTTP status code for the successful request. If the asynchronous
    * operation failed, the response body includes the HTTP status code for
    * the failed request and error information regarding the failure.
    */
    @Override
    public OperationStatusResponse register(ExtensionImageRegisterParameters parameters)
            throws InterruptedException, ExecutionException, ServiceException, IOException {
        ComputeManagementClient 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("parameters", parameters);
            CloudTracing.enter(invocationId, this, "registerAsync", tracingParameters);
        }
        try {
            if (shouldTrace) {
                client2 = this.getClient().withRequestFilterLast(new ClientRequestTrackingHandler(invocationId))
                        .withResponseFilterLast(new ClientRequestTrackingHandler(invocationId));
            }

            OperationResponse response = client2.getExtensionImagesOperations().beginRegisteringAsync(parameters)
                    .get();
            OperationStatusResponse result = client2.getOperationStatusAsync(response.getRequestId()).get();
            int delayInSeconds = 30;
            if (client2.getLongRunningOperationInitialTimeout() >= 0) {
                delayInSeconds = client2.getLongRunningOperationInitialTimeout();
            }
            while (result.getStatus() != null && result.getStatus().equals(OperationStatus.InProgress)) {
                Thread.sleep(delayInSeconds * 1000);
                result = client2.getOperationStatusAsync(response.getRequestId()).get();
                delayInSeconds = 30;
                if (client2.getLongRunningOperationRetryTimeout() >= 0) {
                    delayInSeconds = client2.getLongRunningOperationRetryTimeout();
                }
            }

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

            if (result.getStatus() != OperationStatus.Succeeded) {
                if (result.getError() != null) {
                    ServiceException ex = new ServiceException(
                            result.getError().getCode() + " : " + result.getError().getMessage());
                    ex.setError(new CloudError());
                    ex.getError().setCode(result.getError().getCode());
                    ex.getError().setMessage(result.getError().getMessage());
                    if (shouldTrace) {
                        CloudTracing.error(invocationId, ex);
                    }
                    throw ex;
                } else {
                    ServiceException ex = new ServiceException("");
                    if (shouldTrace) {
                        CloudTracing.error(invocationId, ex);
                    }
                    throw ex;
                }
            }

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

    /**
    * Unregister a version of an extension that was previously registered using
    * either the Register Extension or Update Extension APIs. An extension
    * version is identified by the combination of its ProviderNamespace, Type
    * and Version which are specified when registering the extension.
    * Unregistering is only allowed for internal extensions, that is, the
    * extensions for which the IsInternalExtension field is set to 'true'
    * during registration or during an update. There is a quota (15) on the
    * number of extensions that can be registered per subscription. If your
    * subscription runs out of quota, you will wither need to unregister some
    * of the internal extensions or contact Azure (same email used to become a
    * publisher)  to increase the quota.
    *
    * @param providerNamespace Required. The provider namespace of the
    * extension image to unregister.
    * @param type Required. The type of the extension image to unregister.
    * @param version Required. The version of the extension image to unregister.
    * @return The response body contains the status of the specified
    * asynchronous operation, indicating whether it has succeeded, is
    * inprogress, or has failed. Note that this status is distinct from the
    * HTTP status code returned for the Get Operation Status operation itself.
    * If the asynchronous operation succeeded, the response body includes the
    * HTTP status code for the successful request. If the asynchronous
    * operation failed, the response body includes the HTTP status code for
    * the failed request and error information regarding the failure.
    */
    @Override
    public Future<OperationStatusResponse> unregisterAsync(final String providerNamespace, final String type,
            final String version) {
        return this.getClient().getExecutorService().submit(new Callable<OperationStatusResponse>() {
            @Override
            public OperationStatusResponse call() throws Exception {
                return unregister(providerNamespace, type, version);
            }
        });
    }

    /**
    * Unregister a version of an extension that was previously registered using
    * either the Register Extension or Update Extension APIs. An extension
    * version is identified by the combination of its ProviderNamespace, Type
    * and Version which are specified when registering the extension.
    * Unregistering is only allowed for internal extensions, that is, the
    * extensions for which the IsInternalExtension field is set to 'true'
    * during registration or during an update. There is a quota (15) on the
    * number of extensions that can be registered per subscription. If your
    * subscription runs out of quota, you will wither need to unregister some
    * of the internal extensions or contact Azure (same email used to become a
    * publisher)  to increase the quota.
    *
    * @param providerNamespace Required. The provider namespace of the
    * extension image to unregister.
    * @param type Required. The type of the extension image to unregister.
    * @param version Required. The version of the extension image to unregister.
    * @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 ServiceException Thrown if the server returned an error for the
    * request.
    * @throws IOException Thrown if there was an error setting up tracing for
    * the request.
    * @return The response body contains the status of the specified
    * asynchronous operation, indicating whether it has succeeded, is
    * inprogress, or has failed. Note that this status is distinct from the
    * HTTP status code returned for the Get Operation Status operation itself.
    * If the asynchronous operation succeeded, the response body includes the
    * HTTP status code for the successful request. If the asynchronous
    * operation failed, the response body includes the HTTP status code for
    * the failed request and error information regarding the failure.
    */
    @Override
    public OperationStatusResponse unregister(String providerNamespace, String type, String version)
            throws InterruptedException, ExecutionException, ServiceException, IOException {
        ComputeManagementClient 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("providerNamespace", providerNamespace);
            tracingParameters.put("type", type);
            tracingParameters.put("version", version);
            CloudTracing.enter(invocationId, this, "unregisterAsync", tracingParameters);
        }
        try {
            if (shouldTrace) {
                client2 = this.getClient().withRequestFilterLast(new ClientRequestTrackingHandler(invocationId))
                        .withResponseFilterLast(new ClientRequestTrackingHandler(invocationId));
            }

            OperationResponse response = client2.getExtensionImagesOperations()
                    .beginUnregisteringAsync(providerNamespace, type, version).get();
            OperationStatusResponse result = client2.getOperationStatusAsync(response.getRequestId()).get();
            int delayInSeconds = 30;
            if (client2.getLongRunningOperationInitialTimeout() >= 0) {
                delayInSeconds = client2.getLongRunningOperationInitialTimeout();
            }
            while (result.getStatus() != null && result.getStatus().equals(OperationStatus.InProgress)) {
                Thread.sleep(delayInSeconds * 1000);
                result = client2.getOperationStatusAsync(response.getRequestId()).get();
                delayInSeconds = 30;
                if (client2.getLongRunningOperationRetryTimeout() >= 0) {
                    delayInSeconds = client2.getLongRunningOperationRetryTimeout();
                }
            }

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

            if (result.getStatus() != OperationStatus.Succeeded) {
                if (result.getError() != null) {
                    ServiceException ex = new ServiceException(
                            result.getError().getCode() + " : " + result.getError().getMessage());
                    ex.setError(new CloudError());
                    ex.getError().setCode(result.getError().getCode());
                    ex.getError().setMessage(result.getError().getMessage());
                    if (shouldTrace) {
                        CloudTracing.error(invocationId, ex);
                    }
                    throw ex;
                } else {
                    ServiceException ex = new ServiceException("");
                    if (shouldTrace) {
                        CloudTracing.error(invocationId, ex);
                    }
                    throw ex;
                }
            }

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

    /**
    * Update a new extension. It is allowed to update an extension which had
    * already been registered with the same identity (i.e. combination of
    * ProviderNamespace and Type) but with different version. It will fail if
    * the extension to update has an identity that has not been registered
    * before, or there is already an extension with the same identity and same
    * version.
    *
    * @param parameters Required. Parameters supplied to the Update Virtual
    * Machine Extension Image operation.
    * @return The response body contains the status of the specified
    * asynchronous operation, indicating whether it has succeeded, is
    * inprogress, or has failed. Note that this status is distinct from the
    * HTTP status code returned for the Get Operation Status operation itself.
    * If the asynchronous operation succeeded, the response body includes the
    * HTTP status code for the successful request. If the asynchronous
    * operation failed, the response body includes the HTTP status code for
    * the failed request and error information regarding the failure.
    */
    @Override
    public Future<OperationStatusResponse> updateAsync(final ExtensionImageUpdateParameters parameters) {
        return this.getClient().getExecutorService().submit(new Callable<OperationStatusResponse>() {
            @Override
            public OperationStatusResponse call() throws Exception {
                return update(parameters);
            }
        });
    }

    /**
    * Update a new extension. It is allowed to update an extension which had
    * already been registered with the same identity (i.e. combination of
    * ProviderNamespace and Type) but with different version. It will fail if
    * the extension to update has an identity that has not been registered
    * before, or there is already an extension with the same identity and same
    * version.
    *
    * @param parameters Required. Parameters supplied to the Update Virtual
    * Machine Extension Image operation.
    * @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 ServiceException Thrown if the server returned an error for the
    * request.
    * @throws IOException Thrown if there was an error setting up tracing for
    * the request.
    * @throws ParserConfigurationException Thrown if there was an error
    * configuring the parser for the response body.
    * @throws SAXException Thrown if there was an error parsing the response
    * body.
    * @throws TransformerException Thrown if there was an error creating the
    * DOM transformer.
    * @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 response body contains the status of the specified
    * asynchronous operation, indicating whether it has succeeded, is
    * inprogress, or has failed. Note that this status is distinct from the
    * HTTP status code returned for the Get Operation Status operation itself.
    * If the asynchronous operation succeeded, the response body includes the
    * HTTP status code for the successful request. If the asynchronous
    * operation failed, the response body includes the HTTP status code for
    * the failed request and error information regarding the failure.
    */
    @Override
    public OperationStatusResponse update(ExtensionImageUpdateParameters parameters)
            throws InterruptedException, ExecutionException, ServiceException, IOException,
            ParserConfigurationException, SAXException, TransformerException, URISyntaxException {
        ComputeManagementClient 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("parameters", parameters);
            CloudTracing.enter(invocationId, this, "updateAsync", tracingParameters);
        }
        try {
            if (shouldTrace) {
                client2 = this.getClient().withRequestFilterLast(new ClientRequestTrackingHandler(invocationId))
                        .withResponseFilterLast(new ClientRequestTrackingHandler(invocationId));
            }

            OperationResponse response = client2.getExtensionImagesOperations().beginUpdatingAsync(parameters)
                    .get();
            OperationStatusResponse result = client2.getOperationStatusAsync(response.getRequestId()).get();
            int delayInSeconds = 30;
            if (client2.getLongRunningOperationInitialTimeout() >= 0) {
                delayInSeconds = client2.getLongRunningOperationInitialTimeout();
            }
            while (result.getStatus() != null && result.getStatus().equals(OperationStatus.InProgress)) {
                Thread.sleep(delayInSeconds * 1000);
                result = client2.getOperationStatusAsync(response.getRequestId()).get();
                delayInSeconds = 30;
                if (client2.getLongRunningOperationRetryTimeout() >= 0) {
                    delayInSeconds = client2.getLongRunningOperationRetryTimeout();
                }
            }

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

            if (result.getStatus() != OperationStatus.Succeeded) {
                if (result.getError() != null) {
                    ServiceException ex = new ServiceException(
                            result.getError().getCode() + " : " + result.getError().getMessage());
                    ex.setError(new CloudError());
                    ex.getError().setCode(result.getError().getCode());
                    ex.getError().setMessage(result.getError().getMessage());
                    if (shouldTrace) {
                        CloudTracing.error(invocationId, ex);
                    }
                    throw ex;
                } else {
                    ServiceException ex = new ServiceException("");
                    if (shouldTrace) {
                        CloudTracing.error(invocationId, ex);
                    }
                    throw ex;
                }
            }

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