public AggregateReportInfo Deserialise(AttachmentInfo attachment, EmailMetadata emailMetadata)
        {
            using (Stream stream = attachment.GetStream())
            {
                using (StreamReader streamReader = new StreamReader(stream))
                {
                    using (XmlReader reader = XmlReader.Create(streamReader))
                    {
                        XDocument document = XDocument.Load(reader);

                        XElement feedback = document.Root;
                        if (document.Root.Name != "feedback")
                        {
                            throw new ArgumentException("Root of aggregate report must be feedback.");
                        }

                        ReportMetadata  reportMetadata  = _reportMetadataDeserialiser.Deserialise(feedback.Single("report_metadata"));
                        PolicyPublished policyPublished = _policyPublishedDeserialiser.Deserialise(feedback.Single("policy_published"));

                        IEnumerable <XElement> recordElements = feedback.Where("record").ToList();

                        if (!recordElements.Any())
                        {
                            throw new ArgumentException("Aggregate report must contain at least 1 record.");
                        }

                        Record[] records = _recordDeserialiser.Deserialise(recordElements);

                        Domain.Dmarc.AggregateReport aggregateReport = new Domain.Dmarc.AggregateReport(reportMetadata, policyPublished, records);
                        return(new AggregateReportInfo(aggregateReport, emailMetadata, attachment.AttachmentMetadata));
                    }
                }
            }
        }
        public AggregateReportInfo Deserialise(AttachmentInfo attachment, EmailMetadata emailMetadata)
        {
            attachment.AttachmentStream.Seek(0, SeekOrigin.Begin);
            using (StreamReader streamReader = new StreamReader(attachment.AttachmentStream, Encoding.UTF8, true, 1024, true))
            {
                using (XmlReader reader = XmlReader.Create(streamReader))
                {
                    XDocument document = XDocument.Load(reader);

                    XElement feedback = document.Root;
                    if (document.Root != null && document.Root.Name != "feedback")
                    {
                        throw new ArgumentException("Root of aggregate report must be feedback.");
                    }

                    XElement versionElement = feedback.SingleOrDefault("version");
                    double?  version        = double.TryParse(versionElement?.Value, out var candidateVersion)
                        ? candidateVersion
                        : (double?)null;

                    ReportMetadata  reportMetadata  = _reportMetadataDeserialiser.Deserialise(feedback.Single("report_metadata"));
                    PolicyPublished policyPublished = _policyPublishedDeserialiser.Deserialise(feedback.Single("policy_published"));

                    IEnumerable <XElement> recordElements = feedback.Where("record").ToList();

                    if (!recordElements.Any())
                    {
                        throw new ArgumentException("Aggregate report must contain at least 1 record.");
                    }

                    Record[] records = _recordDeserialiser.Deserialise(recordElements);

                    Domain.Dmarc.AggregateReport aggregateReport = new Domain.Dmarc.AggregateReport(version, reportMetadata, policyPublished, records);
                    return(new AggregateReportInfo(aggregateReport, emailMetadata, attachment));
                }
            }
        }