text:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Common;
using Microsoft.WindowsAzure.Common.Internals;
using Microsoft.WindowsAzure.Management.Compute;
using Microsoft.WindowsAzure.Management.Compute.Models;

namespace Microsoft.WindowsAzure.Management.Compute
{
    /// <summary>
    /// The Service Management API includes operations for managing the disks
    /// in your subscription.  (see
    /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157188.aspx for
    /// more information)
    /// </summary>
    internal partial class VirtualMachineDiskOperations : IServiceOperations<ComputeManagementClient>, IVirtualMachineDiskOperations
    {
        /// <summary>
        /// Initializes a new instance of the VirtualMachineDiskOperations
        /// class.
        /// </summary>
        /// <param name='client'>
        /// Reference to the service client.
        /// </param>
        internal VirtualMachineDiskOperations(ComputeManagementClient client)
        {
            this._client = client;
        }

        private ComputeManagementClient _client;

        /// <summary>
        /// Gets a reference to the
        /// Microsoft.WindowsAzure.Management.Compute.ComputeManagementClient.
        /// </summary>
        public ComputeManagementClient Client
        {
            get { return this._client; }
        }

        /// <summary>
        /// The Delete Data Disk operation removes the specified data disk from
        /// a virtual machine.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157179.aspx
        /// for more information)
        /// </summary>
        /// <param name='serviceName'>
        /// The name of your service.
        /// </param>
        /// <param name='deploymentName'>
        /// The name of the deployment.
        /// </param>
        /// <param name='roleName'>
        /// The name of the role to delete the data disk from.
        /// </param>
        /// <param name='logicalUnitNumber'>
        /// The logical unit number of the disk.
        /// </param>
        /// <param name='deleteFromStorage'>
        /// Optional. Specifies that the source blob for the disk should also
        /// be deleted from storage.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// A standard service response including an HTTP status code and
        /// request ID.
        /// </returns>
        public async Task<OperationResponse> BeginDeletingDataDiskAsync(string serviceName, string deploymentName, string roleName, int logicalUnitNumber, bool deleteFromStorage, CancellationToken cancellationToken)
        {
            // Validate
            if (serviceName == null)
            {
                throw new ArgumentNullException("serviceName");
            }
            if (deploymentName == null)
            {
                throw new ArgumentNullException("deploymentName");
            }
            if (roleName == null)
            {
                throw new ArgumentNullException("roleName");
            }

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("serviceName", serviceName);
                tracingParameters.Add("deploymentName", deploymentName);
                tracingParameters.Add("roleName", roleName);
                tracingParameters.Add("logicalUnitNumber", logicalUnitNumber);
                tracingParameters.Add("deleteFromStorage", deleteFromStorage);
                Tracing.Enter(invocationId, this, "BeginDeletingDataDiskAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/hostedservices/" + serviceName + "/deployments/" + deploymentName + "/roles/" + roleName + "/DataDisks/" + logicalUnitNumber + "?";
            if (deleteFromStorage == true)
            {
                url = url + "&comp=" + Uri.EscapeUriString("media");
            }

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Delete;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.Accepted)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    OperationResponse result = null;
                    result = new OperationResponse();
                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }

        /// <summary>
        /// The Add Data Disk operation adds a data disk to a virtual machine.
        /// There are three ways to create the data disk using the Add Data
        /// Disk operation.  Option 1 – Attach an empty data disk to the role
        /// by specifying the disk label and location of the disk image.  Do
        /// not include the DiskName and SourceMediaLink elements in the
        /// request body.  Include the MediaLink element and reference a blob
        /// that is in the same geographical region as the role.  You can also
        /// omit the MediaLink element. In this usage, Windows Azure will
        /// create the data disk in the storage account configured as default
        /// for the role.   Option 2 – Attach an existing data disk that is in
        /// the image repository.  Do not include the DiskName and
        /// SourceMediaLink elements in the request body.  Specify the data
        /// disk to use by including the DiskName element.  Note: If included
        /// the in the response body, the MediaLink and LogicalDiskSizeInGB
        /// elements are ignored.  Option 3 - Specify the location of a blob
        /// in your storage account that contain a disk image to use.  Include
        /// the SourceMediaLink element. Note: If the MediaLink element
        /// isincluded, it is ignored.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157199.aspx
        /// for more information)
        /// </summary>
        /// <param name='serviceName'>
        /// The name of your service.
        /// </param>
        /// <param name='deploymentName'>
        /// The name of the deployment.
        /// </param>
        /// <param name='roleName'>
        /// The name of the role to add the data disk to.
        /// </param>
        /// <param name='parameters'>
        /// Parameters supplied to the Create Virtual Machine Data Disk
        /// operation.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// A standard service response including an HTTP status code and
        /// request ID.
        /// </returns>
        public async Task<OperationResponse> CreateDataDiskAsync(string serviceName, string deploymentName, string roleName, VirtualMachineDiskCreateDataDiskParameters parameters, CancellationToken cancellationToken)
        {
            // Validate
            if (serviceName == null)
            {
                throw new ArgumentNullException("serviceName");
            }
            if (deploymentName == null)
            {
                throw new ArgumentNullException("deploymentName");
            }
            if (roleName == null)
            {
                throw new ArgumentNullException("roleName");
            }
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }
            if (parameters.MediaLinkUri == null)
            {
                throw new ArgumentNullException("parameters.MediaLinkUri");
            }

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("serviceName", serviceName);
                tracingParameters.Add("deploymentName", deploymentName);
                tracingParameters.Add("roleName", roleName);
                tracingParameters.Add("parameters", parameters);
                Tracing.Enter(invocationId, this, "CreateDataDiskAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/hostedservices/" + serviceName + "/deployments/" + deploymentName + "/roles/" + roleName + "/DataDisks";

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Post;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Serialize Request
                string requestContent = null;
                XDocument requestDoc = new XDocument();

                XElement dataVirtualHardDiskElement = new XElement(XName.Get("DataVirtualHardDisk", "http://schemas.microsoft.com/windowsazure"));
                requestDoc.Add(dataVirtualHardDiskElement);

                XElement hostCachingElement = new XElement(XName.Get("HostCaching", "http://schemas.microsoft.com/windowsazure"));
                hostCachingElement.Value = parameters.HostCaching.ToString();
                dataVirtualHardDiskElement.Add(hostCachingElement);

                if (parameters.DiskLabel != null)
                {
                    XElement diskLabelElement = new XElement(XName.Get("DiskLabel", "http://schemas.microsoft.com/windowsazure"));
                    diskLabelElement.Value = parameters.DiskLabel;
                    dataVirtualHardDiskElement.Add(diskLabelElement);
                }

                if (parameters.DiskName != null)
                {
                    XElement diskNameElement = new XElement(XName.Get("DiskName", "http://schemas.microsoft.com/windowsazure"));
                    diskNameElement.Value = parameters.DiskName;
                    dataVirtualHardDiskElement.Add(diskNameElement);
                }

                if (parameters.LogicalUnitNumber != null)
                {
                    XElement lunElement = new XElement(XName.Get("Lun", "http://schemas.microsoft.com/windowsazure"));
                    lunElement.Value = parameters.LogicalUnitNumber.ToString();
                    dataVirtualHardDiskElement.Add(lunElement);
                }

                XElement logicalDiskSizeInGBElement = new XElement(XName.Get("LogicalDiskSizeInGB", "http://schemas.microsoft.com/windowsazure"));
                logicalDiskSizeInGBElement.Value = parameters.LogicalDiskSizeInGB.ToString();
                dataVirtualHardDiskElement.Add(logicalDiskSizeInGBElement);

                XElement mediaLinkElement = new XElement(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                mediaLinkElement.Value = parameters.MediaLinkUri.ToString();
                dataVirtualHardDiskElement.Add(mediaLinkElement);

                if (parameters.SourceMediaLinkUri != null)
                {
                    XElement sourceMediaLinkElement = new XElement(XName.Get("SourceMediaLink", "http://schemas.microsoft.com/windowsazure"));
                    sourceMediaLinkElement.Value = parameters.SourceMediaLinkUri.ToString();
                    dataVirtualHardDiskElement.Add(sourceMediaLinkElement);
                }

                requestContent = requestDoc.ToString();
                httpRequest.Content = new StringContent(requestContent, Encoding.UTF8);
                httpRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.Created)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, requestContent, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    OperationResponse result = null;
                    result = new OperationResponse();
                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }

        /// <summary>
        /// The Add Disk operation adds a disk to the user image repository.
        /// The disk can be an operating system disk or a data disk.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157178.aspx
        /// for more information)
        /// </summary>
        /// <param name='parameters'>
        /// Parameters supplied to the Create Virtual Machine Disk operation.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// A virtual machine disk associated with your subscription.
        /// </returns>
        public async Task<VirtualMachineDiskCreateDiskResponse> CreateDiskAsync(VirtualMachineDiskCreateDiskParameters parameters, CancellationToken cancellationToken)
        {
            // Validate
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }
            if (parameters.Label == null)
            {
                throw new ArgumentNullException("parameters.Label");
            }
            if (parameters.MediaLinkUri == null)
            {
                throw new ArgumentNullException("parameters.MediaLinkUri");
            }
            if (parameters.Name == null)
            {
                throw new ArgumentNullException("parameters.Name");
            }

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("parameters", parameters);
                Tracing.Enter(invocationId, this, "CreateDiskAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/disks";

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Post;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Serialize Request
                string requestContent = null;
                XDocument requestDoc = new XDocument();

                XElement diskElement = new XElement(XName.Get("Disk", "http://schemas.microsoft.com/windowsazure"));
                requestDoc.Add(diskElement);

                if (parameters.OperatingSystemType != null)
                {
                    XElement osElement = new XElement(XName.Get("OS", "http://schemas.microsoft.com/windowsazure"));
                    osElement.Value = parameters.OperatingSystemType;
                    diskElement.Add(osElement);
                }

                XElement labelElement = new XElement(XName.Get("Label", "http://schemas.microsoft.com/windowsazure"));
                labelElement.Value = parameters.Label;
                diskElement.Add(labelElement);

                XElement mediaLinkElement = new XElement(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                mediaLinkElement.Value = parameters.MediaLinkUri.ToString();
                diskElement.Add(mediaLinkElement);

                XElement nameElement = new XElement(XName.Get("Name", "http://schemas.microsoft.com/windowsazure"));
                nameElement.Value = parameters.Name;
                diskElement.Add(nameElement);

                requestContent = requestDoc.ToString();
                httpRequest.Content = new StringContent(requestContent, Encoding.UTF8);
                httpRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, requestContent, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    VirtualMachineDiskCreateDiskResponse result = null;
                    // Deserialize Response
                    cancellationToken.ThrowIfCancellationRequested();
                    string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                    result = new VirtualMachineDiskCreateDiskResponse();
                    XDocument responseDoc = XDocument.Parse(responseContent);

                    XElement diskElement2 = responseDoc.Element(XName.Get("Disk", "http://schemas.microsoft.com/windowsazure"));
                    if (diskElement2 != null)
                    {
                        XElement osElement2 = diskElement2.Element(XName.Get("OS", "http://schemas.microsoft.com/windowsazure"));
                        if (osElement2 != null)
                        {
                            string osInstance = osElement2.Value;
                            result.OperatingSystem = osInstance;
                        }

                        XElement labelElement2 = diskElement2.Element(XName.Get("Label", "http://schemas.microsoft.com/windowsazure"));
                        if (labelElement2 != null)
                        {
                            string labelInstance = labelElement2.Value;
                            result.Label = labelInstance;
                        }

                        XElement affinityGroupElement = diskElement2.Element(XName.Get("AffinityGroup", "http://schemas.microsoft.com/windowsazure"));
                        if (affinityGroupElement != null)
                        {
                            string affinityGroupInstance = affinityGroupElement.Value;
                            result.AffinityGroup = affinityGroupInstance;
                        }

                        XElement locationElement = diskElement2.Element(XName.Get("Location", "http://schemas.microsoft.com/windowsazure"));
                        if (locationElement != null)
                        {
                            string locationInstance = locationElement.Value;
                            result.Location = locationInstance;
                        }

                        XElement logicalDiskSizeInGBElement = diskElement2.Element(XName.Get("LogicalDiskSizeInGB", "http://schemas.microsoft.com/windowsazure"));
                        if (logicalDiskSizeInGBElement != null)
                        {
                            double logicalDiskSizeInGBInstance = double.Parse(logicalDiskSizeInGBElement.Value, CultureInfo.InvariantCulture);
                            result.LogicalSizeInGB = logicalDiskSizeInGBInstance;
                        }

                        XElement mediaLinkElement2 = diskElement2.Element(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                        if (mediaLinkElement2 != null)
                        {
                            Uri mediaLinkInstance = TypeConversion.TryParseUri(mediaLinkElement2.Value);
                            result.MediaLinkUri = mediaLinkInstance;
                        }

                        XElement nameElement2 = diskElement2.Element(XName.Get("Name", "http://schemas.microsoft.com/windowsazure"));
                        if (nameElement2 != null)
                        {
                            string nameInstance = nameElement2.Value;
                            result.Name = nameInstance;
                        }

                        XElement sourceImageNameElement = diskElement2.Element(XName.Get("SourceImageName", "http://schemas.microsoft.com/windowsazure"));
                        if (sourceImageNameElement != null)
                        {
                            string sourceImageNameInstance = sourceImageNameElement.Value;
                            result.SourceImageName = sourceImageNameInstance;
                        }

                        XElement attachedToElement = diskElement2.Element(XName.Get("AttachedTo", "http://schemas.microsoft.com/windowsazure"));
                        if (attachedToElement != null)
                        {
                            VirtualMachineDiskCreateDiskResponse.VirtualMachineDiskUsageDetails attachedToInstance = new VirtualMachineDiskCreateDiskResponse.VirtualMachineDiskUsageDetails();
                            result.UsageDetails = attachedToInstance;

                            XElement hostedServiceNameElement = attachedToElement.Element(XName.Get("HostedServiceName", "http://schemas.microsoft.com/windowsazure"));
                            if (hostedServiceNameElement != null)
                            {
                                string hostedServiceNameInstance = hostedServiceNameElement.Value;
                                attachedToInstance.HostedServiceName = hostedServiceNameInstance;
                            }

                            XElement deploymentNameElement = attachedToElement.Element(XName.Get("DeploymentName", "http://schemas.microsoft.com/windowsazure"));
                            if (deploymentNameElement != null)
                            {
                                string deploymentNameInstance = deploymentNameElement.Value;
                                attachedToInstance.DeploymentName = deploymentNameInstance;
                            }

                            XElement roleNameElement = attachedToElement.Element(XName.Get("RoleName", "http://schemas.microsoft.com/windowsazure"));
                            if (roleNameElement != null)
                            {
                                string roleNameInstance = roleNameElement.Value;
                                attachedToInstance.RoleName = roleNameInstance;
                            }
                        }

                        XElement isPremiumElement = diskElement2.Element(XName.Get("IsPremium", "http://schemas.microsoft.com/windowsazure"));
                        if (isPremiumElement != null && string.IsNullOrEmpty(isPremiumElement.Value) == false)
                        {
                            bool isPremiumInstance = bool.Parse(isPremiumElement.Value);
                            result.IsPremium = isPremiumInstance;
                        }
                    }

                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }

        /// <summary>
        /// The Delete Data Disk operation removes the specified data disk from
        /// a virtual machine.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157179.aspx
        /// for more information)
        /// </summary>
        /// <param name='serviceName'>
        /// The name of your service.
        /// </param>
        /// <param name='deploymentName'>
        /// The name of the deployment.
        /// </param>
        /// <param name='roleName'>
        /// The name of the role to delete the data disk from.
        /// </param>
        /// <param name='logicalUnitNumber'>
        /// The logical unit number of the disk.
        /// </param>
        /// <param name='deleteFromStorage'>
        /// Optional. Specifies that the source blob for the disk should also
        /// be deleted from storage.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// 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 also includes error
        /// information regarding the failure.
        /// </returns>
        public async Task<ComputeOperationStatusResponse> DeleteDataDiskAsync(string serviceName, string deploymentName, string roleName, int logicalUnitNumber, bool deleteFromStorage, CancellationToken cancellationToken)
        {
            ComputeManagementClient client = this.Client;
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("serviceName", serviceName);
                tracingParameters.Add("deploymentName", deploymentName);
                tracingParameters.Add("roleName", roleName);
                tracingParameters.Add("logicalUnitNumber", logicalUnitNumber);
                tracingParameters.Add("deleteFromStorage", deleteFromStorage);
                Tracing.Enter(invocationId, this, "DeleteDataDiskAsync", tracingParameters);
            }
            try
            {
                if (shouldTrace)
                {
                    client = this.Client.WithHandler(new ClientRequestTrackingHandler(invocationId));
                }

                cancellationToken.ThrowIfCancellationRequested();
                OperationResponse response = await client.VirtualMachineDisks.BeginDeletingDataDiskAsync(serviceName, deploymentName, roleName, logicalUnitNumber, deleteFromStorage, cancellationToken).ConfigureAwait(false);
                cancellationToken.ThrowIfCancellationRequested();
                ComputeOperationStatusResponse result = await client.GetOperationStatusAsync(response.RequestId, cancellationToken).ConfigureAwait(false);
                int delayInSeconds = 30;
                while ((result.Status != OperationStatus.InProgress) == false)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    await TaskEx.Delay(delayInSeconds * 1000, cancellationToken).ConfigureAwait(false);
                    cancellationToken.ThrowIfCancellationRequested();
                    result = await client.GetOperationStatusAsync(response.RequestId, cancellationToken).ConfigureAwait(false);
                    delayInSeconds = 30;
                }

                if (shouldTrace)
                {
                    Tracing.Exit(invocationId, result);
                }

                if (result.Status != OperationStatus.Succeeded)
                {
                    CloudException ex = new CloudException(result.Error.Code + " : " + result.Error.Message);
                    ex.ErrorCode = result.Error.Code;
                    ex.ErrorMessage = result.Error.Message;
                    if (shouldTrace)
                    {
                        Tracing.Error(invocationId, ex);
                    }
                    throw ex;
                }

                return result;
            }
            finally
            {
                if (client != null && shouldTrace)
                {
                    client.Dispose();
                }
            }
        }

        /// <summary>
        /// The Delete Disk operation deletes the specified data or operating
        /// system disk from your image repository.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157200.aspx
        /// for more information)
        /// </summary>
        /// <param name='diskName'>
        /// The name of the disk to delete.
        /// </param>
        /// <param name='deleteFromStorage'>
        /// Optional. Specifies that the source blob for the disk should also
        /// be deleted from storage.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// A standard service response including an HTTP status code and
        /// request ID.
        /// </returns>
        public async Task<OperationResponse> DeleteDiskAsync(string diskName, bool deleteFromStorage, CancellationToken cancellationToken)
        {
            // Validate
            if (diskName == null)
            {
                throw new ArgumentNullException("diskName");
            }

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("diskName", diskName);
                tracingParameters.Add("deleteFromStorage", deleteFromStorage);
                Tracing.Enter(invocationId, this, "DeleteDiskAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/disks/" + diskName + "?";
            if (deleteFromStorage == true)
            {
                url = url + "&comp=" + Uri.EscapeUriString("media");
            }

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Delete;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    OperationResponse result = null;
                    result = new OperationResponse();
                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }

        /// <summary>
        /// The Get Data Disk operation retrieves the specified data disk from
        /// a virtual machine.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157180.aspx
        /// for more information)
        /// </summary>
        /// <param name='serviceName'>
        /// The name of your service.
        /// </param>
        /// <param name='deploymentName'>
        /// The name of the deployment.
        /// </param>
        /// <param name='roleName'>
        /// The name of the role.
        /// </param>
        /// <param name='logicalUnitNumber'>
        /// The logical unit number of the disk.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// The Get Data Disk operation response.
        /// </returns>
        public async Task<VirtualMachineDiskGetDataDiskResponse> GetDataDiskAsync(string serviceName, string deploymentName, string roleName, int logicalUnitNumber, CancellationToken cancellationToken)
        {
            // Validate
            if (serviceName == null)
            {
                throw new ArgumentNullException("serviceName");
            }
            if (deploymentName == null)
            {
                throw new ArgumentNullException("deploymentName");
            }
            if (roleName == null)
            {
                throw new ArgumentNullException("roleName");
            }

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("serviceName", serviceName);
                tracingParameters.Add("deploymentName", deploymentName);
                tracingParameters.Add("roleName", roleName);
                tracingParameters.Add("logicalUnitNumber", logicalUnitNumber);
                Tracing.Enter(invocationId, this, "GetDataDiskAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/hostedservices/" + serviceName + "/deployments/" + deploymentName + "/roles/" + roleName + "/DataDisks/" + logicalUnitNumber;

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Get;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    VirtualMachineDiskGetDataDiskResponse result = null;
                    // Deserialize Response
                    cancellationToken.ThrowIfCancellationRequested();
                    string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                    result = new VirtualMachineDiskGetDataDiskResponse();
                    XDocument responseDoc = XDocument.Parse(responseContent);

                    XElement dataVirtualHardDiskElement = responseDoc.Element(XName.Get("DataVirtualHardDisk", "http://schemas.microsoft.com/windowsazure"));
                    if (dataVirtualHardDiskElement != null)
                    {
                        XElement hostCachingElement = dataVirtualHardDiskElement.Element(XName.Get("HostCaching", "http://schemas.microsoft.com/windowsazure"));
                        if (hostCachingElement != null)
                        {
                            VirtualHardDiskHostCaching hostCachingInstance = (VirtualHardDiskHostCaching)Enum.Parse(typeof(VirtualHardDiskHostCaching), hostCachingElement.Value, false);
                            result.HostCaching = hostCachingInstance;
                        }

                        XElement diskLabelElement = dataVirtualHardDiskElement.Element(XName.Get("DiskLabel", "http://schemas.microsoft.com/windowsazure"));
                        if (diskLabelElement != null)
                        {
                            string diskLabelInstance = diskLabelElement.Value;
                            result.DiskLabel = diskLabelInstance;
                        }

                        XElement diskNameElement = dataVirtualHardDiskElement.Element(XName.Get("DiskName", "http://schemas.microsoft.com/windowsazure"));
                        if (diskNameElement != null)
                        {
                            string diskNameInstance = diskNameElement.Value;
                            result.DiskName = diskNameInstance;
                        }

                        XElement lunElement = dataVirtualHardDiskElement.Element(XName.Get("Lun", "http://schemas.microsoft.com/windowsazure"));
                        if (lunElement != null && string.IsNullOrEmpty(lunElement.Value) == false)
                        {
                            int lunInstance = int.Parse(lunElement.Value, CultureInfo.InvariantCulture);
                            result.LogicalUnitNumber = lunInstance;
                        }

                        XElement logicalDiskSizeInGBElement = dataVirtualHardDiskElement.Element(XName.Get("LogicalDiskSizeInGB", "http://schemas.microsoft.com/windowsazure"));
                        if (logicalDiskSizeInGBElement != null)
                        {
                            double logicalDiskSizeInGBInstance = double.Parse(logicalDiskSizeInGBElement.Value, CultureInfo.InvariantCulture);
                            result.LogicalDiskSizeInGB = logicalDiskSizeInGBInstance;
                        }

                        XElement mediaLinkElement = dataVirtualHardDiskElement.Element(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                        if (mediaLinkElement != null)
                        {
                            Uri mediaLinkInstance = TypeConversion.TryParseUri(mediaLinkElement.Value);
                            result.MediaLinkUri = mediaLinkInstance;
                        }
                    }

                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }

        /// <summary>
        /// The Get Disk operation retrieves a disk from the user image
        /// repository. The disk can be an operating system disk or a data
        /// disk.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157178.aspx
        /// for more information)
        /// </summary>
        /// <param name='diskName'>
        /// The name of the disk.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// A virtual machine disk associated with your subscription.
        /// </returns>
        public async Task<VirtualMachineDiskGetDiskResponse> GetDiskAsync(string diskName, CancellationToken cancellationToken)
        {
            // Validate
            if (diskName == null)
            {
                throw new ArgumentNullException("diskName");
            }

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("diskName", diskName);
                Tracing.Enter(invocationId, this, "GetDiskAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/disks/" + diskName;

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Get;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    VirtualMachineDiskGetDiskResponse result = null;
                    // Deserialize Response
                    cancellationToken.ThrowIfCancellationRequested();
                    string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                    result = new VirtualMachineDiskGetDiskResponse();
                    XDocument responseDoc = XDocument.Parse(responseContent);

                    XElement diskElement = responseDoc.Element(XName.Get("Disk", "http://schemas.microsoft.com/windowsazure"));
                    if (diskElement != null)
                    {
                        XElement affinityGroupElement = diskElement.Element(XName.Get("AffinityGroup", "http://schemas.microsoft.com/windowsazure"));
                        if (affinityGroupElement != null)
                        {
                            string affinityGroupInstance = affinityGroupElement.Value;
                            result.AffinityGroup = affinityGroupInstance;
                        }

                        XElement locationElement = diskElement.Element(XName.Get("Location", "http://schemas.microsoft.com/windowsazure"));
                        if (locationElement != null)
                        {
                            string locationInstance = locationElement.Value;
                            result.Location = locationInstance;
                        }

                        XElement labelElement = diskElement.Element(XName.Get("Label", "http://schemas.microsoft.com/windowsazure"));
                        if (labelElement != null)
                        {
                            string labelInstance = labelElement.Value;
                            result.Label = labelInstance;
                        }

                        XElement logicalDiskSizeInGBElement = diskElement.Element(XName.Get("LogicalDiskSizeInGB", "http://schemas.microsoft.com/windowsazure"));
                        if (logicalDiskSizeInGBElement != null)
                        {
                            double logicalDiskSizeInGBInstance = double.Parse(logicalDiskSizeInGBElement.Value, CultureInfo.InvariantCulture);
                            result.LogicalSizeInGB = logicalDiskSizeInGBInstance;
                        }

                        XElement mediaLinkElement = diskElement.Element(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                        if (mediaLinkElement != null)
                        {
                            Uri mediaLinkInstance = TypeConversion.TryParseUri(mediaLinkElement.Value);
                            result.MediaLinkUri = mediaLinkInstance;
                        }

                        XElement nameElement = diskElement.Element(XName.Get("Name", "http://schemas.microsoft.com/windowsazure"));
                        if (nameElement != null)
                        {
                            string nameInstance = nameElement.Value;
                            result.Name = nameInstance;
                        }

                        XElement osElement = diskElement.Element(XName.Get("OS", "http://schemas.microsoft.com/windowsazure"));
                        if (osElement != null)
                        {
                            string osInstance = osElement.Value;
                            result.OperatingSystemType = osInstance;
                        }

                        XElement sourceImageNameElement = diskElement.Element(XName.Get("SourceImageName", "http://schemas.microsoft.com/windowsazure"));
                        if (sourceImageNameElement != null)
                        {
                            string sourceImageNameInstance = sourceImageNameElement.Value;
                            result.SourceImageName = sourceImageNameInstance;
                        }

                        XElement attachedToElement = diskElement.Element(XName.Get("AttachedTo", "http://schemas.microsoft.com/windowsazure"));
                        if (attachedToElement != null)
                        {
                            VirtualMachineDiskGetDiskResponse.VirtualMachineDiskUsageDetails attachedToInstance = new VirtualMachineDiskGetDiskResponse.VirtualMachineDiskUsageDetails();
                            result.UsageDetails = attachedToInstance;

                            XElement hostedServiceNameElement = attachedToElement.Element(XName.Get("HostedServiceName", "http://schemas.microsoft.com/windowsazure"));
                            if (hostedServiceNameElement != null)
                            {
                                string hostedServiceNameInstance = hostedServiceNameElement.Value;
                                attachedToInstance.HostedServiceName = hostedServiceNameInstance;
                            }

                            XElement deploymentNameElement = attachedToElement.Element(XName.Get("DeploymentName", "http://schemas.microsoft.com/windowsazure"));
                            if (deploymentNameElement != null)
                            {
                                string deploymentNameInstance = deploymentNameElement.Value;
                                attachedToInstance.DeploymentName = deploymentNameInstance;
                            }

                            XElement roleNameElement = attachedToElement.Element(XName.Get("RoleName", "http://schemas.microsoft.com/windowsazure"));
                            if (roleNameElement != null)
                            {
                                string roleNameInstance = roleNameElement.Value;
                                attachedToInstance.RoleName = roleNameInstance;
                            }
                        }

                        XElement isCorruptedElement = diskElement.Element(XName.Get("IsCorrupted", "http://schemas.microsoft.com/windowsazure"));
                        if (isCorruptedElement != null && string.IsNullOrEmpty(isCorruptedElement.Value) == false)
                        {
                            bool isCorruptedInstance = bool.Parse(isCorruptedElement.Value);
                            result.IsCorrupted = isCorruptedInstance;
                        }

                        XElement isPremiumElement = diskElement.Element(XName.Get("IsPremium", "http://schemas.microsoft.com/windowsazure"));
                        if (isPremiumElement != null && string.IsNullOrEmpty(isPremiumElement.Value) == false)
                        {
                            bool isPremiumInstance = bool.Parse(isPremiumElement.Value);
                            result.IsPremium = isPremiumInstance;
                        }
                    }

                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }

        /// <summary>
        /// The List Disks operation retrieves a list of the disks in your
        /// image repository.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157176.aspx
        /// for more information)
        /// </summary>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// The List Disks operation response.
        /// </returns>
        public async Task<VirtualMachineDiskListResponse> ListDisksAsync(CancellationToken cancellationToken)
        {
            // Validate

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                Tracing.Enter(invocationId, this, "ListDisksAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/disks";

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Get;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    VirtualMachineDiskListResponse result = null;
                    // Deserialize Response
                    cancellationToken.ThrowIfCancellationRequested();
                    string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                    result = new VirtualMachineDiskListResponse();
                    XDocument responseDoc = XDocument.Parse(responseContent);

                    XElement disksSequenceElement = responseDoc.Element(XName.Get("Disks", "http://schemas.microsoft.com/windowsazure"));
                    if (disksSequenceElement != null)
                    {
                        foreach (XElement disksElement in disksSequenceElement.Elements(XName.Get("Disk", "http://schemas.microsoft.com/windowsazure")))
                        {
                            VirtualMachineDiskListResponse.VirtualMachineDisk diskInstance = new VirtualMachineDiskListResponse.VirtualMachineDisk();
                            result.Disks.Add(diskInstance);

                            XElement affinityGroupElement = disksElement.Element(XName.Get("AffinityGroup", "http://schemas.microsoft.com/windowsazure"));
                            if (affinityGroupElement != null)
                            {
                                string affinityGroupInstance = affinityGroupElement.Value;
                                diskInstance.AffinityGroup = affinityGroupInstance;
                            }

                            XElement locationElement = disksElement.Element(XName.Get("Location", "http://schemas.microsoft.com/windowsazure"));
                            if (locationElement != null)
                            {
                                string locationInstance = locationElement.Value;
                                diskInstance.Location = locationInstance;
                            }

                            XElement labelElement = disksElement.Element(XName.Get("Label", "http://schemas.microsoft.com/windowsazure"));
                            if (labelElement != null)
                            {
                                string labelInstance = labelElement.Value;
                                diskInstance.Label = labelInstance;
                            }

                            XElement logicalDiskSizeInGBElement = disksElement.Element(XName.Get("LogicalDiskSizeInGB", "http://schemas.microsoft.com/windowsazure"));
                            if (logicalDiskSizeInGBElement != null)
                            {
                                double logicalDiskSizeInGBInstance = double.Parse(logicalDiskSizeInGBElement.Value, CultureInfo.InvariantCulture);
                                diskInstance.LogicalSizeInGB = logicalDiskSizeInGBInstance;
                            }

                            XElement mediaLinkElement = disksElement.Element(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                            if (mediaLinkElement != null)
                            {
                                Uri mediaLinkInstance = TypeConversion.TryParseUri(mediaLinkElement.Value);
                                diskInstance.MediaLinkUri = mediaLinkInstance;
                            }

                            XElement nameElement = disksElement.Element(XName.Get("Name", "http://schemas.microsoft.com/windowsazure"));
                            if (nameElement != null)
                            {
                                string nameInstance = nameElement.Value;
                                diskInstance.Name = nameInstance;
                            }

                            XElement osElement = disksElement.Element(XName.Get("OS", "http://schemas.microsoft.com/windowsazure"));
                            if (osElement != null)
                            {
                                string osInstance = osElement.Value;
                                diskInstance.OperatingSystemType = osInstance;
                            }

                            XElement sourceImageNameElement = disksElement.Element(XName.Get("SourceImageName", "http://schemas.microsoft.com/windowsazure"));
                            if (sourceImageNameElement != null)
                            {
                                string sourceImageNameInstance = sourceImageNameElement.Value;
                                diskInstance.SourceImageName = sourceImageNameInstance;
                            }

                            XElement attachedToElement = disksElement.Element(XName.Get("AttachedTo", "http://schemas.microsoft.com/windowsazure"));
                            if (attachedToElement != null)
                            {
                                VirtualMachineDiskListResponse.VirtualMachineDiskUsageDetails attachedToInstance = new VirtualMachineDiskListResponse.VirtualMachineDiskUsageDetails();
                                diskInstance.UsageDetails = attachedToInstance;

                                XElement hostedServiceNameElement = attachedToElement.Element(XName.Get("HostedServiceName", "http://schemas.microsoft.com/windowsazure"));
                                if (hostedServiceNameElement != null)
                                {
                                    string hostedServiceNameInstance = hostedServiceNameElement.Value;
                                    attachedToInstance.HostedServiceName = hostedServiceNameInstance;
                                }

                                XElement deploymentNameElement = attachedToElement.Element(XName.Get("DeploymentName", "http://schemas.microsoft.com/windowsazure"));
                                if (deploymentNameElement != null)
                                {
                                    string deploymentNameInstance = deploymentNameElement.Value;
                                    attachedToInstance.DeploymentName = deploymentNameInstance;
                                }

                                XElement roleNameElement = attachedToElement.Element(XName.Get("RoleName", "http://schemas.microsoft.com/windowsazure"));
                                if (roleNameElement != null)
                                {
                                    string roleNameInstance = roleNameElement.Value;
                                    attachedToInstance.RoleName = roleNameInstance;
                                }
                            }

                            XElement isCorruptedElement = disksElement.Element(XName.Get("IsCorrupted", "http://schemas.microsoft.com/windowsazure"));
                            if (isCorruptedElement != null && string.IsNullOrEmpty(isCorruptedElement.Value) == false)
                            {
                                bool isCorruptedInstance = bool.Parse(isCorruptedElement.Value);
                                diskInstance.IsCorrupted = isCorruptedInstance;
                            }

                            XElement isPremiumElement = disksElement.Element(XName.Get("IsPremium", "http://schemas.microsoft.com/windowsazure"));
                            if (isPremiumElement != null && string.IsNullOrEmpty(isPremiumElement.Value) == false)
                            {
                                bool isPremiumInstance = bool.Parse(isPremiumElement.Value);
                                diskInstance.IsPremium = isPremiumInstance;
                            }
                        }
                    }

                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }

        /// <summary>
        /// The Update Data Disk operation updates the specified data disk
        /// attached to the specified virtual machine.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157190.aspx
        /// for more information)
        /// </summary>
        /// <param name='serviceName'>
        /// The name of your service.
        /// </param>
        /// <param name='deploymentName'>
        /// The name of the deployment.
        /// </param>
        /// <param name='roleName'>
        /// The name of the role to add the data disk to.
        /// </param>
        /// <param name='logicalUnitNumber'>
        /// The logical unit number of the disk.
        /// </param>
        /// <param name='parameters'>
        /// Parameters supplied to the Update Virtual Machine Data Disk
        /// operation.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// A standard service response including an HTTP status code and
        /// request ID.
        /// </returns>
        public async Task<OperationResponse> UpdateDataDiskAsync(string serviceName, string deploymentName, string roleName, int logicalUnitNumber, VirtualMachineDiskUpdateDataDiskParameters parameters, CancellationToken cancellationToken)
        {
            // Validate
            if (serviceName == null)
            {
                throw new ArgumentNullException("serviceName");
            }
            if (deploymentName == null)
            {
                throw new ArgumentNullException("deploymentName");
            }
            if (roleName == null)
            {
                throw new ArgumentNullException("roleName");
            }
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }
            if (parameters.MediaLinkUri == null)
            {
                throw new ArgumentNullException("parameters.MediaLinkUri");
            }

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("serviceName", serviceName);
                tracingParameters.Add("deploymentName", deploymentName);
                tracingParameters.Add("roleName", roleName);
                tracingParameters.Add("logicalUnitNumber", logicalUnitNumber);
                tracingParameters.Add("parameters", parameters);
                Tracing.Enter(invocationId, this, "UpdateDataDiskAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/hostedservices/" + serviceName + "/deployments/" + deploymentName + "/roles/" + roleName + "/DataDisks/" + logicalUnitNumber;

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Put;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Serialize Request
                string requestContent = null;
                XDocument requestDoc = new XDocument();

                XElement dataVirtualHardDiskElement = new XElement(XName.Get("DataVirtualHardDisk", "http://schemas.microsoft.com/windowsazure"));
                requestDoc.Add(dataVirtualHardDiskElement);

                XElement hostCachingElement = new XElement(XName.Get("HostCaching", "http://schemas.microsoft.com/windowsazure"));
                hostCachingElement.Value = parameters.HostCaching.ToString();
                dataVirtualHardDiskElement.Add(hostCachingElement);

                if (parameters.DiskLabel != null)
                {
                    XElement diskLabelElement = new XElement(XName.Get("DiskLabel", "http://schemas.microsoft.com/windowsazure"));
                    diskLabelElement.Value = parameters.DiskLabel;
                    dataVirtualHardDiskElement.Add(diskLabelElement);
                }

                if (parameters.DiskName != null)
                {
                    XElement diskNameElement = new XElement(XName.Get("DiskName", "http://schemas.microsoft.com/windowsazure"));
                    diskNameElement.Value = parameters.DiskName;
                    dataVirtualHardDiskElement.Add(diskNameElement);
                }

                if (parameters.LogicalUnitNumber != null)
                {
                    XElement lunElement = new XElement(XName.Get("Lun", "http://schemas.microsoft.com/windowsazure"));
                    lunElement.Value = parameters.LogicalUnitNumber.ToString();
                    dataVirtualHardDiskElement.Add(lunElement);
                }

                XElement logicalDiskSizeInGBElement = new XElement(XName.Get("LogicalDiskSizeInGB", "http://schemas.microsoft.com/windowsazure"));
                logicalDiskSizeInGBElement.Value = parameters.LogicalDiskSizeInGB.ToString();
                dataVirtualHardDiskElement.Add(logicalDiskSizeInGBElement);

                XElement mediaLinkElement = new XElement(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                mediaLinkElement.Value = parameters.MediaLinkUri.ToString();
                dataVirtualHardDiskElement.Add(mediaLinkElement);

                requestContent = requestDoc.ToString();
                httpRequest.Content = new StringContent(requestContent, Encoding.UTF8);
                httpRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, requestContent, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    OperationResponse result = null;
                    result = new OperationResponse();
                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }

        /// <summary>
        /// The Add Disk operation adds a disk to the user image repository.
        /// The disk can be an operating system disk or a data disk.  (see
        /// http://msdn.microsoft.com/en-us/library/windowsazure/jj157178.aspx
        /// for more information)
        /// </summary>
        /// <param name='diskName'>
        /// The name of the disk being updated.
        /// </param>
        /// <param name='parameters'>
        /// Parameters supplied to the Update Virtual Machine Disk operation.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// A virtual machine disk associated with your subscription.
        /// </returns>
        public async Task<VirtualMachineDiskUpdateDiskResponse> UpdateDiskAsync(string diskName, VirtualMachineDiskUpdateDiskParameters parameters, CancellationToken cancellationToken)
        {
            // Validate
            if (diskName == null)
            {
                throw new ArgumentNullException("diskName");
            }
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }
            if (parameters.Label == null)
            {
                throw new ArgumentNullException("parameters.Label");
            }
            if (parameters.Name == null)
            {
                throw new ArgumentNullException("parameters.Name");
            }

            // Tracing
            bool shouldTrace = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;
            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
                tracingParameters.Add("diskName", diskName);
                tracingParameters.Add("parameters", parameters);
                Tracing.Enter(invocationId, this, "UpdateDiskAsync", tracingParameters);
            }

            // Construct URL
            string url = this.Client.BaseUri + "/" + this.Client.Credentials.SubscriptionId + "/services/disks/" + diskName;

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;
            try
            {
                httpRequest = new HttpRequestMessage();
                httpRequest.Method = HttpMethod.Put;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("x-ms-version", "2013-11-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Serialize Request
                string requestContent = null;
                XDocument requestDoc = new XDocument();

                XElement diskElement = new XElement(XName.Get("Disk", "http://schemas.microsoft.com/windowsazure"));
                requestDoc.Add(diskElement);

                if (parameters.HasOperatingSystem != null)
                {
                    XElement hasOperatingSystemElement = new XElement(XName.Get("HasOperatingSystem", "http://schemas.microsoft.com/windowsazure"));
                    hasOperatingSystemElement.Value = parameters.HasOperatingSystem.ToString().ToLower();
                    diskElement.Add(hasOperatingSystemElement);
                }

                if (parameters.OperatingSystemType != null)
                {
                    XElement osElement = new XElement(XName.Get("OS", "http://schemas.microsoft.com/windowsazure"));
                    osElement.Value = parameters.OperatingSystemType;
                    diskElement.Add(osElement);
                }

                XElement labelElement = new XElement(XName.Get("Label", "http://schemas.microsoft.com/windowsazure"));
                labelElement.Value = parameters.Label;
                diskElement.Add(labelElement);

                if (parameters.MediaLinkUri != null)
                {
                    XElement mediaLinkElement = new XElement(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                    mediaLinkElement.Value = parameters.MediaLinkUri.ToString();
                    diskElement.Add(mediaLinkElement);
                }

                XElement nameElement = new XElement(XName.Get("Name", "http://schemas.microsoft.com/windowsazure"));
                nameElement.Value = parameters.Name;
                diskElement.Add(nameElement);

                requestContent = requestDoc.ToString();
                httpRequest.Content = new StringContent(requestContent, Encoding.UTF8);
                httpRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, requestContent, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), CloudExceptionType.Xml);
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    VirtualMachineDiskUpdateDiskResponse result = null;
                    // Deserialize Response
                    cancellationToken.ThrowIfCancellationRequested();
                    string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
                    result = new VirtualMachineDiskUpdateDiskResponse();
                    XDocument responseDoc = XDocument.Parse(responseContent);

                    XElement diskElement2 = responseDoc.Element(XName.Get("Disk", "http://schemas.microsoft.com/windowsazure"));
                    if (diskElement2 != null)
                    {
                        XElement osElement2 = diskElement2.Element(XName.Get("OS", "http://schemas.microsoft.com/windowsazure"));
                        if (osElement2 != null)
                        {
                            string osInstance = osElement2.Value;
                            result.OperatingSystem = osInstance;
                        }

                        XElement labelElement2 = diskElement2.Element(XName.Get("Label", "http://schemas.microsoft.com/windowsazure"));
                        if (labelElement2 != null)
                        {
                            string labelInstance = labelElement2.Value;
                            result.Label = labelInstance;
                        }

                        XElement affinityGroupElement = diskElement2.Element(XName.Get("AffinityGroup", "http://schemas.microsoft.com/windowsazure"));
                        if (affinityGroupElement != null)
                        {
                            string affinityGroupInstance = affinityGroupElement.Value;
                            result.AffinityGroup = affinityGroupInstance;
                        }

                        XElement locationElement = diskElement2.Element(XName.Get("Location", "http://schemas.microsoft.com/windowsazure"));
                        if (locationElement != null)
                        {
                            string locationInstance = locationElement.Value;
                            result.Location = locationInstance;
                        }

                        XElement logicalDiskSizeInGBElement = diskElement2.Element(XName.Get("LogicalDiskSizeInGB", "http://schemas.microsoft.com/windowsazure"));
                        if (logicalDiskSizeInGBElement != null)
                        {
                            double logicalDiskSizeInGBInstance = double.Parse(logicalDiskSizeInGBElement.Value, CultureInfo.InvariantCulture);
                            result.LogicalSizeInGB = logicalDiskSizeInGBInstance;
                        }

                        XElement mediaLinkElement2 = diskElement2.Element(XName.Get("MediaLink", "http://schemas.microsoft.com/windowsazure"));
                        if (mediaLinkElement2 != null)
                        {
                            Uri mediaLinkInstance = TypeConversion.TryParseUri(mediaLinkElement2.Value);
                            result.MediaLinkUri = mediaLinkInstance;
                        }

                        XElement nameElement2 = diskElement2.Element(XName.Get("Name", "http://schemas.microsoft.com/windowsazure"));
                        if (nameElement2 != null)
                        {
                            string nameInstance = nameElement2.Value;
                            result.Name = nameInstance;
                        }

                        XElement isPremiumElement = diskElement2.Element(XName.Get("IsPremium", "http://schemas.microsoft.com/windowsazure"));
                        if (isPremiumElement != null && string.IsNullOrEmpty(isPremiumElement.Value) == false)
                        {
                            bool isPremiumInstance = bool.Parse(isPremiumElement.Value);
                            result.IsPremium = isPremiumInstance;
                        }
                    }

                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return result;
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }
    }
}