/// <summary>
        /// Revert the obfuscated XML document of <paramref name="value"/> to its original state by applying the mappable XML document of <paramref name="mapping"/>.
        /// </summary>
        /// <param name="value">The obfuscated <see cref="Stream"/> to revert.</param>
        /// <param name="mapping">A <see cref="Stream"/> containing mappable values necessary to revert <paramref name="value"/> to its original state.</param>
        /// <returns>
        /// A <see cref="Stream"/> object where the obfuscated XML document has been reverted to its original XML document.
        /// </returns>
        public override Stream Revert(Stream value, Stream mapping)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            MemoryStream tempOutput = null;

            try
            {
                XmlDocument document    = XmlDocumentConverter.FromStream(mapping);
                var         mappingNode = document.DocumentElement;

                XmlNode encryptedNode = mappingNode.GetElementsByTagName(MappingEncryptedElement).Item(0);
                if (encryptedNode != null)
                {
                    mappingNode.InnerXml = StringConverter.FromBytes(AdvancedEncryptionStandardUtility.Decrypt(Convert.FromBase64String(encryptedNode.InnerText), Key, InitializationVector), options =>
                    {
                        options.Encoding = Encoding;
                        options.Preamble = PreambleSequence.Remove;
                    });
                }

                tempOutput = new MemoryStream();
                using (XmlWriter writer = XmlWriter.Create(tempOutput, XmlWriterUtility.CreateSettings(o => o.Encoding = Encoding)))
                {
                    document.WriteTo(writer);
                }
                tempOutput.Position = 0;
                mapping             = tempOutput;
                tempOutput          = null;
            }
            finally
            {
                if (tempOutput != null)
                {
                    tempOutput.Dispose();
                }
            }

            return(base.Revert(value, mapping));
        }
        /// <summary>
        /// Creates and returns a mappable XML document of the original values and the obfuscated values.
        /// </summary>
        /// <returns>A mappable XML document of the original values and the obfuscated values.</returns>
        public override Stream CreateMapping()
        {
            MemoryStream output;
            MemoryStream tempOutput = null;

            try
            {
                XmlDocument document                   = XmlDocumentConverter.FromStream(base.CreateMapping());
                XmlNode     mappingNode                = document.DocumentElement;
                string      innerXmlOfMappingNode      = mappingNode.InnerXml;
                byte[]      innerXmlOfMappingNodeBytes = ByteConverter.FromString(innerXmlOfMappingNode, options =>
                {
                    options.Encoding = Encoding;
                    options.Preamble = PreambleSequence.Remove;
                });
                XmlElement encryptedNode = document.CreateElement(MappingEncryptedElement);
                encryptedNode.InnerText = Convert.ToBase64String(AdvancedEncryptionStandardUtility.Encrypt(innerXmlOfMappingNodeBytes, Key, InitializationVector));
                mappingNode.InnerXml    = "";
                mappingNode.AppendChild(encryptedNode);
                tempOutput = new MemoryStream();
                using (XmlWriter writer = XmlWriter.Create(tempOutput, XmlWriterUtility.CreateSettings(o => o.Encoding = Encoding)))
                {
                    document.WriteTo(writer);
                }
                tempOutput.Position = 0;
                output     = tempOutput;
                tempOutput = null;
            }
            finally
            {
                if (tempOutput != null)
                {
                    tempOutput.Dispose();
                }
            }
            return(output);
        }