void ApplyDynamicConfiguration(bool initialConfigMustWaitForApplication)
        {
            Debug.Assert(_section != null);
            // It has been Obsolete (Warn) for a long time. Now we throw.
            if (_section["HandleAspNetLogs"] != null)
            {
                throw new CKException("Configuration name \"HandleAspNetLogs\" is obsolete: please use \"HandleDotNetLogs\" instead.");
            }
            if (_section["LogUnhandledExceptions"] != null)
            {
                throw new CKException("Configuration name \"LogUnhandledExceptions\" is not used anymore, it is now on the GrandOutput: use \"GrandOutput.TrackUnhandledExceptions\" instead (defaults to true).");
            }

            bool dotNetLogs = !String.Equals(_section["HandleDotNetLogs"], "false", StringComparison.OrdinalIgnoreCase);

            LogFilter defaultFilter                   = LogFilter.Undefined;
            bool      hasGlobalDefaultFilter          = _section["GlobalDefaultFilter"] != null;
            bool      errorParsingGlobalDefaultFilter = hasGlobalDefaultFilter && !LogFilter.TryParse(_section["GlobalDefaultFilter"], out defaultFilter);

            if (hasGlobalDefaultFilter && !errorParsingGlobalDefaultFilter)
            {
                if (initialConfigMustWaitForApplication)
                {
                    // On first initialization, configure the filter as early as possible.
                    if (defaultFilter.Group != LogLevelFilter.None && defaultFilter.Line != LogLevelFilter.None)
                    {
                        ActivityMonitor.DefaultFilter = defaultFilter;
                    }
                    // If the filter is invalid (a None appears}, keep the default Trace.
                }
                else
                {
                    // If a GlobalDefaultFilter has been successfully parsed and we are reconfiguring and it is different than
                    // the current one, logs the change and applies the configuration.
                    if (defaultFilter != ActivityMonitor.DefaultFilter)
                    {
                        Debug.Assert(_target != null, "Since !initialConfigMustWaitForApplication.");
                        defaultFilter = SetGlobalDefaultFilter(defaultFilter);
                    }
                }
            }

            try
            {
                GrandOutputConfiguration c = CreateConfigurationFromSection(_section);
                if (_target == null)
                {
                    Debug.Assert(_isDefaultGrandOutput && initialConfigMustWaitForApplication);
                    _target         = GrandOutput.EnsureActiveDefault(c);
                    _loggerProvider = new GrandOutputLoggerAdapterProvider(_target);
                }
                else
                {
                    Debug.Assert(_loggerProvider != null);
                    _target.ApplyConfiguration(c, initialConfigMustWaitForApplication);
                }
            }
            catch (Exception ex)
            {
                if (_target == null)
                {
                    // Using the default "Text" log configuration.
                    // If this fails (!), let the exception breaks the whole initialization since this
                    // is really unrecoverable.
                    _target         = GrandOutput.EnsureActiveDefault();
                    _loggerProvider = new GrandOutputLoggerAdapterProvider(_target);
                }
                _target.ExternalLog(Core.LogLevel.Fatal, message: $"While applying dynamic configuration.", ex: ex);
            }
            Debug.Assert(_loggerProvider != null);
            _loggerProvider._running = dotNetLogs;

            // Applying Tags.
            var rawTags = _section.GetSection("TagFilters").Get <string[][]>();

            if (rawTags != null && rawTags.Length > 0)
            {
                var tags = new List <(CKTrait, LogClamper)>();
                foreach (var bi in rawTags)
                {
                    if (bi != null && bi[0] != null && bi[1] != null)
                    {
                        var t = ActivityMonitor.Tags.Register(bi[0]);
                        if (!t.IsEmpty && LogClamper.TryParse(bi[1], out var c))
                        {
                            tags.Add((t, c));
                        }
                        else
                        {
                            if (t.IsEmpty)
                            {
                                _target.ExternalLog(Core.LogLevel.Warn, message: $"Ignoring TagFilters entry '{bi[0]},{bi[1]}'. Tag is empty");
                            }
                            else
                            {
                                _target.ExternalLog(Core.LogLevel.Warn, message: $"Ignoring TagFilters entry '{bi[0]},{bi[1]}'. Unable to parse clamp value. Expected a LogFilter (followed by an optional '!'): \"Debug\", \"Trace\", \"Verbose\", \"Monitor\", \"Terse\", \"Release\", \"Off\" or pairs of \"{{Group,Line}}\" levels where Group or Line can be Debug, Trace, Info, Warn, Error, Fatal or Off.");
                            }
                        }
                    }
                }
                ActivityMonitor.Tags.SetFilters(tags.ToArray());
            }

            if (hasGlobalDefaultFilter)
            {
                // Always log the parse error, but only log and applies if this is the initial configuration.
                if (errorParsingGlobalDefaultFilter)
                {
                    _target.ExternalLog(Core.LogLevel.Error, message: $"Unable to parse configuration 'GlobalDefaultFilter'. Expected \"Debug\", \"Trace\", \"Verbose\", \"Monitor\", \"Terse\", \"Release\", \"Off\" or pairs of \"{{Group,Line}}\" levels where Group or Line can be Debug, Trace, Info, Warn, Error, Fatal or Off.");
                }
                else if (initialConfigMustWaitForApplication)
                {
                    SetGlobalDefaultFilter(defaultFilter);
                }
            }
        }