private static async Task<IEnumerable<MetricValue>> GetMetricData(string resource, string metricName, DateTime startTimestamp, DateTime endTimestamp)
        {
            var timeWindow = endTimestamp - startTimestamp;

            if (timeWindow <= TimeSpan.FromMinutes(0) || timeWindow > TimeSpan.FromDays(31))
            {
                throw new InvalidOperationException("The number of minutes must be above 0 and less than one month.");
            }

            var authentication = await ResourceUtilities.GetAuthentication().ConfigureAwait(continueOnCapturedContext: false);
            var client = new Microsoft.Azure.Insights.InsightsClient(new TokenCloudCredentials(ConfigurationManager.AppSettings["AzureResourceConnector_SubscriptionId"], authentication.AccessToken));

            var metricDefinitions = await client.MetricDefinitionOperations.GetMetricDefinitionsAsync(resource, "name.value eq '" + metricName + "'", CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);

            var definitionResponse = metricDefinitions.MetricDefinitionCollection.Value;

            if (definitionResponse.FirstOrDefault() == null)
            {
                throw new InvalidOperationException("The metric you provided does not exist.");
            }

            var timeGrain = definitionResponse.FirstOrDefault().MetricAvailabilities.OrderBy(x => x.TimeGrain).FirstOrDefault();


            if (timeGrain == null || timeGrain.TimeGrain > timeWindow)
            {
                throw new InvalidOperationException("The metric does not have a time grain small enough for the window you provided. The smallest timegrain is: " + timeGrain.TimeGrain.Minutes);
            }

            var filter = "startTime eq " + startTimestamp.ToString("o") + " and endTime eq " + endTimestamp.ToString("o") + " and timeGrain eq duration'PT" + timeGrain.TimeGrain.Minutes + "M'";


            var metricResult = await client.MetricOperations.GetMetricsAsync(resource, filter, definitionResponse, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);

            if (metricResult.MetricCollection.Value.FirstOrDefault() == null)
            {
                throw new InvalidOperationException("There are not any data points for this metric in the time window you provided.");
            }

            return metricResult.MetricCollection.Value.FirstOrDefault().MetricValues;

        }
        private async static Task<IEnumerable<EventData>> GetEventData(string resource, string status, DateTime startTimestamp, DateTime endTimestamp)
        {
            var timeWindow = endTimestamp - startTimestamp;

            if (timeWindow <= TimeSpan.FromMinutes(0) || timeWindow > TimeSpan.FromDays(31))
            {
                throw new InvalidOperationException("The number of minutes must be above 0 and less than one month.");
            }

            var authentication = await ResourceUtilities.GetAuthentication().ConfigureAwait(continueOnCapturedContext: false);
            var client = new Microsoft.Azure.Insights.InsightsClient(new TokenCloudCredentials(ConfigurationManager.AppSettings["AzureResourceConnector_SubscriptionId"], authentication.AccessToken));

            var filter = "eventTimestamp ge '" + startTimestamp + "' and eventTimestamp le '" + endTimestamp + "' and eventChannels eq 'Admin, Operation'";

            if (resource != null)
            {
                var segments = resource.Split('/');
                if (segments.Count() > 7)
                {
                    filter += " and resourceUri eq '" + resource + "'";
                }
                else if (segments.Count() == 4)
                {
                    filter += " and resourceGroupName eq '" + ResourceUtilities.GetResourceGroupFromId(resource) + "'";
                }
            }

            if (status != null)
            {
                filter += " and status eq '" + status + "'";
            }

            var eventResult = await client.EventOperations.ListEventsAsync(filter, null, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);

            return eventResult.EventDataCollection.Value.OrderBy(x => x.EventTimestamp);
        }