/// <summary>
        /// AppDomain aware singleton initialization. All calls except the very first one in the process are ignored.
        /// </summary>
        /// <param name="serverUrl">Url of Seq server</param>
        /// <param name="apiKey">API Key if you have any</param>
        /// <param name="batchPostingLimit">Number of events posted per batch</param>
        /// <param name="period">Time to wait between checking for event batches</param>
        /// <param name="baseBufferFilename">Filename of the backing</param>
        /// <param name="bufferFileSizeLimitBytes"></param>
        public void Initialize(string serverUrl, string apiKey, int batchPostingLimit, TimeSpan period, string baseBufferFilename, long? bufferFileSizeLimitBytes)
        {
            lock (_initializeSyncRoot)
            {
                if (_sink != null) return;

                _sink = new DurableSeqSink(serverUrl, baseBufferFilename, apiKey, batchPostingLimit, period, bufferFileSizeLimitBytes);
            }
        }
        /// <summary>
        /// Adds a sink that writes log events to a http://getseq.net Seq event server.
        /// </summary>
        /// <param name="loggerSinkConfiguration">The logger configuration.</param>
        /// <param name="serverUrl">The base URL of the Seq server that log events will be written to.</param>
        /// <param name="restrictedToMinimumLevel">The minimum log event level required 
        /// in order to write an event to the sink.</param>
        /// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
        /// <param name="period">The time to wait between checking for event batches.</param>
        /// <param name="bufferBaseFilename">Path for a set of files that will be used to buffer events until they
        /// can be successfully transmitted across the network. Individual files will be created using the
        /// pattern <paramref name="bufferBaseFilename"/>-{Date}.json.</param>
        /// <param name="apiKey">A Seq <i>API key</i> that authenticates the client to the Seq server.</param>
        /// <param name="bufferFileSizeLimitBytes">The maximum size, in bytes, to which the buffer
        /// log file for a specific date will be allowed to grow. By default no limit will be applied.</param>
        /// <returns>Logger configuration, allowing configuration to continue.</returns>
        /// <exception cref="ArgumentNullException">A required parameter is null.</exception>
        public static LoggerConfiguration Seq(
            this LoggerSinkConfiguration loggerSinkConfiguration,
            string serverUrl,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            int batchPostingLimit = SeqSink.DefaultBatchPostingLimit,
            TimeSpan? period = null,
            string apiKey = null,
            string bufferBaseFilename = null,
            long? bufferFileSizeLimitBytes = null)
        {
            if (loggerSinkConfiguration == null) throw new ArgumentNullException("loggerSinkConfiguration");
            if (serverUrl == null) throw new ArgumentNullException("serverUrl");
            if (bufferFileSizeLimitBytes.HasValue && bufferFileSizeLimitBytes < 0) throw new ArgumentException("Negative value provided; file size limit must be non-negative");

            var defaultedPeriod = period ?? SeqSink.DefaultPeriod;

            ILogEventSink sink;
            if (bufferBaseFilename == null)
                sink = new SeqSink(serverUrl, apiKey, batchPostingLimit, defaultedPeriod);
            else
                sink = new DurableSeqSink(serverUrl, bufferBaseFilename, apiKey, batchPostingLimit, defaultedPeriod, bufferFileSizeLimitBytes);

            return loggerSinkConfiguration.Sink(sink, restrictedToMinimumLevel);
        }
        /// <summary>
        /// Adds a sink that writes log events to a http://getseq.net Seq event server.
        /// </summary>
        /// <param name="loggerSinkConfiguration">The logger configuration.</param>
        /// <param name="serverUrl">The base URL of the Seq server that log events will be written to.</param>
        /// <param name="restrictedToMinimumLevel">The minimum log event level required 
        /// in order to write an event to the sink.</param>
        /// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
        /// <param name="period">The time to wait between checking for event batches.</param>
        /// <param name="bufferBaseFilename">Path for a set of files that will be used to buffer events until they
        /// can be successfully transmitted across the network. Individual files will be created using the
        /// pattern <paramref name="bufferBaseFilename"/>-{Date}.json.</param>
        /// <param name="apiKey">A Seq <i>API key</i> that authenticates the client to the Seq server.</param>
        /// <param name="bufferFileSizeLimitBytes">The maximum size, in bytes, to which the buffer
        /// log file for a specific date will be allowed to grow. By default no limit will be applied.</param>
        /// <param name="eventBodyLimitBytes">The maximum size, in bytes, that the JSON representation of
        /// an event may take before it is dropped rather than being sent to the Seq server. Specify null for no limit.
        /// The default is 265 KB.</param>
        /// <param name="controlLevelSwitch">If provided, the switch will be updated based on the Seq server's level setting
        /// for the corresponding API key. Passing the same key to MinimumLevel.ControlledBy() will make the whole pipeline
        /// dynamically controlled. Do not specify <paramref name="restrictedToMinimumLevel"/> with this setting.</param>
        /// <param name="messageHandler">Used to construct the HttpClient that will be used to send the log meesages to Seq.</param>
        /// <param name="retainedInvalidPayloadsLimitBytes">A soft limit for the number of bytes to use for storing failed requests.  
        /// The limit is soft in that it can be exceeded by any single error payload, but in that case only that single error
        /// payload will be retained.</param>
        /// <returns>Logger configuration, allowing configuration to continue.</returns>
        /// <exception cref="ArgumentNullException">A required parameter is null.</exception>
        public static LoggerConfiguration Seq(
            this LoggerSinkConfiguration loggerSinkConfiguration,
            string serverUrl,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            int batchPostingLimit = SeqSink.DefaultBatchPostingLimit,
            TimeSpan? period = null,
            string apiKey = null,
            string bufferBaseFilename = null,
            long? bufferFileSizeLimitBytes = null,
            long? eventBodyLimitBytes = 256 * 1024,
            LoggingLevelSwitch controlLevelSwitch = null,
            HttpMessageHandler messageHandler = null,
            long? retainedInvalidPayloadsLimitBytes = null)
        {
            if (loggerSinkConfiguration == null) throw new ArgumentNullException(nameof(loggerSinkConfiguration));
            if (serverUrl == null) throw new ArgumentNullException(nameof(serverUrl));
            if (bufferFileSizeLimitBytes.HasValue && bufferFileSizeLimitBytes < 0) throw new ArgumentException("Negative value provided; file size limit must be non-negative");

            var defaultedPeriod = period ?? SeqSink.DefaultPeriod;

            ILogEventSink sink;

            if (bufferBaseFilename == null)
            {
                sink = new SeqSink(
                    serverUrl, 
                    apiKey, 
                    batchPostingLimit, 
                    defaultedPeriod, 
                    eventBodyLimitBytes,
                    controlLevelSwitch,
                    messageHandler);
            }
            else
            {
#if DURABLE
                sink = new DurableSeqSink(
                    serverUrl,
                    bufferBaseFilename,
                    apiKey,
                    batchPostingLimit,
                    defaultedPeriod,
                    bufferFileSizeLimitBytes,
                    eventBodyLimitBytes,
                    controlLevelSwitch,
                    messageHandler,
                    retainedInvalidPayloadsLimitBytes);
#else
                // We keep the API consistent for easier packaging and to support bait-and-switch.
                throw new NotSupportedException("Durable log shipping is not supported on this platform.");
#endif
            }

            return loggerSinkConfiguration.Sink(sink, restrictedToMinimumLevel);
        }