/// <summary>
        /// Writes the event element.
        /// </summary>
        /// <param name="eventElement">An event element.</param>
        public void Write(EventElement eventElement)
        {
            //XML Example:
            //<stream>
            //  <event>
            //      <index>sdk-tests2</index>
            //      <sourcetype>test sourcetype</sourcetype>
            //      <source>test source</source>
            //      <host>test host</host>
            //      <data>Event with all default fields set</data>
            //  </event>
            //  <event stanza="modular_input://UnitTest2" unbroken="1">
            //      <data>Part 1 of channel 2 without a newline </data>
            //  </event>
            //</stream>

            xmlWriter.WriteStartElement("event");

            var stanza = eventElement.Stanza;

            if (stanza != null)
            {
                xmlWriter.WriteAttributeString("stanza", stanza);
            }

            if (eventElement.Unbroken)
            {
                xmlWriter.WriteAttributeString("unbroken", "1");
            }

            WriteElementIfNotNull(eventElement.Index, "index");
            WriteElementIfNotNull(eventElement.SourceType, "sourcetype");
            WriteElementIfNotNull(eventElement.Source, "source");
            WriteElementIfNotNull(eventElement.Host, "host");

            WriteElementIfNotNull(eventElement.Data, "data");

            var time = eventElement.Time;

            if (time != null)
            {
                xmlWriter.WriteElementString(
                    "time",
                    ConvertTimeToUtcUnixTimestamp(time.Value));
            }

            if (eventElement.Done)
            {
                xmlWriter.WriteStartElement("done");
                xmlWriter.WriteEndElement();
                Console.Out.Flush();
            }

            xmlWriter.WriteEndElement();
        }
        /// <summary>
        /// Writes the event element.
        /// </summary>
        /// <param name="eventElement">An event element.</param>
        public void Write(EventElement eventElement)
        {
            //XML Example:
            //<stream>
            //  <event>
            //      <index>sdk-tests2</index>
            //      <sourcetype>test sourcetype</sourcetype>
            //      <source>test source</source>
            //      <host>test host</host>
            //      <data>Event with all default fields set</data>
            //  </event>
            //  <event stanza="modular_input://UnitTest2" unbroken="1">
            //      <data>Part 1 of channel 2 without a newline </data>
            //  </event>
            //</stream>

            xmlWriter.WriteStartElement("event");

            var stanza = eventElement.Stanza;
            if (stanza != null)
            {
                xmlWriter.WriteAttributeString("stanza", stanza);
            }

            if (eventElement.Unbroken)
            {
                xmlWriter.WriteAttributeString("unbroken", "1");
            }

            WriteElementIfNotNull(eventElement.Index, "index");
            WriteElementIfNotNull(eventElement.SourceType, "sourcetype");
            WriteElementIfNotNull(eventElement.Source, "source");
            WriteElementIfNotNull(eventElement.Host, "host");

            WriteElementIfNotNull(eventElement.Data, "data");

            var time = eventElement.Time;
            if (time != null)
            {
                xmlWriter.WriteElementString(
                    "time",
                    ConvertTimeToUtcUnixTimestamp(time.Value));
            }

            if (eventElement.Done)
            {
                xmlWriter.WriteStartElement("done");
                xmlWriter.WriteEndElement();
                Console.Out.Flush();
            }

            xmlWriter.WriteEndElement();
        }
        /// <summary>
        /// Writes an <see cref="EventElement"/> to the standard output device.
        /// </summary>
        /// <param name="eventElement">
        /// An object representing an event element.
        /// </param>
        /// <remarks>
        /// <example>Sample event stream</example>
        /// <code>
        /// <stream>
        ///   <event>
        ///     <index>sdk-tests2</index>
        ///     <sourcetype>test sourcetype</sourcetype>
        ///     <source>test source</source>
        ///     <host>test host</host>
        ///     <data>Event with all default fields set</data>
        ///   </event>
        ///   <event stanza="modular_input:UnitTest2" unbroken="1">
        ///     <data>Part 1 of channel 2 without a newline </data>
        ///   </event>
        /// </stream>
        /// </code>
        /// </remarks>
        public async Task WriteEventAsync(EventElement eventElement)
        {
            if (this.xmlWriter.WriteState == WriteState.Start)
            {
                await this.xmlWriter.WriteStartElementAsync(prefix : null, localName : "stream", ns : null);
            }

            await this.xmlWriter.WriteStartElementAsync(prefix : null, localName : "event", ns : null);

            var stanza = eventElement.Stanza;

            if (stanza != null)
            {
                await this.xmlWriter.WriteAttributeStringAsync(prefix : null, localName : "stanza", ns : null, value : stanza);
            }

            if (eventElement.Unbroken)
            {
                await this.xmlWriter.WriteAttributeStringAsync(prefix : null, localName : "unbroken", ns : null, value : "1");
            }

            await this.WriteElementIfNotNullAsync("index", eventElement.Index);

            await this.WriteElementIfNotNullAsync("sourcetype", eventElement.SourceType);

            await this.WriteElementIfNotNullAsync("source", eventElement.Source);

            await this.WriteElementIfNotNullAsync("host", eventElement.Host);

            await this.WriteElementIfNotNullAsync("data", eventElement.Data);

            var time = eventElement.Time;

            if (time != null)
            {
                await this.xmlWriter.WriteElementStringAsync(
                    prefix : null, localName : "time", ns : null, value : ConvertTimeToUtcUnixTimestamp(time.Value));
            }

            if (eventElement.Done)
            {
                await this.xmlWriter.WriteStartElementAsync(prefix : null, localName : "done", ns : null);

                await this.xmlWriter.WriteEndElementAsync();

                await this.xmlWriter.FlushAsync();
            }

            await this.xmlWriter.WriteEndElementAsync();
        }
        /// <summary>
        ///     Write events using EventStreamWriter
        /// </summary>
        // This method can be used by manual testing thus is public
        public static void WriteEvents()
        {
            using (var writer = new EventStreamWriter())
            {
                var eventTemplate = new EventElement
                    {
                        Index = "sdk-tests2",
                        Host = "test host",
                        SourceType = "test sourcetype",
                        Source = "test source",
                    };

                WriteEventData(
                    writer,
                    eventTemplate,
                    "Event with all default fields set");

                WriteEventData(
                    writer,
                    eventTemplate,
                    "Letter O with double acute: \u0150");

                eventTemplate.Unbroken = true;

                WriteEventData(
                    writer,
                    eventTemplate,
                    "Part 1 of an unbroken event ");

                WriteEventData(
                    writer,
                    eventTemplate,
                    "Part 2 of an unbroken event ending with newline" + Environment.NewLine);

                WriteEventDone(
                    writer,
                    eventTemplate);

                eventTemplate.Unbroken = false;

                WriteEventData(
                    writer,
                    eventTemplate,
                    "Event after done key");

                var timedEvent = eventTemplate;
                timedEvent.Time = new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                timedEvent.Data = "Event with fixed time";
                writer.Write(timedEvent);

                WriteMultiplex(writer);
            }
        }
        /// <summary>
        ///     Write for multiple stanzas
        /// </summary>
        /// <param name="writer">An event writer</param>
        private static void WriteMultiplex(EventStreamWriter writer)
        {
            var eventTemplate1 = new EventElement
                {
                    Stanza = "modular_input://UnitTest1",
                    Unbroken = true,
                };

            var eventTemplate2 = new EventElement
                {
                    Stanza = "modular_input://UnitTest2",
                    Unbroken = true,
                };

            WriteEventDataLine(writer, eventTemplate1, "Part 1 of channel 1 with a newline");
            WriteEventData(writer, eventTemplate2, "Part 1 of channel 2 without a newline ");

            // Mark the first channel done.
            WriteEventDone(writer, eventTemplate1);

            WriteEventDataLine(writer, eventTemplate1, "Part 2 of channel 1 with a newline");
            WriteEventDataLine(writer, eventTemplate2, "Part 2 of channel 2 with a newline");

            // Mark the second channel done.
            WriteEventDone(writer, eventTemplate2);
        }
 /// <summary>
 ///     Write a done key
 /// </summary>
 /// <param name="writer">An event writer</param>
 /// <param name="eventTemplate">An event template</param>
 private static void WriteEventDone(EventStreamWriter writer, EventElement eventTemplate)
 {
     var @event = eventTemplate;
     @event.Unbroken = false;
     @event.Done = true;
     writer.Write(@event);
 }
 /// <summary>
 ///     Write an event data line.
 /// </summary>
 /// <param name="writer">An event writer</param>
 /// <param name="eventTemplate">An event template</param>
 /// <param name="eventData">Event data</param>
 private static void WriteEventDataLine(
     EventStreamWriter writer,
     EventElement eventTemplate,
     string eventData)
 {
     WriteEventData(
         writer,
         eventTemplate,
         eventData + Environment.NewLine);
 }
 /// <summary>
 ///     Write event data without appending a newline seperator.
 /// </summary>
 /// <param name="writer">An event writer</param>
 /// <param name="eventTemplate">An event template</param>
 /// <param name="eventData">Event data</param>
 private static void WriteEventData(EventStreamWriter writer, EventElement eventTemplate, string eventData)
 {
     var @event = eventTemplate;
     @event.Data = eventData;
     writer.Write(@event);
 }
        /// <summary>
        /// Writes an <see cref="EventElement"/> to the standard output device.
        /// </summary>
        /// <param name="eventElement">
        /// An object representing an event element.
        /// </param>
        /// <remarks>
        /// <example>Sample event stream</example>
        /// <code>
        /// <stream>
        ///   <event>
        ///     <index>sdk-tests2</index>
        ///     <sourcetype>test sourcetype</sourcetype>
        ///     <source>test source</source>
        ///     <host>test host</host>
        ///     <data>Event with all default fields set</data>
        ///   </event>
        ///   <event stanza="modular_input:UnitTest2" unbroken="1">
        ///     <data>Part 1 of channel 2 without a newline </data>
        ///   </event>
        /// </stream>
        /// </code>
        /// </remarks>
        public async Task WriteEventAsync(EventElement eventElement)
        {
            if (this.xmlWriter.WriteState == WriteState.Start)
            {
                await this.xmlWriter.WriteStartElementAsync(prefix: null, localName: "stream", ns: null);
            }

            await this.xmlWriter.WriteStartElementAsync(prefix: null, localName: "event", ns: null);
            var stanza = eventElement.Stanza;

            if (stanza != null)
            {
                await this.xmlWriter.WriteAttributeStringAsync(prefix: null, localName: "stanza", ns: null, value: stanza);
            }

            if (eventElement.Unbroken)
            {
                await this.xmlWriter.WriteAttributeStringAsync(prefix: null, localName: "unbroken", ns: null, value: "1");
            }

            await this.WriteElementIfNotNullAsync("index", eventElement.Index);
            await this.WriteElementIfNotNullAsync("sourcetype", eventElement.SourceType);
            await this.WriteElementIfNotNullAsync("source", eventElement.Source);
            await this.WriteElementIfNotNullAsync("host", eventElement.Host);
            await this.WriteElementIfNotNullAsync("data", eventElement.Data);

            var time = eventElement.Time;

            if (time != null)
            {
                await this.xmlWriter.WriteElementStringAsync(
                    prefix: null, localName: "time", ns: null, value: ConvertTimeToUtcUnixTimestamp(time.Value));
            }

            if (eventElement.Done)
            {
                await this.xmlWriter.WriteStartElementAsync(prefix: null, localName: "done", ns: null);
                await this.xmlWriter.WriteEndElementAsync();
                await this.xmlWriter.FlushAsync();
            }

            await this.xmlWriter.WriteEndElementAsync();
        }
 /// <summary>
 ///     Write event data without appending a newline seperator.
 /// </summary>
 /// <param name="writer">An event writer</param>
 /// <param name="eventTemplate">An event template</param>
 /// <param name="eventData">Event data</param>
 static async Task WriteEventData(EventStreamWriter writer, EventElement eventTemplate, string eventData)
 {
     var @event = eventTemplate;
     @event.Data = eventData;
     await writer.WriteEventAsync(@event);
 }
 /// <summary>
 ///     Write an event data line.
 /// </summary>
 /// <param name="writer">An event writer</param>
 /// <param name="eventTemplate">An event template</param>
 /// <param name="eventData">Event data</param>
 static async Task WriteEventDataLine(
     EventStreamWriter writer,
     EventElement eventTemplate,
     string eventData)
 {
     await WriteEventData(
         writer,
         eventTemplate,
         eventData + Environment.NewLine);
 }
 /// <summary>
 ///     Write a done key
 /// </summary>
 /// <param name="writer">An event writer</param>
 /// <param name="eventTemplate">An event template</param>
 static async Task WriteEventDone(EventStreamWriter writer, EventElement eventTemplate)
 {
     var @event = eventTemplate;
     @event.Unbroken = false;
     @event.Done = true;
     await writer.WriteEventAsync(@event);
 }