/// <summary>
        /// Fetches the attributes in document variant option as well as the entire documentation itself
        /// and populate the document variant info objects.
        /// </summary>
        /// <param name="documents">The documents to be updated.</param>
        /// <param name="element">The xml element containing document-level config in the config xml.</param>
        /// <param name="xmlDocuments">The list of XDocuments representing the annotation xmls.</param>
        /// <param name="settings">The document config filter settings.</param>
        /// <exception cref="ConflictingDocumentVariantAttributesException">
        /// Thrown when there is a conflict
        /// between the attributes in the existing document variant info and the new one.
        /// </exception>
        public void Apply(
            IDictionary <DocumentVariantInfo, OpenApiDocument> documents,
            XElement element,
            IList <XDocument> xmlDocuments,
            DocumentConfigFilterSettings settings)
        {
            var variantElements = element.Elements(KnownXmlStrings.Variant);

            foreach (var variantElement in variantElements)
            {
                // First, populate the document variant info attributes using the document variant option.
                var variantOptions = variantElement.Element(KnownXmlStrings.Options)?.Elements(KnownXmlStrings.Option);

                if (variantOptions != null)
                {
                    foreach (var variantOption in variantOptions)
                    {
                        var documentVariantInfo = new DocumentVariantInfo
                        {
                            Title       = variantOption.Value,
                            Categorizer = variantElement.Element(KnownXmlStrings.Name)?.Value
                        };

                        foreach (var attribute in variantOption.Attributes())
                        {
                            if (!documentVariantInfo.Attributes.ContainsKey(attribute.Name.ToString()))
                            {
                                documentVariantInfo.Attributes[attribute.Name.ToString()] = attribute.Value;
                            }
                        }

                        PopulateAttributesInExistingDocumentVariantInfo(documents, documentVariantInfo);
                    }
                }

                // Second, populate the document variant info attributes using the information from the documents.
                var allCategorizerNodes = new List <XElement>();

                foreach (var xmlDocument in xmlDocuments)
                {
                    allCategorizerNodes.AddRange(
                        xmlDocument.Descendants(variantElement.Element(KnownXmlStrings.Name)?.Value));
                }

                foreach (var categorizerNode in allCategorizerNodes)
                {
                    var documentVariantInfo = new DocumentVariantInfo
                    {
                        Title       = categorizerNode.Value,
                        Categorizer = categorizerNode.Name.ToString()
                    };

                    foreach (var attribute in categorizerNode.Attributes())
                    {
                        if (!documentVariantInfo.Attributes.ContainsKey(attribute.Name.ToString()))
                        {
                            documentVariantInfo.Attributes[attribute.Name.ToString()] = attribute.Value;
                        }
                    }

                    PopulateAttributesInExistingDocumentVariantInfo(documents, documentVariantInfo);
                }
            }
        }
        /// <summary>
        /// Fetches the attributes in document variant option as well as the entire documentation itself
        /// and populate the document variant info objects.
        /// </summary>
        /// <param name="documents">The documents to be updated.</param>
        /// <param name="element">The xml element containing document-level config in the config xml.</param>
        /// <param name="xmlDocuments">The list of XDocuments representing the annotation xmls.</param>
        /// <param name="settings">The document config filter settings.</param>
        /// <exception cref="ConflictingDocumentVariantAttributesException">
        /// Thrown when there is a conflict
        /// between the attributes in the existing document variant info and the new one.
        /// </exception>
        /// <returns>The list of generation errors, if any produced when processing the filter.</returns>
        public IList <GenerationError> Apply(
            IDictionary <DocumentVariantInfo, OpenApiDocument> documents,
            XElement element,
            IList <XDocument> xmlDocuments,
            DocumentConfigFilterSettings settings)
        {
            var generationErrors = new List <GenerationError>();

            if (element == null || xmlDocuments == null)
            {
                return(generationErrors);
            }


            try
            {
                var variantElements = element.Elements(KnownXmlStrings.Variant);

                foreach (var variantElement in variantElements)
                {
                    // First, populate the document variant info attributes using the document variant option.
                    var variantOptions = variantElement.Element(KnownXmlStrings.Options)?.Elements(KnownXmlStrings.Option);

                    if (variantOptions != null)
                    {
                        foreach (var variantOption in variantOptions)
                        {
                            var documentVariantInfo = new DocumentVariantInfo
                            {
                                Title       = variantOption.Value,
                                Categorizer = variantElement.Element(KnownXmlStrings.Name)?.Value
                            };

                            foreach (var attribute in variantOption.Attributes())
                            {
                                if (!documentVariantInfo.Attributes.ContainsKey(attribute.Name.ToString()))
                                {
                                    documentVariantInfo.Attributes[attribute.Name.ToString()] = attribute.Value;
                                }
                            }

                            PopulateAttributesInExistingDocumentVariantInfo(documents, documentVariantInfo);
                        }
                    }

                    // Second, populate the document variant info attributes using the information from the documents.
                    var allCategorizerNodes = new List <XElement>();

                    foreach (var xmlDocument in xmlDocuments)
                    {
                        allCategorizerNodes.AddRange(
                            xmlDocument.Descendants(variantElement.Element(KnownXmlStrings.Name)?.Value));
                    }

                    foreach (var categorizerNode in allCategorizerNodes)
                    {
                        var documentVariantInfo = new DocumentVariantInfo
                        {
                            Title       = categorizerNode.Value,
                            Categorizer = categorizerNode.Name.ToString()
                        };

                        foreach (var attribute in categorizerNode.Attributes())
                        {
                            if (!documentVariantInfo.Attributes.ContainsKey(attribute.Name.ToString()))
                            {
                                documentVariantInfo.Attributes[attribute.Name.ToString()] = attribute.Value;
                            }
                        }

                        PopulateAttributesInExistingDocumentVariantInfo(documents, documentVariantInfo);
                    }
                }
            }
            catch (Exception ex)
            {
                generationErrors.Add(
                    new GenerationError
                {
                    Message       = ex.Message,
                    ExceptionType = ex.GetType().Name
                });
            }

            return(generationErrors);
        }