public CollectionConfigurationAccumulator(CollectionConfiguration collectionConfiguration)
        {
            this.CollectionConfiguration = collectionConfiguration;

            // prepare the accumulators based on the collection configuration
            IEnumerable <Tuple <string, AggregationType> > allMetrics = collectionConfiguration?.TelemetryMetadata;

            foreach (Tuple <string, AggregationType> metricId in allMetrics ?? Enumerable.Empty <Tuple <string, AggregationType> >())
            {
                var accumulatedValues = new AccumulatedValues(metricId.Item1, metricId.Item2);

                this.MetricAccumulators.Add(metricId.Item1, accumulatedValues);
            }
        }
        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();
        }