/// <summary>
        /// Process a collected telemetry item.
        /// </summary>
        /// <param name="item">A collected Telemetry item.</param>
        public void Process(ITelemetry item)
        {
            if (this.EventSourceInternal == null)
            {
                return;
            }

            Action <ITelemetry> handler = null;
            var itemType = item.GetType();

            if (this.telemetryHandlers.TryGetValue(itemType, out handler))
            {
                item.FlattenIExtensionIfExists();
                handler(item);
            }
            else
            {
                if (this.unknownTelemetryHandler != null)
                {
                    item.Sanitize();
                    EventData telemetryData = item.FlattenTelemetryIntoEventData();
                    telemetryData.name = Constants.EventNameForUnknownTelemetry;

                    this.unknownTelemetryHandler(telemetryData, item.Context.InstrumentationKey, item.Context.SanitizedTags, item.Context.Flags);
                }
            }
        }
        /// <summary>
        /// Process a collected telemetry item.
        /// </summary>
        /// <param name="item">A collected Telemetry item.</param>
        public void Process(ITelemetry item)
        {
            if (item is RequestTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Requests))
                {
                    return;
                }

                var telemetryItem = item as RequestTelemetry;
                // Sanitize, Copying global properties is to be done before calling .Data,
                // as Data returns a singleton instance, which won't be updated with changes made
                // after .Data is called.
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    RequestTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.Requests);
            }
            else if (item is TraceTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Traces))
                {
                    return;
                }

                var telemetryItem = item as TraceTelemetry;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    TraceTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.Traces);
            }
            else if (item is EventTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Events))
                {
                    return;
                }

                var telemetryItem = item as EventTelemetry;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    EventTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.Events);
            }
            else if (item is DependencyTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Dependencies))
                {
                    return;
                }

                var telemetryItem = item as DependencyTelemetry;
                // Sanitize, Copying global properties is to be done before calling .InternalData,
                // as InternalData returns a singleton instance, which won't be updated with changes made
                // after .InternalData is called.
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    DependencyTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.InternalData,
                    telemetryItem.Context.Flags,
                    Keywords.Dependencies);
            }
            else if (item is MetricTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Metrics))
                {
                    return;
                }

                var telemetryItem = item as MetricTelemetry;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    MetricTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.Metrics);
            }
            else if (item is ExceptionTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Exceptions))
                {
                    return;
                }

                var telemetryItem = item as ExceptionTelemetry;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    ExceptionTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data.Data,
                    telemetryItem.Context.Flags,
                    Keywords.Exceptions);
            }
#pragma warning disable 618
            else if (item is PerformanceCounterTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Metrics))
                {
                    return;
                }

                var telemetryItem = (item as PerformanceCounterTelemetry).Data;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    MetricTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.Metrics);
            }
#pragma warning restore 618
            else if (item is PageViewTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.PageViews))
                {
                    return;
                }

                var telemetryItem = item as PageViewTelemetry;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    PageViewTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.PageViews);
            }
            else if (item is PageViewPerformanceTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.PageViewPerformance))
                {
                    return;
                }

                var telemetryItem = item as PageViewPerformanceTelemetry;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    PageViewPerformanceTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.PageViewPerformance);
            }
#pragma warning disable 618
            else if (item is SessionStateTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Events))
                {
                    return;
                }

                var telemetryItem = (item as SessionStateTelemetry).Data;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    EventTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.Events);
            }
            else if (item is AvailabilityTelemetry)
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Availability))
                {
                    return;
                }

                var telemetryItem = item as AvailabilityTelemetry;
                telemetryItem.FlattenIExtensionIfExists();
                CopyGlobalPropertiesIfRequired(item, telemetryItem.Properties);
                item.Sanitize();
                this.WriteEvent(
                    AvailabilityTelemetry.EtwEnvelopeName,
                    telemetryItem.Context.InstrumentationKey,
                    telemetryItem.Context.SanitizedTags,
                    telemetryItem.Data,
                    telemetryItem.Context.Flags,
                    Keywords.Availability);
            }
            else
            {
                if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.Events))
                {
                    return;
                }

                item.Sanitize();

                EventData telemetryData = item.FlattenTelemetryIntoEventData();
                telemetryData.name = Constants.EventNameForUnknownTelemetry;

                this.WriteEvent(
                    EventTelemetry.EtwEnvelopeName,
                    item.Context.InstrumentationKey,
                    item.Context.SanitizedTags,
                    telemetryData,
                    item.Context.Flags,
                    Keywords.Events);
            }
        }