public static List <Object> InitializeSinks(
            IEnumerable <LttProducer> lttngProducers,
            IEnumerable <string> folderNames,
            Action <string> onInvalidCast)
        {
            var consumerSinks = new List <object>();

            // Get the union of the consumer sink lists from each of the Ltt producers
            // that depend on us
            foreach (var producer in lttngProducers)
            {
                if (null != producer.ConsumerSinks)
                {
                    consumerSinks = consumerSinks.Union(producer.ConsumerSinks).ToList();
                }
            }

            var sinks = new List <Object>();

            // Go through the consumer sinks,
            // Deliver the folder list to IFolderSink
            foreach (var sinkAsObject in consumerSinks)
            {
                ICsvFileSink csvFileSink = sinkAsObject as ICsvFileSink;
                if (csvFileSink != null)
                {
                    sinks.Add(csvFileSink);
                    continue;
                }

                IFolderSink csvFolderSink = sinkAsObject as IFolderSink;
                if (csvFolderSink != null)
                {
                    csvFolderSink.RegisterFolders(folderNames);
                    continue;
                }

                // Using IEtlFileSink since Ltt trace events are being serialized in binary format as in ETW events.
                IEtlFileSink etlFileSink = sinkAsObject as IEtlFileSink;
                if (etlFileSink != null)
                {
                    sinks.Add(etlFileSink);
                    continue;
                }

                onInvalidCast(
                    string.Format(
                        "Could not cast an object of type {0} to interface ICsvFileSink, IFolderSink, IEtlFileSink.",
                        sinkAsObject.GetType()));
            }

            return(sinks);
        }
        // TODO - Uncomment code below when totally transitioned to structured traces
        private void DeliverEventToSinks(ref EventRecord eventRecord, StringBuilder unstructuredTextString, bool isUnstructured)
        {
            var decodedEvent      = new DecodedEtwEvent();
            var decodingAttempted = false;
            var decodingFailed    = false;

            List <EventRecord>     rawEventList     = null;
            List <DecodedEtwEvent> decodedEventList = null;

            foreach (var sink in this.sinksIEtlFile)
            {
                if (sink.NeedsDecodedEvent)
                {
                    // This consumer needs the decoded event
                    if (false == decodingAttempted)
                    {
                        // We haven't yet attempted to decode the event. Attempt
                        // it now.
                        // For handling Linux legacy unstructured traces only
                        if (isUnstructured == true)
                        {
                            decodedEvent.StringRepresentation = unstructuredTextString.ToString();
                            decodingFailed    = false;
                            decodingAttempted = true;
                        }
                        else
                        {
                            try
                            {
                                string unusedOriginalEventName;

                                if (false == this.DecodeEvent(ref eventRecord, out decodedEvent, out unusedOriginalEventName))
                                {
                                    // Our attempt to decode the event failed
                                    decodingFailed = true;
                                }
                            }
                            catch (Exception e)
                            {
                                this.traceSource.WriteError(
                                    this.logSourceId,
                                    "Exception encountered while decoding Ltt event. The event will be skipped. Event ID: {0}, Task: {1}, Level: {2}. Exception information: {3}",
                                    eventRecord.EventHeader.EventDescriptor.Id,
                                    eventRecord.EventHeader.EventDescriptor.Task,
                                    eventRecord.EventHeader.EventDescriptor.Level,
                                    e);
                                decodingFailed = true;
                            }
                        }

                        if (false == decodingFailed)
                        {
                            // Our attempt to decode the event succeeded. Put it
                            // in the event list.
                            Debug.Assert(null == decodedEventList, "Decoded event list should not be initialized previously.");
                            decodedEventList = new List <DecodedEtwEvent> {
                                decodedEvent
                            };
                        }

                        decodingAttempted = true;
                    }

                    if (false == decodingFailed)
                    {
                        sink.OnEtwEventsAvailable(decodedEventList);
                    }
                }
                else
                {
                    if (isUnstructured == false)
                    {
                        // This consumer needs the raw event
                        if (null == rawEventList)
                        {
                            // Put the event in the event list
                            rawEventList = new List <EventRecord> {
                                eventRecord
                            };
                        }
                        if (sink is IEtlFileSink)
                        {
                            IEtlFileSink sinkEtl = sink as IEtlFileSink;
                            sinkEtl.OnEtwEventsAvailable(rawEventList);
                        }
                    }
                }
            }
        }