public ComparisonUnitWord(IEnumerable <ComparisonUnitAtom> comparisonUnitAtomList)
        {
            Contents = comparisonUnitAtomList.OfType <ComparisonUnit>().ToList();
            string sha1String = Contents.Select(c => c.SHA1Hash).StringConcatenate();

            SHA1Hash = WmlComparerUtil.SHA1HashStringForUTF8String(sha1String);
        }
        private static WmlDocument HashBlockLevelContent(
            WmlDocument source,
            WmlDocument sourceAfterProc,
            WmlComparerSettings settings)
        {
            using (var msSource = new MemoryStream())
                using (var msAfterProc = new MemoryStream())
                {
                    msSource.Write(source.DocumentByteArray, 0, source.DocumentByteArray.Length);
                    msAfterProc.Write(sourceAfterProc.DocumentByteArray, 0, sourceAfterProc.DocumentByteArray.Length);

                    using (WordprocessingDocument wDocSource = WordprocessingDocument.Open(msSource, true))
                        using (WordprocessingDocument wDocAfterProc = WordprocessingDocument.Open(msAfterProc, true))
                        {
                            // create Unid dictionary for source
                            XDocument sourceMainXDoc = wDocSource.MainDocumentPart.GetXDocument();
                            XElement  sourceMainRoot = sourceMainXDoc.Root ?? throw new ArgumentException();
                            Dictionary <string, XElement> sourceUnidDict = sourceMainRoot
                                                                           .Descendants()
                                                                           .Where(d => d.Name == W.p || d.Name == W.tbl || d.Name == W.tr)
                                                                           .ToDictionary(d => (string)d.Attribute(PtOpenXml.Unid));

                            XDocument afterProcMainXDoc = wDocAfterProc.MainDocumentPart.GetXDocument();
                            XElement  afterProcMainRoot = afterProcMainXDoc.Root ?? throw new ArgumentException();
                            IEnumerable <XElement> blockLevelElements = afterProcMainRoot
                                                                        .Descendants()
                                                                        .Where(d => d.Name == W.p || d.Name == W.tbl || d.Name == W.tr);

                            foreach (XElement blockLevelContent in blockLevelElements)
                            {
                                var cloneBlockLevelContentForHashing = (XElement)CloneBlockLevelContentForHashing(
                                    wDocAfterProc.MainDocumentPart,
                                    blockLevelContent,
                                    true,
                                    settings);

                                string shaString = cloneBlockLevelContentForHashing
                                                   .ToString(SaveOptions.DisableFormatting)
                                                   .Replace(" xmlns=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"", "");

                                string sha1Hash = WmlComparerUtil.SHA1HashStringForUTF8String(shaString);
                                var    thisUnid = (string)blockLevelContent.Attribute(PtOpenXml.Unid);
                                if (thisUnid != null)
                                {
                                    if (sourceUnidDict.ContainsKey(thisUnid))
                                    {
                                        XElement correlatedBlockLevelContent = sourceUnidDict[thisUnid];
                                        correlatedBlockLevelContent.Add(new XAttribute(PtOpenXml.CorrelatedSHA1Hash, sha1Hash));
                                    }
                                }
                            }

                            wDocSource.MainDocumentPart.PutXDocument();
                        }

                    var sourceWithCorrelatedSHA1Hash = new WmlDocument(source.FileName, msSource.ToArray());
                    return(sourceWithCorrelatedSHA1Hash);
                }
        }
        public ComparisonUnitAtom(
            XElement contentElement,
            XElement[] ancestorElements,
            OpenXmlPart part,
            WmlComparerSettings settings)
        {
            ContentElement   = contentElement;
            AncestorElements = ancestorElements;
            Part             = part;
            RevTrackElement  = GetRevisionTrackingElementFromAncestors(contentElement, AncestorElements);

            if (RevTrackElement == null)
            {
                CorrelationStatus = CorrelationStatus.Equal;
            }
            else
            {
                if (RevTrackElement.Name == W.del)
                {
                    CorrelationStatus = CorrelationStatus.Deleted;
                }
                else if (RevTrackElement.Name == W.ins)
                {
                    CorrelationStatus = CorrelationStatus.Inserted;
                }
            }

            var sha1Hash = (string)contentElement.Attribute(PtOpenXml.SHA1Hash);

            if (sha1Hash != null)
            {
                SHA1Hash = sha1Hash;
            }
            else
            {
                string shaHashString = GetSha1HashStringForElement(ContentElement, settings);
                SHA1Hash = WmlComparerUtil.SHA1HashStringForUTF8String(shaHashString);
            }
        }