public CollectionConfiguration(
            CollectionConfigurationInfo info,
            out CollectionConfigurationError[] errors,
            Clock timeProvider,
            IEnumerable <DocumentStream> previousDocumentStreams = null)
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            this.info = info;

            // create metrics based on descriptions in info
            this.CreateTelemetryMetrics(info, out CollectionConfigurationError[] metricErrors);

            // maintain a separate collection of all (Id, AggregationType) pairs with some additional data - to allow for uniform access to all types of metrics
            // this includes both telemetry metrics and Metric metrics
            this.CreateMetadata();

            // create document streams based on description in info
            this.CreateDocumentStreams(out CollectionConfigurationError[] documentStreamErrors, timeProvider, previousDocumentStreams ?? new DocumentStream[0]);

            // create performance counters
            this.CreatePerformanceCounters(out CollectionConfigurationError[] performanceCounterErrors);

            errors = metricErrors.Concat(documentStreamErrors).Concat(performanceCounterErrors).ToArray();

            foreach (var error in errors)
            {
                error.Data["ETag"] = this.info.ETag;
            }
        }
        private void CreateTelemetryMetrics(CollectionConfigurationInfo info, out CollectionConfigurationError[] errors)
        {
            var errorList = new List <CollectionConfigurationError>();
            var metricIds = new HashSet <string>();

            foreach (CalculatedMetricInfo metricInfo in info.Metrics ?? new CalculatedMetricInfo[0])
            {
                if (metricIds.Contains(metricInfo.Id))
                {
                    // there must not be metrics with duplicate ids
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.MetricDuplicateIds,
                            string.Format(CultureInfo.InvariantCulture, "Metric with a duplicate id ignored: {0}", metricInfo.Id),
                            null,
                            Tuple.Create("MetricId", metricInfo.Id)));

                    continue;
                }

                CollectionConfigurationError[] localErrors = null;
                switch (metricInfo.TelemetryType)
                {
                case TelemetryType.Request:
                    CollectionConfiguration.AddMetric(metricInfo, this.requestTelemetryMetrics, out localErrors);
                    break;

                case TelemetryType.Dependency:
                    CollectionConfiguration.AddMetric(metricInfo, this.dependencyTelemetryMetrics, out localErrors);
                    break;

                case TelemetryType.Exception:
                    CollectionConfiguration.AddMetric(metricInfo, this.exceptionTelemetryMetrics, out localErrors);
                    break;

                case TelemetryType.Event:
                    CollectionConfiguration.AddMetric(metricInfo, this.eventTelemetryMetrics, out localErrors);
                    break;

                case TelemetryType.PerformanceCounter:
                    // no need to create a wrapper, we rely on the underlying CollectionConfigurationInfo to provide data about performance counters
                    // move on to the next metric
                    continue;

                case TelemetryType.Trace:
                    CollectionConfiguration.AddMetric(metricInfo, this.traceTelemetryMetrics, out localErrors);
                    break;

                default:
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.MetricTelemetryTypeUnsupported,
                            string.Format(CultureInfo.InvariantCulture, "TelemetryType is not supported: {0}", metricInfo.TelemetryType),
                            null,
                            Tuple.Create("MetricId", metricInfo.Id),
                            Tuple.Create("TelemetryType", metricInfo.TelemetryType.ToString())));
                    break;
                }

                errorList.AddRange(localErrors ?? new CollectionConfigurationError[0]);

                metricIds.Add(metricInfo.Id);
            }

            errors = errorList.ToArray();
        }