/// <summary>
        /// Asynchronously deserializes the given <paramref name="input"/> stream to an <see cref="AS4Message"/> model.
        /// </summary>
        /// <param name="input">The source stream from where the message should be read.</param>
        /// <param name="contentType">The content type required to correctly deserialize the message into different MIME parts.</param>
        /// <param name="cancellation">The token to control the cancellation of the deserialization.</param>
        public async Task <AS4Message> DeserializeAsync(
            Stream input,
            string contentType,
            CancellationToken cancellation = default(CancellationToken))
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if (contentType == null)
            {
                throw new ArgumentNullException(nameof(contentType));
            }

            var envelopeDocument = new XmlDocument {
                PreserveWhitespace = true
            };

            envelopeDocument.Load(input);

            // Sometimes throws 'The 'http://www.w3.org/XML/1998/namespace:lang' attribute is not declared.'
            // ValidateEnvelopeDocument(envelopeDocument);

            XmlNamespaceManager nsMgr = GetNamespaceManagerForDocument(envelopeDocument);

            SecurityHeader securityHeader  = DeserializeSecurityHeader(envelopeDocument, nsMgr);
            Messaging      messagingHeader = DeserializeMessagingHeader(envelopeDocument, nsMgr);
            Body1          body            = DeserializeBody(envelopeDocument, nsMgr);

            if (messagingHeader == null)
            {
                throw new InvalidMessageException("The envelopeStream does not contain a Messaging element");
            }

            AS4Message as4Message =
                await AS4Message.CreateAsync(
                    envelopeDocument,
                    contentType,
                    securityHeader,
                    messagingHeader,
                    body);

            StreamUtilities.MovePositionToStreamStart(input);

            return(as4Message);
        }