// Calling this based on a grouping (in SasMetricRetriever) should guarantee that it will have metric names specified (cannot have empty group)
        internal override async Task <MetricListResponse> GetMetricsInternalAsync(MetricFilter filter, MetricLocation location, string invocationId)
        {
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            if (location == null)
            {
                throw new ArgumentNullException("location");
            }

            // This is called based on the definitions no the dimension portion of the filter should never be null or empty
            if (filter.DimensionFilters == null || !filter.DimensionFilters.Any())
            {
                throw new ArgumentNullException("filter.DimensionFilters");
            }

            // Separate out capacity metrics and transaction metrics into two groups
            IEnumerable <string> capacityMetrics    = filter.DimensionFilters.Select(df => df.Name).Where(StorageConstants.MetricNames.IsCapacityMetric);
            IEnumerable <string> transactionMetrics = filter.DimensionFilters.Select(df => df.Name).Where(n => !StorageConstants.MetricNames.IsCapacityMetric(n));

            List <Task <IEnumerable <Metric> > > queryTasks = new List <Task <IEnumerable <Metric> > >();

            // Add task to get capacity metrics (if any)
            if (capacityMetrics.Any())
            {
                MetricTableInfo capacityTableInfo = location.TableInfo.FirstOrDefault(ti => StorageConstants.IsCapacityMetricsTable(ti.TableName));
                if (capacityTableInfo == null)
                {
                    throw new InvalidOperationException("Definitions for capacity metrics must contain table info for capacity metrics table");
                }

                queryTasks.Add(GetCapacityMetricsAsync(filter, GetTableReference(location, capacityTableInfo), capacityMetrics, invocationId));
            }

            // Add tasks to get transaction metrics (if any)
            if (transactionMetrics.Any())
            {
                IEnumerable <MetricTableInfo> transactionTableInfos = location.TableInfo.Where(ti => !StorageConstants.IsCapacityMetricsTable(ti.TableName));
                if (!transactionTableInfos.Any())
                {
                    throw new InvalidOperationException("Definitions for transaction metrics must contain table info for transaction metrics table");
                }

                queryTasks.AddRange(transactionTableInfos
                                    .Select(info => GetTransactionMetricsAsync(filter, GetTableReference(location, info), transactionMetrics, invocationId)));
            }

            // Collect results and wrap
            return(new MetricListResponse()
            {
                RequestId = invocationId,
                StatusCode = HttpStatusCode.OK,
                MetricCollection = new MetricCollection()
                {
                    Value = (await CollectResultsAsync(queryTasks)).ToList()
                }
            });
        }
        /// <summary>
        /// A string representation of the MetricTableInfo including indentation
        /// </summary>
        /// <param name="metricTableInfo">The MetricTableInfo object</param>
        /// <param name="indentationTabs">The number of tabs to insert in front of each member</param>
        /// <returns>A string representation of the MetricTableInfo including indentation</returns>
        public static string ToString(this MetricTableInfo metricTableInfo, int indentationTabs)
        {
            StringBuilder output = new StringBuilder();

            if (metricTableInfo != null)
            {
                output.AppendLine();
                output.AddSpacesInFront(indentationTabs).AppendLine("Table name                 : " + metricTableInfo.TableName);
                output.AddSpacesInFront(indentationTabs).AppendLine("Table sas token            : " + metricTableInfo.SasToken);
                output.AddSpacesInFront(indentationTabs).AppendLine("Table sas token expiration : " + metricTableInfo.SasTokenExpirationTime.ToUniversalTime().ToString("O"));
                output.AddSpacesInFront(indentationTabs).AppendLine("Start time                 : " + metricTableInfo.StartTime.ToUniversalTime().ToString("O"));
                output.AddSpacesInFront(indentationTabs).Append("End time                   : " + metricTableInfo.EndTime.ToUniversalTime().ToString("O"));
            }

            return(output.ToString());
        }
        /// <summary>
        /// The List Metric Definitions operation lists the metric definitions
        /// for the resource.
        /// </summary>
        /// <param name='resourceUri'>
        /// Required. The resource identifier of the target resource to get
        /// metrics for.
        /// </param>
        /// <param name='filterString'>
        /// Optional. An OData $filter expression that supports querying by the
        /// name of the metric definition. For example, "name.value eq
        /// 'Percentage CPU'". Name is optional, meaning the expression may be
        /// "".
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// The List Metric Definitions operation response.
        /// </returns>
        public async Task <MetricDefinitionListResponse> GetMetricDefinitionsAsync(string resourceUri, string filterString, CancellationToken cancellationToken)
        {
            // Validate
            if (resourceUri == null)
            {
                throw new ArgumentNullException("resourceUri");
            }

            // 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("resourceUri", resourceUri);
                tracingParameters.Add("filterString", filterString);
                Tracing.Enter(invocationId, this, "GetMetricDefinitionsAsync", tracingParameters);
            }

            // Construct URL
            string url = "/" + resourceUri.Trim() + "/metricDefinitions?";

            url = url + "api-version=2014-04-01";
            if (filterString != null)
            {
                url = url + "&$filter=" + Uri.EscapeDataString(filterString != null ? filterString.Trim() : "");
            }
            string baseUrl = this.Client.BaseUri.AbsoluteUri;

            // Trim '/' character from the end of baseUrl and beginning of url.
            if (baseUrl[baseUrl.Length - 1] == '/')
            {
                baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
            }
            if (url[0] == '/')
            {
                url = url.Substring(1);
            }
            url = baseUrl + "/" + url;
            url = url.Replace(" ", "%20");

            // 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("Accept", "application/json");
                httpRequest.Headers.Add("x-ms-version", "2014-04-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));
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    MetricDefinitionListResponse result = null;
                    // Deserialize Response
                    cancellationToken.ThrowIfCancellationRequested();
                    string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

                    result = new MetricDefinitionListResponse();
                    JToken responseDoc = null;
                    if (string.IsNullOrEmpty(responseContent) == false)
                    {
                        responseDoc = JToken.Parse(responseContent);
                    }

                    if (responseDoc != null && responseDoc.Type != JTokenType.Null)
                    {
                        MetricDefinitionCollection metricDefinitionCollectionInstance = new MetricDefinitionCollection();
                        result.MetricDefinitionCollection = metricDefinitionCollectionInstance;

                        JToken valueArray = responseDoc["value"];
                        if (valueArray != null && valueArray.Type != JTokenType.Null)
                        {
                            foreach (JToken valueValue in ((JArray)valueArray))
                            {
                                MetricDefinition metricDefinitionInstance = new MetricDefinition();
                                metricDefinitionCollectionInstance.Value.Add(metricDefinitionInstance);

                                JToken nameValue = valueValue["name"];
                                if (nameValue != null && nameValue.Type != JTokenType.Null)
                                {
                                    LocalizableString nameInstance = new LocalizableString();
                                    metricDefinitionInstance.Name = nameInstance;

                                    JToken valueValue2 = nameValue["value"];
                                    if (valueValue2 != null && valueValue2.Type != JTokenType.Null)
                                    {
                                        string valueInstance = ((string)valueValue2);
                                        nameInstance.Value = valueInstance;
                                    }

                                    JToken localizedValueValue = nameValue["localizedValue"];
                                    if (localizedValueValue != null && localizedValueValue.Type != JTokenType.Null)
                                    {
                                        string localizedValueInstance = ((string)localizedValueValue);
                                        nameInstance.LocalizedValue = localizedValueInstance;
                                    }
                                }

                                JToken unitValue = valueValue["unit"];
                                if (unitValue != null && unitValue.Type != JTokenType.Null)
                                {
                                    Unit unitInstance = ((Unit)Enum.Parse(typeof(Unit), ((string)unitValue), true));
                                    metricDefinitionInstance.Unit = unitInstance;
                                }

                                JToken primaryAggregationTypeValue = valueValue["primaryAggregationType"];
                                if (primaryAggregationTypeValue != null && primaryAggregationTypeValue.Type != JTokenType.Null)
                                {
                                    AggregationType primaryAggregationTypeInstance = ((AggregationType)Enum.Parse(typeof(AggregationType), ((string)primaryAggregationTypeValue), true));
                                    metricDefinitionInstance.PrimaryAggregationType = primaryAggregationTypeInstance;
                                }

                                JToken resourceUriValue = valueValue["resourceUri"];
                                if (resourceUriValue != null && resourceUriValue.Type != JTokenType.Null)
                                {
                                    string resourceUriInstance = ((string)resourceUriValue);
                                    metricDefinitionInstance.ResourceUri = resourceUriInstance;
                                }

                                JToken metricAvailabilitiesArray = valueValue["metricAvailabilities"];
                                if (metricAvailabilitiesArray != null && metricAvailabilitiesArray.Type != JTokenType.Null)
                                {
                                    foreach (JToken metricAvailabilitiesValue in ((JArray)metricAvailabilitiesArray))
                                    {
                                        MetricAvailability metricAvailabilityInstance = new MetricAvailability();
                                        metricDefinitionInstance.MetricAvailabilities.Add(metricAvailabilityInstance);

                                        JToken timeGrainValue = metricAvailabilitiesValue["timeGrain"];
                                        if (timeGrainValue != null && timeGrainValue.Type != JTokenType.Null)
                                        {
                                            TimeSpan timeGrainInstance = TypeConversion.From8601TimeSpan(((string)timeGrainValue));
                                            metricAvailabilityInstance.TimeGrain = timeGrainInstance;
                                        }

                                        JToken retentionValue = metricAvailabilitiesValue["retention"];
                                        if (retentionValue != null && retentionValue.Type != JTokenType.Null)
                                        {
                                            TimeSpan retentionInstance = TypeConversion.From8601TimeSpan(((string)retentionValue));
                                            metricAvailabilityInstance.Retention = retentionInstance;
                                        }

                                        JToken locationValue = metricAvailabilitiesValue["location"];
                                        if (locationValue != null && locationValue.Type != JTokenType.Null)
                                        {
                                            MetricLocation locationInstance = new MetricLocation();
                                            metricAvailabilityInstance.Location = locationInstance;

                                            JToken tableEndpointValue = locationValue["tableEndpoint"];
                                            if (tableEndpointValue != null && tableEndpointValue.Type != JTokenType.Null)
                                            {
                                                string tableEndpointInstance = ((string)tableEndpointValue);
                                                locationInstance.TableEndpoint = tableEndpointInstance;
                                            }

                                            JToken tableInfoArray = locationValue["tableInfo"];
                                            if (tableInfoArray != null && tableInfoArray.Type != JTokenType.Null)
                                            {
                                                foreach (JToken tableInfoValue in ((JArray)tableInfoArray))
                                                {
                                                    MetricTableInfo metricTableInfoInstance = new MetricTableInfo();
                                                    locationInstance.TableInfo.Add(metricTableInfoInstance);

                                                    JToken tableNameValue = tableInfoValue["tableName"];
                                                    if (tableNameValue != null && tableNameValue.Type != JTokenType.Null)
                                                    {
                                                        string tableNameInstance = ((string)tableNameValue);
                                                        metricTableInfoInstance.TableName = tableNameInstance;
                                                    }

                                                    JToken startTimeValue = tableInfoValue["startTime"];
                                                    if (startTimeValue != null && startTimeValue.Type != JTokenType.Null)
                                                    {
                                                        DateTime startTimeInstance = ((DateTime)startTimeValue);
                                                        metricTableInfoInstance.StartTime = startTimeInstance;
                                                    }

                                                    JToken endTimeValue = tableInfoValue["endTime"];
                                                    if (endTimeValue != null && endTimeValue.Type != JTokenType.Null)
                                                    {
                                                        DateTime endTimeInstance = ((DateTime)endTimeValue);
                                                        metricTableInfoInstance.EndTime = endTimeInstance;
                                                    }

                                                    JToken sasTokenValue = tableInfoValue["sasToken"];
                                                    if (sasTokenValue != null && sasTokenValue.Type != JTokenType.Null)
                                                    {
                                                        string sasTokenInstance = ((string)sasTokenValue);
                                                        metricTableInfoInstance.SasToken = sasTokenInstance;
                                                    }

                                                    JToken sasTokenExpirationTimeValue = tableInfoValue["sasTokenExpirationTime"];
                                                    if (sasTokenExpirationTimeValue != null && sasTokenExpirationTimeValue.Type != JTokenType.Null)
                                                    {
                                                        DateTime sasTokenExpirationTimeInstance = ((DateTime)sasTokenExpirationTimeValue);
                                                        metricTableInfoInstance.SasTokenExpirationTime = sasTokenExpirationTimeInstance;
                                                    }
                                                }
                                            }

                                            JToken partitionKeyValue = locationValue["partitionKey"];
                                            if (partitionKeyValue != null && partitionKeyValue.Type != JTokenType.Null)
                                            {
                                                string partitionKeyInstance = ((string)partitionKeyValue);
                                                locationInstance.PartitionKey = partitionKeyInstance;
                                            }
                                        }
                                    }
                                }

                                JToken propertiesSequenceElement = ((JToken)valueValue["properties"]);
                                if (propertiesSequenceElement != null && propertiesSequenceElement.Type != JTokenType.Null)
                                {
                                    foreach (JProperty property in propertiesSequenceElement)
                                    {
                                        string propertiesKey   = ((string)property.Name);
                                        string propertiesValue = ((string)property.Value);
                                        metricDefinitionInstance.Properties.Add(propertiesKey, propertiesValue);
                                    }
                                }
                            }
                        }
                    }

                    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();
                }
            }
        }
 private static CloudTable GetTableReference(MetricLocation location, MetricTableInfo tableInfo)
 {
     return(new CloudTableClient(new Uri(location.TableEndpoint), new StorageCredentials(tableInfo.SasToken)).GetTableReference(tableInfo.TableName));
 }
        /// <summary>
        /// The List Metric Definitions operation lists the metric definitions
        /// for the resource.
        /// </summary>
        /// <param name='resourceUri'>
        /// Required. The resource identifier of the target resource to get
        /// metrics for.
        /// </param>
        /// <param name='filterString'>
        /// Optional. An OData $filter expression that supports querying by the
        /// name of the metric definition. For example, "name.value eq
        /// 'Percentage CPU'". Name is optional, meaning the expression may be
        /// "".
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// The List Metric Definitions operation response.
        /// </returns>
        internal async Task <MetricDefinitionListResponse> GetMetricDefinitionsInternalAsync(string resourceUri, string filterString, CancellationToken cancellationToken)
        {
            // Validate
            if (resourceUri == null)
            {
                throw new ArgumentNullException("resourceUri");
            }

            // Tracing
            bool   shouldTrace  = TracingAdapter.IsEnabled;
            string invocationId = null;

            if (shouldTrace)
            {
                invocationId = TracingAdapter.NextInvocationId.ToString();
                Dictionary <string, object> tracingParameters = new Dictionary <string, object>();
                tracingParameters.Add("resourceUri", resourceUri);
                tracingParameters.Add("filterString", filterString);
                TracingAdapter.Enter(invocationId, this, "GetMetricDefinitionsAsync", tracingParameters);
            }

            #region Manually added

            // We need to handle document db differently for now until they onboard to shoebox.
            // Construct URL
            string url = "";
            url = url + "/";
            url = url + resourceUri;
            List <string> queryParameters = new List <string>();
            if (Util.IsLegacyResource(resourceUri))
            {
                url = url + "/metricDefinitions";
                queryParameters.Add("api-version=2014-04-01");
            }
            else
            {
                url = url + "/providers/microsoft.insights/metricDefinitions";
                queryParameters.Add("api-version=2015-07-01");
            }

            #endregion

            List <string> odataFilter = new List <string>();
            if (filterString != null)
            {
                odataFilter.Add(Uri.EscapeDataString(filterString));
            }
            if (odataFilter.Count > 0)
            {
                queryParameters.Add("$filter=" + string.Join(null, odataFilter));
            }
            if (queryParameters.Count > 0)
            {
                url = url + "?" + string.Join("&", queryParameters);
            }
            string baseUrl = this.Client.BaseUri.AbsoluteUri;
            // Trim '/' character from the end of baseUrl and beginning of url.
            if (baseUrl[baseUrl.Length - 1] == '/')
            {
                baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
            }
            if (url[0] == '/')
            {
                url = url.Substring(1);
            }
            url = baseUrl + "/" + url;
            url = url.Replace(" ", "%20");

            // 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("Accept", "application/json");
                httpRequest.Headers.Add("x-ms-version", "2014-04-01");

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

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        TracingAdapter.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                    if (shouldTrace)
                    {
                        TracingAdapter.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));
                        if (shouldTrace)
                        {
                            TracingAdapter.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    MetricDefinitionListResponse result = null;
                    // Deserialize Response
                    if (statusCode == HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

                        result = new MetricDefinitionListResponse();
                        JToken responseDoc = null;
                        if (string.IsNullOrEmpty(responseContent) == false)
                        {
                            responseDoc = JToken.Parse(responseContent);
                        }

                        if (responseDoc != null && responseDoc.Type != JTokenType.Null)
                        {
                            MetricDefinitionCollection metricDefinitionCollectionInstance = new MetricDefinitionCollection();
                            result.MetricDefinitionCollection = metricDefinitionCollectionInstance;

                            JToken valueArray = responseDoc["value"];
                            if (valueArray != null && valueArray.Type != JTokenType.Null)
                            {
                                foreach (JToken valueValue in ((JArray)valueArray))
                                {
                                    MetricDefinition metricDefinitionInstance = new MetricDefinition();
                                    metricDefinitionCollectionInstance.Value.Add(metricDefinitionInstance);

                                    JToken nameValue = valueValue["name"];
                                    if (nameValue != null && nameValue.Type != JTokenType.Null)
                                    {
                                        LocalizableString nameInstance = new LocalizableString();
                                        metricDefinitionInstance.Name = nameInstance;

                                        JToken valueValue2 = nameValue["value"];
                                        if (valueValue2 != null && valueValue2.Type != JTokenType.Null)
                                        {
                                            string valueInstance = ((string)valueValue2);
                                            nameInstance.Value = valueInstance;
                                        }

                                        JToken localizedValueValue = nameValue["localizedValue"];
                                        if (localizedValueValue != null && localizedValueValue.Type != JTokenType.Null)
                                        {
                                            string localizedValueInstance = ((string)localizedValueValue);
                                            nameInstance.LocalizedValue = localizedValueInstance;
                                        }
                                    }

                                    JToken unitValue = valueValue["unit"];
                                    if (unitValue != null && unitValue.Type != JTokenType.Null)
                                    {
                                        Unit unitInstance = ((Unit)Enum.Parse(typeof(Unit), ((string)unitValue), true));
                                        metricDefinitionInstance.Unit = unitInstance;
                                    }

                                    JToken primaryAggregationTypeValue = valueValue["primaryAggregationType"];
                                    if (primaryAggregationTypeValue != null && primaryAggregationTypeValue.Type != JTokenType.Null)
                                    {
                                        AggregationType primaryAggregationTypeInstance = ((AggregationType)Enum.Parse(typeof(AggregationType), ((string)primaryAggregationTypeValue), true));
                                        metricDefinitionInstance.PrimaryAggregationType = primaryAggregationTypeInstance;
                                    }

                                    JToken resourceUriValue = valueValue["resourceUri"];
                                    if (resourceUriValue != null && resourceUriValue.Type != JTokenType.Null)
                                    {
                                        string resourceUriInstance = ((string)resourceUriValue);
                                        metricDefinitionInstance.ResourceId = resourceUriInstance;
                                    }

                                    JToken metricAvailabilitiesArray = valueValue["metricAvailabilities"];
                                    if (metricAvailabilitiesArray != null && metricAvailabilitiesArray.Type != JTokenType.Null)
                                    {
                                        foreach (JToken metricAvailabilitiesValue in ((JArray)metricAvailabilitiesArray))
                                        {
                                            MetricAvailability metricAvailabilityInstance = new MetricAvailability();
                                            metricDefinitionInstance.MetricAvailabilities.Add(metricAvailabilityInstance);

                                            JToken timeGrainValue = metricAvailabilitiesValue["timeGrain"];
                                            if (timeGrainValue != null && timeGrainValue.Type != JTokenType.Null)
                                            {
                                                TimeSpan timeGrainInstance = XmlConvert.ToTimeSpan(((string)timeGrainValue));
                                                metricAvailabilityInstance.TimeGrain = timeGrainInstance;
                                            }

                                            JToken retentionValue = metricAvailabilitiesValue["retention"];
                                            if (retentionValue != null && retentionValue.Type != JTokenType.Null)
                                            {
                                                TimeSpan retentionInstance = XmlConvert.ToTimeSpan(((string)retentionValue));
                                                metricAvailabilityInstance.Retention = retentionInstance;
                                            }

                                            JToken locationValue = metricAvailabilitiesValue["location"];
                                            if (locationValue != null && locationValue.Type != JTokenType.Null)
                                            {
                                                MetricLocation locationInstance = new MetricLocation();
                                                metricAvailabilityInstance.Location = locationInstance;

                                                JToken tableEndpointValue = locationValue["tableEndpoint"];
                                                if (tableEndpointValue != null && tableEndpointValue.Type != JTokenType.Null)
                                                {
                                                    string tableEndpointInstance = ((string)tableEndpointValue);
                                                    locationInstance.TableEndpoint = tableEndpointInstance;
                                                }

                                                JToken tableInfoArray = locationValue["tableInfo"];
                                                if (tableInfoArray != null && tableInfoArray.Type != JTokenType.Null)
                                                {
                                                    foreach (JToken tableInfoValue in ((JArray)tableInfoArray))
                                                    {
                                                        MetricTableInfo metricTableInfoInstance = new MetricTableInfo();
                                                        locationInstance.TableInfo.Add(metricTableInfoInstance);

                                                        JToken tableNameValue = tableInfoValue["tableName"];
                                                        if (tableNameValue != null && tableNameValue.Type != JTokenType.Null)
                                                        {
                                                            string tableNameInstance = ((string)tableNameValue);
                                                            metricTableInfoInstance.TableName = tableNameInstance;
                                                        }

                                                        JToken startTimeValue = tableInfoValue["startTime"];
                                                        if (startTimeValue != null && startTimeValue.Type != JTokenType.Null)
                                                        {
                                                            DateTime startTimeInstance = ((DateTime)startTimeValue);
                                                            metricTableInfoInstance.StartTime = startTimeInstance;
                                                        }

                                                        JToken endTimeValue = tableInfoValue["endTime"];
                                                        if (endTimeValue != null && endTimeValue.Type != JTokenType.Null)
                                                        {
                                                            DateTime endTimeInstance = ((DateTime)endTimeValue);
                                                            metricTableInfoInstance.EndTime = endTimeInstance;
                                                        }

                                                        JToken sasTokenValue = tableInfoValue["sasToken"];
                                                        if (sasTokenValue != null && sasTokenValue.Type != JTokenType.Null)
                                                        {
                                                            string sasTokenInstance = ((string)sasTokenValue);
                                                            metricTableInfoInstance.SasToken = sasTokenInstance;
                                                        }

                                                        JToken sasTokenExpirationTimeValue = tableInfoValue["sasTokenExpirationTime"];
                                                        if (sasTokenExpirationTimeValue != null && sasTokenExpirationTimeValue.Type != JTokenType.Null)
                                                        {
                                                            DateTime sasTokenExpirationTimeInstance = ((DateTime)sasTokenExpirationTimeValue);
                                                            metricTableInfoInstance.SasTokenExpirationTime = sasTokenExpirationTimeInstance;
                                                        }
                                                    }
                                                }

                                                JToken partitionKeyValue = locationValue["partitionKey"];
                                                if (partitionKeyValue != null && partitionKeyValue.Type != JTokenType.Null)
                                                {
                                                    string partitionKeyInstance = ((string)partitionKeyValue);
                                                    locationInstance.PartitionKey = partitionKeyInstance;
                                                }
                                            }

                                            JToken blobLocationValue = metricAvailabilitiesValue["blobLocation"];
                                            if (blobLocationValue != null && blobLocationValue.Type != JTokenType.Null)
                                            {
                                                BlobLocation blobLocationInstance = new BlobLocation();
                                                metricAvailabilityInstance.BlobLocation = blobLocationInstance;

                                                JToken blobEndpointValue = blobLocationValue["blobEndpoint"];
                                                if (blobEndpointValue != null && blobEndpointValue.Type != JTokenType.Null)
                                                {
                                                    string blobEndpointInstance = ((string)blobEndpointValue);
                                                    blobLocationInstance.BlobEndpoint = blobEndpointInstance;
                                                }

                                                JToken blobInfoArray = blobLocationValue["blobInfo"];
                                                if (blobInfoArray != null && blobInfoArray.Type != JTokenType.Null)
                                                {
                                                    foreach (JToken blobInfoValue in ((JArray)blobInfoArray))
                                                    {
                                                        BlobInfo blobInfoInstance = new BlobInfo();
                                                        blobLocationInstance.BlobInfo.Add(blobInfoInstance);

                                                        JToken blobUriValue = blobInfoValue["blobUri"];
                                                        if (blobUriValue != null && blobUriValue.Type != JTokenType.Null)
                                                        {
                                                            string blobUriInstance = ((string)blobUriValue);
                                                            blobInfoInstance.BlobUri = blobUriInstance;
                                                        }

                                                        JToken startTimeValue2 = blobInfoValue["startTime"];
                                                        if (startTimeValue2 != null && startTimeValue2.Type != JTokenType.Null)
                                                        {
                                                            DateTime startTimeInstance2 = ((DateTime)startTimeValue2);
                                                            blobInfoInstance.StartTime = startTimeInstance2;
                                                        }

                                                        JToken endTimeValue2 = blobInfoValue["endTime"];
                                                        if (endTimeValue2 != null && endTimeValue2.Type != JTokenType.Null)
                                                        {
                                                            DateTime endTimeInstance2 = ((DateTime)endTimeValue2);
                                                            blobInfoInstance.EndTime = endTimeInstance2;
                                                        }

                                                        JToken sasTokenValue2 = blobInfoValue["sasToken"];
                                                        if (sasTokenValue2 != null && sasTokenValue2.Type != JTokenType.Null)
                                                        {
                                                            string sasTokenInstance2 = ((string)sasTokenValue2);
                                                            blobInfoInstance.SasToken = sasTokenInstance2;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    JToken propertiesSequenceElement = ((JToken)valueValue["properties"]);
                                    if (propertiesSequenceElement != null && propertiesSequenceElement.Type != JTokenType.Null)
                                    {
                                        foreach (JProperty property in propertiesSequenceElement)
                                        {
                                            string propertiesKey   = ((string)property.Name);
                                            string propertiesValue = ((string)property.Value);
                                            metricDefinitionInstance.Properties.Add(propertiesKey, propertiesValue);
                                        }
                                    }

                                    JToken dimensionsArray = valueValue["dimensions"];
                                    if (dimensionsArray != null && dimensionsArray.Type != JTokenType.Null)
                                    {
                                        foreach (JToken dimensionsValue in ((JArray)dimensionsArray))
                                        {
                                            Dimension dimensionInstance = new Dimension();
                                            metricDefinitionInstance.Dimensions.Add(dimensionInstance);

                                            JToken nameValue2 = dimensionsValue["name"];
                                            if (nameValue2 != null && nameValue2.Type != JTokenType.Null)
                                            {
                                                LocalizableString nameInstance2 = new LocalizableString();
                                                dimensionInstance.Name = nameInstance2;

                                                JToken valueValue3 = nameValue2["value"];
                                                if (valueValue3 != null && valueValue3.Type != JTokenType.Null)
                                                {
                                                    string valueInstance2 = ((string)valueValue3);
                                                    nameInstance2.Value = valueInstance2;
                                                }

                                                JToken localizedValueValue2 = nameValue2["localizedValue"];
                                                if (localizedValueValue2 != null && localizedValueValue2.Type != JTokenType.Null)
                                                {
                                                    string localizedValueInstance2 = ((string)localizedValueValue2);
                                                    nameInstance2.LocalizedValue = localizedValueInstance2;
                                                }
                                            }

                                            JToken valuesArray = dimensionsValue["values"];
                                            if (valuesArray != null && valuesArray.Type != JTokenType.Null)
                                            {
                                                foreach (JToken valuesValue in ((JArray)valuesArray))
                                                {
                                                    LocalizableString localizableStringInstance = new LocalizableString();
                                                    dimensionInstance.Values.Add(localizableStringInstance);

                                                    JToken valueValue4 = valuesValue["value"];
                                                    if (valueValue4 != null && valueValue4.Type != JTokenType.Null)
                                                    {
                                                        string valueInstance3 = ((string)valueValue4);
                                                        localizableStringInstance.Value = valueInstance3;
                                                    }

                                                    JToken localizedValueValue3 = valuesValue["localizedValue"];
                                                    if (localizedValueValue3 != null && localizedValueValue3.Type != JTokenType.Null)
                                                    {
                                                        string localizedValueInstance3 = ((string)localizedValueValue3);
                                                        localizableStringInstance.LocalizedValue = localizedValueInstance3;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

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