﻿/***************************************************************************

Copyright (c) Eric White 2016.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

Published at http://EricWhite.com
Resource Center and Documentation: http://ericwhite.com/

Developer: Eric White
Blog: http://www.ericwhite.com
Twitter: @EricWhiteDev
Email: eric@ericwhite.com

***************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
using System.Drawing;

namespace OpenXmlPowerTools
{
    public class ContentTypeRule
    {
        public string ContentType;
        public string StyleName;
        public Regex StyleNameRegex;
        public Regex[] RegexArray;
        public Func<XElement, ContentTypeRule, WordprocessingDocument, WmlToXmlSettings, bool> MatchLambda;
        public bool ApplyRunContentTypes = true;
    }

    public class GlobalValidationRule
    {
        public string[] RuleNames;
        public string[] RuleDescriptions;
        public Func<GlobalValidationRule, WordprocessingDocument, WordprocessingDocument, XElement, WmlToXmlSettings, List<WmlToXmlValidationError>> GlobalRuleLambda;
        public bool IsOnlyWarning;
        public string Message;
    }

    public class BlockLevelContentValidationRule
    {
        public string[] RuleNames;
        public string[] RuleDescriptions;
        public Regex StyleNameRegex;
        public Func<XElement, BlockLevelContentValidationRule, WordprocessingDocument, XElement, WmlToXmlSettings, List<WmlToXmlValidationError>> BlockLevelContentRuleLambda;
        public bool IsOnlyWarning;
        public string Message;
    }

    public class WmlToXmlValidationError
    {
        public string RuleName;
        public string ErrorMessage;
        public string BlockLevelContentIdentifier;  // this string is the same as the unid that is in the source document.  This string should be sufficient to identify and find any
                                                    // invalid paragraph, table, row, cell, or anything else in the source document.
                                                    // for now, i am putting an integer into this attribute / id, but I expect that this will be more elaborate than this.
                                                    // I need to again research exactly how to move to a specific paragraph or table in a document, in a VSTO app.
    }

    public class WmlToXmlProgressInfo
    {
        public int ContentCount;
        public int ContentTotal;
        public string InProgressMessage;
    }

    public class TransformInfo
    {
        public string DefaultLangFromStylesPart;
    }

    public class WmlToXmlSettings
    {
        public List<ContentTypeRule> GlobalContentTypeRules;
        public List<ContentTypeRule> DocumentTypeContentTypeRules;
        public List<ContentTypeRule> DocumentContentTypeRules;
        public List<ContentTypeRule> RunContentTypeRules;
        public List<GlobalValidationRule> GlobalValidationRules;
        public List<BlockLevelContentValidationRule> BlockLevelContentValidationRules;
        public ListItemRetrieverSettings ListItemRetrieverSettings;
        public bool? InjectCommentForContentTypes;
        public XElement ContentTypeHierarchyDefinition;
        public Func<XElement, WmlToXmlSettings, bool> ContentTypeHierarchyLambda;
        public Dictionary<string, Func<string, OpenXmlPart, XElement, WmlToXmlSettings, object>> XmlGenerationLambdas;
        public DirectoryInfo ImageBase;
        public bool WriteImageFiles = true;
        public Action<WmlToXmlProgressInfo> ProgressFunction;
        public XDocument ContentTypeRegexExtension;
        public string DefaultLang;
        public object UserData;

        public WmlToXmlSettings(
            List<ContentTypeRule> globalContentTypeRules,
            List<ContentTypeRule> documentTypeContentTypeRules,
            List<ContentTypeRule> documentContentTypeRules,
            List<ContentTypeRule> runContentTypeRules,
            List<GlobalValidationRule> globalValidationRules,
            List<BlockLevelContentValidationRule> blockLevelContentValidationRules,
            XElement contentTypeHierarchyDefinition,
            Func<XElement, WmlToXmlSettings, bool> contentTypeHierarchyLambda,
            Dictionary<string, Func<string, OpenXmlPart, XElement, WmlToXmlSettings, object>> xmlGenerationLambdas,
            DirectoryInfo imageBase,
            XDocument contentTypeRegexExtension)
        {
            GlobalContentTypeRules = globalContentTypeRules;
            DocumentTypeContentTypeRules = documentTypeContentTypeRules;
            DocumentContentTypeRules = documentContentTypeRules;
            RunContentTypeRules = runContentTypeRules;
            GlobalValidationRules = globalValidationRules;
            BlockLevelContentValidationRules = blockLevelContentValidationRules;
            ListItemRetrieverSettings = new ListItemRetrieverSettings();
            ContentTypeHierarchyDefinition = contentTypeHierarchyDefinition;
            ContentTypeHierarchyLambda = contentTypeHierarchyLambda;
            XmlGenerationLambdas = xmlGenerationLambdas;
            ImageBase = imageBase;
            ContentTypeRegexExtension = contentTypeRegexExtension;
        }

        public WmlToXmlSettings(
            List<ContentTypeRule> globalContentTypeRules,
            List<ContentTypeRule> documentTypeContentTypeRules,
            List<ContentTypeRule> documentContentTypeRules,
            List<ContentTypeRule> runContentTypeRules,
            List<GlobalValidationRule> globalValidationRules,
            List<BlockLevelContentValidationRule> blockLevelContentValidationRules,
            Func<XElement, WmlToXmlSettings, bool> contentTypeHierarchyLambda,
            Dictionary<string, Func<string, OpenXmlPart, XElement, WmlToXmlSettings, object>> xmlGenerationLambdas,
            ListItemRetrieverSettings listItemRetrieverSettings,
            DirectoryInfo imageBase,
            XDocument contentTypeRegexExtension)
        {
            GlobalContentTypeRules = globalContentTypeRules;
            DocumentTypeContentTypeRules = documentTypeContentTypeRules;
            DocumentContentTypeRules = documentContentTypeRules;
            RunContentTypeRules = runContentTypeRules;
            GlobalValidationRules = globalValidationRules;
            BlockLevelContentValidationRules = blockLevelContentValidationRules;
            ListItemRetrieverSettings = listItemRetrieverSettings;
            ContentTypeHierarchyLambda = contentTypeHierarchyLambda;
            XmlGenerationLambdas = xmlGenerationLambdas;
            ImageBase = imageBase;
            ContentTypeRegexExtension = contentTypeRegexExtension;
        }
    }

    public static class WmlToXml
    {
        public static WmlDocument ApplyContentTypes(WmlDocument document, WmlToXmlSettings settings)
        {
            using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(document))
            {
                using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
                {
                    ApplyContentTypes(doc, settings);
                }
                return streamDoc.GetModifiedWmlDocument();
            }
        }

        public static void ApplyContentTypes(WordprocessingDocument wDoc, WmlToXmlSettings settings)
        {
#if false
<Extensions>
  <Extension ContentType='Introduction'>
    <RegexExtension>
      <Regex>.*Infroduction.*</Regex>
      <Regex>.*Entroduction.*</Regex>
    </RegexExtension>
  </Extension>
</Extensions>
#endif
            if (settings.ContentTypeRegexExtension != null)
            {
                foreach (var ext in settings.ContentTypeRegexExtension.Root.Elements("Extension"))
                {
                    var ct = (string)ext.Attribute("ContentType");
                    var rules = settings.DocumentContentTypeRules.Concat(settings.DocumentTypeContentTypeRules).Concat(settings.GlobalContentTypeRules);
                    var ruleToUpdate = rules
                        .FirstOrDefault(r => r.ContentType == ct);
                    if (ruleToUpdate == null)
                        throw new OpenXmlPowerToolsException("ContentTypeRexexExtension refers to content type that does not exist");
                    var oldRegexRules = ruleToUpdate.RegexArray.ToList();
                    var newRegexRules = ext.Elements("RegexExtension").Elements("Regex").Select(z => new Regex(z.Value)).ToArray();
                    var regexArray = oldRegexRules.Concat(newRegexRules).ToArray();
                    ruleToUpdate.RegexArray = regexArray;
                }
            }

            if (settings.ProgressFunction != null)
            {
                WmlToXmlProgressInfo pi = new WmlToXmlProgressInfo()
                {
                    ContentCount = 0,
                    ContentTotal = 0,
                    InProgressMessage = "Simplify markup" + Environment.NewLine,
                };
                settings.ProgressFunction(pi);
            }

            SimplifyMarkupSettings markupSimplifierSettings = new SimplifyMarkupSettings()
            {
                AcceptRevisions = true,
                NormalizeXml = true,
                RemoveBookmarks = false,
                RemoveComments = true,
                RemoveContentControls = false,
                RemoveEndAndFootNotes = false,
                RemoveFieldCodes = false,
                RemoveGoBackBookmark = true,
                RemoveHyperlinks = false,
                RemoveLastRenderedPageBreak = true,
                RemoveMarkupForDocumentComparison = false,
                RemovePermissions = true,
                RemoveProof = true,
                RemoveRsidInfo = true,
                RemoveSmartTags = true,
                RemoveSoftHyphens = false,
                RemoveWebHidden = true,
                ReplaceTabsWithSpaces = false,
            };
            MarkupSimplifier.SimplifyMarkup(wDoc, markupSimplifierSettings);

            if (settings.ProgressFunction != null)
            {
                WmlToXmlProgressInfo pi = new WmlToXmlProgressInfo()
                {
                    ContentCount = 0,
                    ContentTotal = 0,
                    InProgressMessage = "Assemble formatting" + Environment.NewLine,
                };
                settings.ProgressFunction(pi);
            }

            FormattingAssemblerSettings formattingAssemblerSettings = new FormattingAssemblerSettings();
            formattingAssemblerSettings.RemoveStyleNamesFromParagraphAndRunProperties = false;
            formattingAssemblerSettings.RestrictToSupportedLanguages = false;
            formattingAssemblerSettings.RestrictToSupportedNumberingFormats = false;
            FormattingAssembler.AssembleFormatting(wDoc, formattingAssemblerSettings);

            ContentTypeApplierInfo ctai = new ContentTypeApplierInfo();

            XDocument sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
            XElement defaultParagraphStyle = sXDoc
                .Root
                .Elements(W.style)
                .FirstOrDefault(st => st.Attribute(W._default).ToBoolean() == true &&
                    (string)st.Attribute(W.type) == "paragraph");
            if (defaultParagraphStyle != null)
                ctai.DefaultParagraphStyleName = (string)defaultParagraphStyle.Attribute(W.styleId);
            XElement defaultCharacterStyle = sXDoc
                .Root
                .Elements(W.style)
                .FirstOrDefault(st => st.Attribute(W._default).ToBoolean() == true &&
                    (string)st.Attribute(W.type) == "character");
            if (defaultCharacterStyle != null)
                ctai.DefaultCharacterStyleName = (string)defaultCharacterStyle.Attribute(W.styleId);
            XElement defaultTableStyle = sXDoc
                .Root
                .Elements(W.style)
                .FirstOrDefault(st => st.Attribute(W._default).ToBoolean() == true &&
                    (string)st.Attribute(W.type) == "table");
            if (defaultTableStyle != null)
                ctai.DefaultTableStyleName = (string)defaultTableStyle.Attribute(W.styleId);

            if (settings.ProgressFunction != null)
            {
                WmlToXmlProgressInfo pi = new WmlToXmlProgressInfo()
                {
                    ContentCount = 0,
                    ContentTotal = 0,
                    InProgressMessage = "Assemble list item information" + Environment.NewLine,
                };
                settings.ProgressFunction(pi);
            }

            ListItemRetrieverSettings listItemRetrieverSettings = new ListItemRetrieverSettings();
            AssembleListItemInformation(wDoc, settings.ListItemRetrieverSettings);
            ApplyContentTypesForRuleSet(settings, ctai, wDoc);
        }

        public static XElement ProduceContentTypeXml(WmlDocument document, WmlToXmlSettings settings)
        {
            using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(document))
            {
                using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
                {
                    return ProduceContentTypeXml(doc, settings);
                }
            }
        }

        public static XElement ProduceContentTypeXml(WordprocessingDocument wDoc, WmlToXmlSettings settings)
        {
            var mainPart = wDoc.MainDocumentPart;
            var mainXDoc = mainPart.GetXDocument();

#if false
<w:styles xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se">
	<w:docDefaults>
		<w:rPrDefault>
			<w:rPr>
				<w:rFonts w:ascii="Georgia" w:eastAsiaTheme="minorHAnsi" w:hAnsi="Georgia" w:cs="Times New Roman"/>
				<w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/>
			</w:rPr>
		</w:rPrDefault>
		<w:pPrDefault/>
	</w:docDefaults>
#endif

            AssignLevelsToContent(mainXDoc, settings);

            // Call RetrieveListItem so that all paragraphs are initialized with ListItemInfo
            var firstParagraph = mainXDoc.Descendants(W.p).FirstOrDefault();

            // if there is no content, then return an empty document.
            if (firstParagraph == null)
                return new XElement("ContentTypeXml");

            var listItem = ListItemRetriever.RetrieveListItem(wDoc, firstParagraph);

            // Annotate runs associated with fields, so that can retrieve hyperlinks that are stored as fields.
            FieldRetriever.AnnotateWithFieldInfo(wDoc.MainDocumentPart);

            AnnotateRunsThatUseFieldsForNumbering(mainXDoc);

            var newRoot = (XElement)AnnotateRunsThatUseFldSimple(mainXDoc.Root);
            mainXDoc.Root.ReplaceWith(newRoot);

            wDoc.MainDocumentPart.PutXDocument();

            // Annotate runs associated with fields, so that can retrieve hyperlinks that are stored as fields.
            FieldRetriever.AnnotateWithFieldInfo(wDoc.MainDocumentPart);

            mainXDoc = wDoc.MainDocumentPart.GetXDocument();

            var body = mainXDoc.Root.Descendants(W.body).FirstOrDefault();
            if (body == null)
                throw new OpenXmlPowerToolsException("Internal error: invalid document");

            var contentList = body.Elements()
                .Where(e => e.Attribute(PtOpenXml.Level) != null)
                .ToList();

            var rootLevelContentList = contentList
                .Where(h => (int)h.Attribute(PtOpenXml.Level) == 1)
                .ToList();

            var contentTypeXml = new XElement("ContentTypeXml",
                rootLevelContentList
                    .Select(h =>
                    {
                        var childrenHeadings = GetChildrenHeadings(mainPart, contentList, h, settings);
                        XElement xml = (XElement)ProduceXmlTransform(mainPart, h, settings);
                        if (xml != null)
                            xml.Add(childrenHeadings);
                        return xml;
                    }));

            contentTypeXml = HierarchyPerSettings(contentTypeXml, settings);

            return contentTypeXml;
        }

        private static XElement HierarchyPerSettings(XElement contentTypeXml, WmlToXmlSettings settings)
        {
            var hierarchyDefinition = settings.ContentTypeHierarchyDefinition;
            HashSet<XName> hierarchyElements = new HashSet<XName>(hierarchyDefinition.DescendantsAndSelf().Select(d => d.Name).Distinct());

            Stack<XElement> stack = new Stack<XElement>();
            var rootElement = hierarchyDefinition
                .Elements()
                .FirstOrDefault(e => (bool)e.Attribute("IsRoot"));
            if (rootElement == null)
                throw new OpenXmlPowerToolsException("Invalid content type hierarchy definition - no root element");
            stack.Push(rootElement);

            var currentlyLookingAt = hierarchyDefinition.Element(rootElement.Name);

            foreach (var item in contentTypeXml.Elements())
            {
                if (!hierarchyElements.Contains(item.Name))
                    throw new OpenXmlPowerToolsException(string.Format("Invalid Content Type Hierarchy Definition - missing def for {0}", item.Name));

                bool found = false;
                var possibleChildItem = currentlyLookingAt.Element(item.Name);
                if (possibleChildItem != null)
                {
                    if (!possibleChildItem.HasAttributes)
                        found = true;
                    if (!found)
                    {
                        var anyMismatch = possibleChildItem.Attributes().Any(a =>
                        {
                            var val1 = a.Value;
                            var a2 = item.Attribute(a.Name);
                            if (a2 == null)
                                return true;
                            var val2 = a2.Value;
                            if (val1 != val2)
                                return true;
                            return false;
                        });
                        if (!anyMismatch)
                            found = true;
                    }
                }
                if (found)
                {
                    item.Add(new XAttribute(PtOpenXml.IndentLevel, stack.Count()));
                    stack.Push(item);
                    currentlyLookingAt = FindCurrentlyLookingAt(hierarchyDefinition, item);
                    continue;
                }
                if (hierarchyElements.Contains(item.Name))
                {
                    while (true)
                    {
                        if (stack.Count() == 1)
                        {
                            // have encountered an unexpected hierarchy element.  have gone up the stack, and no element up the stack allows for this as a child element.
                            // Therefore, put it at level one, and let the Narrdoc transform generate invalid narrdoc.
                            item.Add(new XAttribute(PtOpenXml.IndentLevel, stack.Count()));
                            break;
                        }
                        stack.Pop();
                        var last = stack.Peek();
                        currentlyLookingAt = FindCurrentlyLookingAt(hierarchyDefinition, last);
                        bool found2 = false;
                        var possibleChildItem2 = currentlyLookingAt.Element(item.Name);
                        if (possibleChildItem2 != null)
                        {
                            if (!possibleChildItem2.HasAttributes)
                                found2 = true;
                            if (!found2)
                            {
                                var anyMismatch2 = possibleChildItem2.Attributes().Any(a =>
                                {
                                    var val1 = a.Value;
                                    var a2 = item.Attribute(a.Name);
                                    if (a2 == null)
                                        return true;
                                    var val2 = a2.Value;
                                    if (val1 != val2)
                                        return true;
                                    return false;
                                });
                                if (!anyMismatch2)
                                    found2 = true;
                            }
                        }
                        if (found2)
                        {
                            item.Add(new XAttribute(PtOpenXml.IndentLevel, stack.Count()));
                            stack.Push(item);
                            currentlyLookingAt = FindCurrentlyLookingAt(hierarchyDefinition, item);
                            break;
                        }
                        if (stack.Count() == 0)
                            throw new OpenXmlPowerToolsException("Internal error = reached top of hierarchy - prob not an internal error - some other error");
                    }
                    continue;
                }
                // otherwise continue on to next item.
            }

            var hierarchicalContentTypeXml = new XElement("ContentTypeXml",
                HierarchyPerSettingsTransform(contentTypeXml.Elements(), 1));

            hierarchicalContentTypeXml.DescendantsAndSelf().Attributes(PtOpenXml.IndentLevel).Remove();

            return hierarchicalContentTypeXml;
        }

        private static XElement FindCurrentlyLookingAt(XElement hierarchyDefinition, XElement item)
        {
            var candidates = hierarchyDefinition
                .Elements(item.Name)
                .OrderByDescending(e => e.Attributes().Count());

            var theOne = candidates
                .FirstOrDefault(c =>
                {
                    if (!c.HasAttributes)
                        return true;
                    var anyMismatch2 = c.Attributes().Any(a =>
                    {
                        var val1 = a.Value;
                        var a2 = item.Attribute(a.Name);
                        if (a2 == null)
                            return true;
                        var val2 = a2.Value;
                        if (val1 != val2)
                            return true;
                        return false;
                    });
                    if (anyMismatch2)
                        return false;
                    return true;
                });

            if (theOne == null)
                throw new OpenXmlPowerToolsException("Internal error");

            return theOne;
        }

        private static object HierarchyPerSettingsTransform(IEnumerable<XElement> list, int level)
        {
            // small optimization - other code in this method would have same effect, but this is more efficient.
            if (!list.Any())
                return null;

            List<int> groupingKeys = new List<int>();
            int currentGroupingKey = 0;
            foreach (var item in list)
            {
                if (item.Attribute(PtOpenXml.IndentLevel) == null)
                    throw new OpenXmlPowerToolsException(string.Format("Invalid Content Type Hierarchy Definition - missing def for {0}", item.Name));
                if ((int)item.Attribute(PtOpenXml.IndentLevel) == level)
                {
                    currentGroupingKey += 1;
                }
                groupingKeys.Add(currentGroupingKey);
            }

            var zipped = list
                .Zip(groupingKeys, (item, key) => new
                {
                    Item = item,
                    Key = key,
                })
                .GroupBy(z => z.Key)
                .ToList();

            var newContent = zipped
                .Select(z =>
                {
                    var first = z.First().Item;
                    var newItem = new XElement(first.Name,
                        first.Attributes(),
                        first.Elements(),
                        HierarchyPerSettingsTransform(z.Skip(1).Select(r => r.Item), level + 1));
                    return newItem;
                })
                .ToList();

            return newContent;
        }


        // this is where we need to do the same type of run annotation as for complex fields, but for simple fields.
        // I think that we may need to split up the run following the simple field

#if false
<w:p pt:StyleName="Caption" pt:ContentType="Caption" pt:Level="2">
  <w:r pt:ContentType="Span">
    <w:t xml:space="preserve">Table </w:t>
  </w:r>
  <w:r>
    <w:fldChar w:fldCharType="begin" />
  </w:r>
  <w:r>
    <w:instrText xml:space="preserve"> STYLEREF 1 \s </w:instrText>
  </w:r>
  <w:r>
    <w:fldChar w:fldCharType="separate" />
  </w:r>
  <w:r pt:ContentType="Span">
    <w:t>1</w:t>
  </w:r>
  <w:r>
    <w:fldChar w:fldCharType="end" />
  </w:r>
  <w:r pt:ContentType="Span">
    <w:t>.</w:t>
  </w:r>
  <w:r>
    <w:fldChar w:fldCharType="begin" />
  </w:r>
  <w:r>
    <w:instrText xml:space="preserve"> SEQ Table \* ARABIC </w:instrText>
  </w:r>
  <w:r>
    <w:fldChar w:fldCharType="separate" />
  </w:r>
  <w:r pt:ContentType="Span">
    <w:t>1</w:t>
  </w:r>
  <w:r>
    <w:fldChar w:fldCharType="end" />
  </w:r>
  <w:r pt:ContentType="Span">
    <w:t>Type the title here</w:t>
  </w:r>
</w:p>
#endif

        private static void AnnotateRunsThatUseFieldsForNumbering(XDocument mainXDoc)
        {
            var cachedAnnotationInformation = mainXDoc.Root.Annotation<Dictionary<int, List<XElement>>>();
            if (cachedAnnotationInformation == null)
                return;

            StringBuilder sb = new StringBuilder();
            foreach (var item in cachedAnnotationInformation)
            {
                var instrText = FieldRetriever.InstrText(mainXDoc.Root, item.Key).TrimStart('{').TrimEnd('}');
                var fi = FieldRetriever.ParseField(instrText);

                if (fi.FieldType.ToUpper() == "SEQ" || fi.FieldType.ToUpper() == "STYLEREF")
                {
                    var runsForField = mainXDoc
                        .Root
                        .Descendants()
                        .Where(d =>
                        {
                            Stack<FieldRetriever.FieldElementTypeInfo> stack = d.Annotation<Stack<FieldRetriever.FieldElementTypeInfo>>();
                            if (stack == null)
                                return false;
                            if (stack.Any(stackItem => stackItem.Id == item.Key && stackItem.FieldElementType == FieldRetriever.FieldElementTypeEnum.Result))
                                return true;
                            return false;
                        })
                        .Select(d => d.AncestorsAndSelf(W.r).FirstOrDefault())
                        .Where(z9 => z9 != null)
                        .GroupAdjacent(o => o)
                        .Select(g => g.First())
                        .Where(r => r.Element(W.t) != null)
                        .ToList();

                    if (!runsForField.Any())
                        continue;

                    var lastRun = runsForField.LastOrDefault();

                    var para = lastRun
                        .Ancestors(W.p)
                        .FirstOrDefault();

                    if (para == null)
                        throw new OpenXmlPowerToolsException("Internal error - invalid document");

                    // if already processed
                    if (para.Descendants(W.r).Any(r => r.Attribute(PtOpenXml.ListItemRun) != null))
                        continue;

                    var lastFldCharRun = para
                        .Elements(W.r)
                        .LastOrDefault(r =>
                        {
                            if (r.Element(W.fldChar) == null)
                                return false;
                            Stack<FieldRetriever.FieldElementTypeInfo> stack = r.Annotation<Stack<FieldRetriever.FieldElementTypeInfo>>();
                            if (stack == null)
                                return false;

                            if (stack.Any(stackItem =>
                                {
                                    var instrText2 = FieldRetriever.InstrText(mainXDoc.Root, stackItem.Id).TrimStart('{').TrimEnd('}');
                                    var fi2 = FieldRetriever.ParseField(instrText2);
                                    if (fi2.FieldType.ToUpper() == "SEQ" || fi2.FieldType.ToUpper() == "STYLEREF")
                                        return true;
                                    return false;
                                }))
                                return true;
                            return false;
                        });

                    var elementAfter = lastFldCharRun
                        .ElementsAfterSelf(W.r)
                        .FirstOrDefault();

                    // elementAfter may be null - that is ok - the rest of the routine works properly in this case.

                    var listItemText = para
                        .Elements(W.r)
                        .TakeWhile(e => e != elementAfter)
                        .Select(r1 => r1.Descendants(W.t).Select(t => (string)t).StringConcatenate())
                        .StringConcatenate()
                        .Trim();

                    var nextRun = lastFldCharRun
                        .ElementsAfterSelf(W.r)
                        .FirstOrDefault(nr => nr.Element(W.t) != null);

                    var lastFldCharRunText = lastFldCharRun
                        .ElementsBeforeSelf(W.r)
                        .Reverse()
                        .First(r => r.Element(W.t) != null)
                        .Element(W.t);

                    string sepCharsString = "";
                    if (nextRun != null)
                    {
                        var nextRunTextElement = nextRun
                            .Element(W.t);

                        var nextRunText = nextRunTextElement.Value;
                        var sepChars = nextRunText
                            .TakeWhile(ch => ch == '.' || ch == ' ')
                            .ToList();

                        sepCharsString = nextRunText.Substring(0, sepChars.Count());

                        nextRunText = nextRunText.Substring(sepChars.Count());
                        nextRunTextElement.Value = nextRunText;

                        lastFldCharRunText.Value = lastFldCharRunText.Value + sepCharsString;
                    }

                    Regex re = new Regex("[A-F0-9.]+$");
                    Match m = re.Match(listItemText);
                    string matchedValue = null;
                    if (m.Success)
                    {
                        matchedValue = m.Value;
                    }

                    if (matchedValue != null)
                    {
                        matchedValue += sepCharsString;
                        matchedValue = matchedValue.TrimStart('.');
                        matchedValue = matchedValue.TrimEnd('.', ' ');

                        foreach (var run in para.Elements(W.r).TakeWhile(e => e != elementAfter).Where(e => e.Element(W.t) != null))
                            run.Add(new XAttribute(PtOpenXml.ListItemRun, matchedValue));
                    }

                }

#if false
                // old code
                if (fi.FieldType.ToUpper() == "SEQ")
                {
                    // have it

                    var runsForField = mainXDoc
                        .Root
                        .Descendants()
                        .Where(d =>
                        {
                            Stack<FieldRetriever.FieldElementTypeInfo> stack = d.Annotation<Stack<FieldRetriever.FieldElementTypeInfo>>();
                            if (stack == null)
                                return false;
                            if (stack.Any(stackItem => stackItem.Id == item.Key && stackItem.FieldElementType == FieldRetriever.FieldElementTypeEnum.Result))
                                return true;
                            return false;
                        })
                        .Select(d => d.AncestorsAndSelf(W.r).FirstOrDefault())
                        .Where(z9 => z9 != null)
                        .GroupAdjacent(o => o)
                        .Select(g => g.First())
                        .Where(r => r.Element(W.t) != null)
                        .ToList();

                    if (!runsForField.Any())
                        continue;

                    var lastRun = runsForField
                        .Last();

                    var lastRunTextElement = lastRun
                        .Element(W.t);

                    var lastRunText = lastRunTextElement.Value;
                    
                    var nextRun = lastRun
                        .ElementsAfterSelf(W.r)
                        .FirstOrDefault(r => r.Element(W.t) != null);

                    if (nextRun != null)
                    {
                        var nextRunTextElement = nextRun
                            .Element(W.t);

                        var nextRunText = nextRunTextElement.Value;
                        var sepChars = nextRunText
                            .TakeWhile(ch => ch == '.' || ch == ' ')
                            .ToList();

                        nextRunText = nextRunText.Substring(sepChars.Count());
                        nextRunTextElement.Value = nextRunText;

                        lastRunText = lastRunTextElement.Value + sepChars.Select(ch => ch.ToString()).StringConcatenate();
                        lastRunTextElement.Value = lastRunText;
                    }

                    lastRun.Add(new XAttribute(PtOpenXml.ListItemRun, lastRunText));

                    foreach (var runbefore in lastRun
                        .ElementsBeforeSelf(W.r)
                        .Where(rz => rz.Element(W.t) != null))
                    {
                        runbefore.Add(new XAttribute(PtOpenXml.ListItemRun, lastRunText));
                    }
                }
#endif

            }
            }

#if false
<w:p pt14:StyleName="Caption">
  <w:r>
    <w:t xml:space="preserve">Box </w:t>
  </w:r>
  <w:fldSimple w:instr=" SEQ Box \* ARABIC ">
    <w:r>
      <w:t>1</w:t>
    </w:r>
  </w:fldSimple>
  <w:r>
    <w:t>. Type the title here</w:t>
  </w:r>
</w:p>
#endif
        private static object AnnotateRunsThatUseFldSimple(XNode node)
        {
            var element = node as XElement;
            if (element != null)
            {
                if (element.Name == W.p &&
                    element.Elements(W.fldSimple).Any(fs =>
                    {
                        var instrText = ((string)fs.Attribute(W.instr)).Trim();
                        return instrText.StartsWith("SEQ");
                    }))
                {
                    var fldSimple = element.Elements(W.fldSimple).FirstOrDefault(fs =>
                    {
                        var instrText = ((string)fs.Attribute(W.instr)).Trim();
                        return instrText.StartsWith("SEQ");
                    });
                    var instr = ((string)fldSimple.Attribute(W.instr)).Trim();

                    // we have to do some funny business here because Word puts the ". " as part of the text following the fldSimple, and we want that text to be part of the list item.
                    var runAfter = fldSimple.ElementsAfterSelf(W.r).FirstOrDefault();
                    var runAfterText = runAfter.Elements(W.t).Select(t => (string)t).StringConcatenate();
                    var runAfterTextTrimmed = runAfterText.TrimStart('.', ' ');
                    var listItemNum = fldSimple.Elements(W.r).Elements(W.t).Select(t => (string)t).StringConcatenate();
                    var runsBefore = element
                        .Elements()
                        .TakeWhile(fs => fs.Name != W.fldSimple || (fs.Name == W.fldSimple && !((string)fs.Attribute(W.instr)).Trim().StartsWith("SEQ")))
                        .Select(e =>
                        {
#if false
<w:r pt14:StyleName="DefaultParagraphFont" pt14:FontName="Calibri" pt14:LanguageType="western" pt14:ListItemRun="3" xmlns:pt14="http://powertools.codeplex.com/2011" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  <w:rPr>
    <w:rFonts w:asciiTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:eastAsiaTheme="minorHAnsi" w:cstheme="minorBidi" w:ascii="Calibri" w:hAnsi="Calibri" w:eastAsia="Calibri" w:cs="" />
    <w:bCs />
    <w:sz w:val="22" />
    <w:szCs w:val="22" />
    <w:lang w:bidi="ar-SA" w:eastAsia="en-US" w:val="en-US" />
  </w:rPr>
  <w:t>3.</w:t>
</w:r>
#endif
                            var newE = new XElement(e); // clone
                            if (e.Value != "" && e.Attribute(PtOpenXml.ListItemRun) == null)
                                newE.Add(new XAttribute(PtOpenXml.ListItemRun, listItemNum));
                            return newE;
                        })
                        .ToList();
                    var fldSimpleRuns = fldSimple.Elements().Select(e =>
                        {
                            var newE = new XElement(e.Name,
                                e.Attributes(),
                                new XAttribute(PtOpenXml.ListItemRun, listItemNum),
                                e.Elements());
                            return newE;
                        });
                    var runAfterTextTrimmedLength = runAfterText.Length - runAfterTextTrimmed.Length;
                    XElement runAfterListItemElement = null;
                    if (runAfterTextTrimmedLength != 0)
                    {
                        runAfterListItemElement = new XElement(W.r,
                            runAfter.Attributes(),
                            new XAttribute(PtOpenXml.ListItemRun, listItemNum),
                            runAfter.Elements(W.rPr),
                            new XElement(W.t, runAfterText.Substring(0, runAfterTextTrimmedLength)));
                    }
                    XElement runAfterRemainderElement = new XElement(W.r,
                        runAfter.Attributes(),
                        runAfter.Elements(W.rPr),
                        new XElement(W.t, runAfterText.Substring(runAfterTextTrimmedLength)));
                    var newPara = new XElement(W.p,
                        element.Attributes(),
                        runsBefore,
                        fldSimpleRuns,
                        runAfterListItemElement,
                        runAfterRemainderElement,
                        fldSimple.ElementsAfterSelf(W.r).Skip(1));
                    return newPara;
                }

                return new XElement(element.Name,
                    element.Attributes(),
                    element.Nodes().Select(n => AnnotateRunsThatUseFldSimple(n)));
            }
            return node;
        }

        // this method produces the XML for an endnote or footnote - the blockLevelContentContainer is the w:endnote or w:footnote element, and it produces the content type XML for the
        // contents of the endnote or footnote, to be inserted en situ in the ContentTypeXml.
        public static object ProduceContentTypeXmlForBlockLevelContentContainer(WordprocessingDocument wDoc, WmlToXmlSettings settings, OpenXmlPart part, XElement blockLevelContentContainer)
        {
            AssignLevelsToContentForEndFootNote(blockLevelContentContainer, settings);

            // Call RetrieveListItem so that all paragraphs are initialized with ListItemInfo
            var firstParagraph = blockLevelContentContainer.Descendants(W.p).FirstOrDefault();
            var listItem = ListItemRetriever.RetrieveListItem(wDoc, firstParagraph);

            var contentList = blockLevelContentContainer.Elements()
                .Where(e => e.Attribute(PtOpenXml.Level) != null)
                .ToList();

            var rootLevelContentList = contentList
                .Where(h => (int)h.Attribute(PtOpenXml.Level) == 1)
                .ToList();

            var contentTypeXml = rootLevelContentList
                    .Select(h =>
                    {
                        var childrenHeadings = GetChildrenHeadings(part, contentList, h, settings);
                        XElement xml = (XElement)ProduceXmlTransform(part, h, settings);
                        if (xml != null)
                            xml.Add(childrenHeadings);
                        return xml;
                    });

            return contentTypeXml;
        }


        private static object GetChildrenHeadings(OpenXmlPart part, List<XElement> contentList, XElement parent, WmlToXmlSettings settings)
        {
            return contentList
                    .SkipWhile(h => h != parent)
                    .Skip(1)
                    .TakeWhile(h => (int)h.Attribute(PtOpenXml.Level) > (int)parent.Attribute(PtOpenXml.Level))
                    .Where(h => (int)h.Attribute(PtOpenXml.Level) == (int)parent.Attribute(PtOpenXml.Level) + 1)
                    .Select(h =>
                    {
                        var childrenHeadings = GetChildrenHeadings(part, contentList, h, settings);
                        XElement xml = (XElement)ProduceXmlTransform(part, h, settings);
                        if (xml != null)
                            xml.Add(childrenHeadings);
                        return xml;
                    }
                    );
        }

        public static object ProduceXmlTransform(OpenXmlPart part, XNode node, WmlToXmlSettings settings)
        {
            var element = node as XElement;
            if (element != null)
            {
                if (settings.XmlGenerationLambdas == null)
                    throw new ArgumentOutOfRangeException("Xml Generation Lambdas are required");

                var contentType = (string)element.Attribute(PtOpenXml.ContentType);

                if (element.Name == W.t || element.Name == W.fldSimple)
                    return element.Nodes().Select(z => ProduceXmlTransform(part, z, settings));

                if (contentType == null && element.Name == W.r)
                {
                    if (settings.XmlGenerationLambdas.ContainsKey("Run"))
                    {
                        var lamda = settings.XmlGenerationLambdas["Run"];
                        var newElement = lamda(contentType, part, element, settings);
                        return newElement;
                    }
                    else
                    {
                        throw new OpenXmlPowerToolsException("Entry for Run content type in XML generation lambdas is required");
                    }
                }

                if (element.Name == W.hyperlink)
                {
                    if (settings.XmlGenerationLambdas.ContainsKey("Hyperlink"))
                    {
                        var lamda = settings.XmlGenerationLambdas["Hyperlink"];
                        var newElement = lamda(contentType, part, element, settings);
                        return newElement;
                    }
                    else
                    {
                        throw new OpenXmlPowerToolsException("Entry for Hyperlink content type in XML generation lambdas is required");
                    }
                }

                if (contentType != null)
                {

                    if (settings.XmlGenerationLambdas != null)
                    {
                        if (settings.XmlGenerationLambdas.ContainsKey(contentType))
                        {
                            var lamda = settings.XmlGenerationLambdas[contentType];
                            var newElement = lamda(contentType, part, element, settings);

                            string lang = (string)element.Elements(W.pPr).Elements(W.rPr).Elements(W.lang).Attributes(W.val).FirstOrDefault();
                            if (lang == null)
                                lang = settings.DefaultLang;
                            if (lang != null && ! lang.StartsWith("en"))  // TODO we are not generating lang if English, but this needs revised after analysis
                            {
                                var n = newElement as XElement;
                                if (n != null)
                                {
                                    n.Add(new XAttribute("Lang", lang));
                                    if (element.Attribute(PtOpenXml.Unid) != null)
                                        n.Add(new XAttribute("Unid", element.Attribute(PtOpenXml.Unid).Value));
                                    return n;
                                }
                            }

                            var n2 = newElement as XElement;
                            if (n2 != null && element.Attribute(PtOpenXml.Unid) != null)
                            {
                                n2.Add(new XAttribute("Unid", element.Attribute(PtOpenXml.Unid).Value));
                                return n2;
                            }

                            return newElement;
                        }

                    }

                    // if no generation rules are set, or if there is no rule for this content type, then
                    // generate the default, for now.

                    // todo this is not ideal in my mind.  Need to think about this more.  Maybe every content type
                    // must have a generation lambda.

                    return new XElement(contentType, new XElement("Content",
                        element.Elements().Select(rce => ProduceXmlTransform(part, rce, settings))));
                }

                // ignore any other elements
                return null;
            }

#if false
            // The following code inserts an XML comment for unicode characters above 256

            // This could be made more efficient - group characters together and create fewer XText nodes.
            // As it is, it is pretty slow, so should be used only for debugging.

            var xt = node as XText;
            if (xt != null)
            {
                var newContent = xt.Value.Select(c =>
                {
                    var ic = (int)c;
                    if (ic < 256)
                        return (object)new XText(c.ToString());

                    return new[] {
                        (object)new XText(c.ToString()),
                        new XComment(ic.ToString("X")),
                    };
                })
                .ToList();
                return newContent;
            }
#endif

            return node;
        }

        private static void AssignLevelsToContent(XDocument mainXDoc, WmlToXmlSettings settings)
        {
            var contentWithContentType = mainXDoc
                .Root
                .Descendants()
                .Where(d => d.Name == W.p || d.Name == W.tbl || d.Name == W.tr || d.Name == W.tc)
                .Where(d => d.Attribute(PtOpenXml.ContentType) != null)
                .ToList();

            int currentLevel = 1;
            foreach (var content in contentWithContentType)
            {
                var thisLevel = GetIndentLevel(content, settings);
                if (thisLevel == null)
                {
                    content.Add(new XAttribute(PtOpenXml.Level, currentLevel));
                }
                else
                {
                    if (content.Attribute(PtOpenXml.Level) == null)
                        content.Add(new XAttribute(PtOpenXml.Level, thisLevel));
                    currentLevel = (int)thisLevel + 1;
                }
            }
        }

        private static void AssignLevelsToContentForEndFootNote(XElement blockLevelContentContainer, WmlToXmlSettings settings)
        {
            var contentWithContentType = blockLevelContentContainer
                .Descendants()
                .Where(d => d.Name == W.p || d.Name == W.tbl || d.Name == W.tr || d.Name == W.tc)
                .Where(d => d.Attribute(PtOpenXml.ContentType) != null)
                .ToList();

            foreach (var content in contentWithContentType)
                content.Add(new XAttribute(PtOpenXml.Level, 1));
        }

        private static int? GetIndentLevel(XElement blockLevelContent, WmlToXmlSettings settings)
        {
            if (settings.ContentTypeHierarchyLambda(blockLevelContent, settings))
                return 1;
            return 2;
        }

        // Apply the Document rules first, then apply the DocumentType rules, then apply the Global rules.  First one that matches, wins.
        private static void ApplyContentTypesForRuleSet(WmlToXmlSettings settings, ContentTypeApplierInfo ctai, WordprocessingDocument wDoc)
        {
            ApplyRulesToPart(settings, ctai, wDoc, wDoc.MainDocumentPart);
            if (wDoc.MainDocumentPart.EndnotesPart != null)
                ApplyRulesToPart(settings, ctai, wDoc, wDoc.MainDocumentPart.EndnotesPart);
            if (wDoc.MainDocumentPart.FootnotesPart != null)
                ApplyRulesToPart(settings, ctai, wDoc, wDoc.MainDocumentPart.FootnotesPart);
        }

        private static void ApplyRulesToPart(WmlToXmlSettings settings, ContentTypeApplierInfo ctai, WordprocessingDocument wDoc, OpenXmlPart part)
        {
            var partXDoc = part.GetXDocument();
            var styleXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
            var blockContent = partXDoc.Descendants()
                .Where(d => d.Name == W.p || d.Name == W.tbl || d.Name == W.tr || d.Name == W.tc);

            int totalCount = 0;
            if (settings.ProgressFunction != null)
            {
                totalCount = blockContent.Count();
                string message;
                if (part is MainDocumentPart)
                    message = "Apply rules to main document part";
                else if (part is EndnotesPart)
                    message = "Apply rules to endnotes part";
                else
                    message = "Apply rules to footnotes part";
                WmlToXmlProgressInfo pi = new WmlToXmlProgressInfo()
                {
                    ContentTotal = totalCount,
                    ContentCount = 0,
                    InProgressMessage = message + Environment.NewLine,
                };
                settings.ProgressFunction(pi);
            }

            var count = 0;
            foreach (var blc in blockContent)
            {
                if (settings.ProgressFunction != null)
                {
                    ++count;
                    if (count < 50 || (count) % 10 == 0 || count == totalCount)
                    {
                        var msg = string.Format("  {0} of {1}", count, totalCount);
                        msg += "".PadRight(msg.Length, '\b');
                        WmlToXmlProgressInfo pi2 = new WmlToXmlProgressInfo()
                        {
                            ContentTotal = totalCount,
                            ContentCount = count,
                            InProgressMessage = msg,
                        };
                        settings.ProgressFunction(pi2);
                    }
                }

                string styleOfBlc = null;
                string styleOfBlcUC = null;
                if (blc.Name == W.p)
                {
                    var styleIdOfBlc = (string)blc.Elements(W.pPr).Elements(W.pStyle).Attributes(W.val).FirstOrDefault();
                    if (styleIdOfBlc != null)
                    {
                        styleOfBlc = (string)styleXDoc
                            .Root
                            .Elements(W.style)
                            .Where(s => (string)s.Attribute(W.styleId) == styleIdOfBlc && (string)s.Attribute(W.type) == "paragraph")
                            .Elements(W.name)
                            .Attributes(W.val)
                            .FirstOrDefault();
                    }
                    if (styleOfBlc == null)
                        styleOfBlc = ctai.DefaultParagraphStyleName;
                    styleOfBlcUC = styleOfBlc.ToUpper();
                }
                else if (blc.Name == W.tbl)
                {
                    var styleIdOfBlc = (string)blc.Elements(W.tblPr).Elements(W.tblStyle).Attributes(W.val).FirstOrDefault();
                    if (styleIdOfBlc != null)
                    {
                        styleOfBlc = (string)styleXDoc
                            .Root
                            .Elements(W.style)
                            .Where(s => (string)s.Attribute(W.styleId) == styleIdOfBlc && (string)s.Attribute(W.type) == "table")
                            .Elements(W.name)
                            .Attributes(W.val)
                            .FirstOrDefault();
                    }
                    if (styleOfBlc == null)
                        styleOfBlc = ctai.DefaultTableStyleName;
                    styleOfBlcUC = styleOfBlc.ToUpper();
                }

                ///////////////////////////////////////////////////////////////////////////////////////////
                // The following is useful to get a list of all content types and the code gen list

                //var contentTypeList = settings
                //    .DocumentContentTypeRules
                //    .Concat(settings.DocumentTypeContentTypeRules)
                //    .Concat(settings.GlobalContentTypeRules)
                //    .Select(ct => ct.ContentType)
                //    .Distinct()
                //    .OrderBy(n => n)
                //    .ToList();

                //var contentTypeCodeGenList = settings
                //    .XmlGenerationLambdas
                //    .Select(xgl => xgl.Key)
                //    .OrderBy(n => n)
                //    .ToList();

                //var rulesWithoutGenCode = contentTypeList
                //    .Except(contentTypeCodeGenList)
                //    .ToList();

                //var codeGenWithoutRules = contentTypeCodeGenList
                //    .Except(contentTypeList)
                //    .ToList();

                //var s10 = codeGenWithoutRules.Select(m => m + Environment.NewLine).StringConcatenate();
                //Console.WriteLine(s10);

                //var s9 = contentTypeList.Select(m => m + Environment.NewLine).StringConcatenate();
                //Console.WriteLine(s9);

                // Apply the Document rules first, then apply the DocumentType rules, then apply the Global rules.  First one that matches, wins.
                foreach (var rule in settings.DocumentContentTypeRules.Concat(settings.DocumentTypeContentTypeRules).Concat(settings.GlobalContentTypeRules))
                {
                    bool stylePass = false;
                    bool styleRegexPass = false;
                    bool regexPass = false;
                    bool matchLambdaPass = false;

                    stylePass = rule.StyleName == null || rule.StyleName.ToUpper() == styleOfBlcUC;

                    if (stylePass)
                    {
                        styleRegexPass = rule.StyleNameRegex == null;
                        if (rule.StyleNameRegex != null && styleOfBlc != null)
                            styleRegexPass = rule.StyleNameRegex.IsMatch(styleOfBlc);
                    }

                    if (stylePass && styleRegexPass)
                    {
                        regexPass = rule.RegexArray == null;
                        if (rule.RegexArray != null)
                        {
                            for (int i = 0; i < rule.RegexArray.Length; i++)
                            {
                                // clone the blc because OpenXmlRegex.Match replaces content, mucks with the run, probably should not if it only is used to find content.
                                var clonedBlc = new XElement(blc);

                                // following removes the subtitle created by a soft break, so that the pattern matches appropriately.
                                clonedBlc = RemoveContentAfterBR(clonedBlc);

#if false
<p p1:FontName="Georgia" p1:LanguageType="western" p1:AbstractNumId="28" xmlns:p1="http://powertools.codeplex.com/2011" xmlns="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  <r p1:ListItemRun="1.1" p1:FontName="Georgia" p1:LanguageType="western">
    <t xml:space="preserve">1.1</t>
  </r>
#endif
                                // remove list item runs so that they are not matched in the content
                                clonedBlc.Elements(W.r).Where(r => r.Attribute(PtOpenXml.ListItemRun) != null).Remove();

                                if (OpenXmlRegex.Match(new[] { clonedBlc }, rule.RegexArray[i]) != 0)
                                {
                                    regexPass = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (stylePass && styleRegexPass && regexPass)
                    {
                        matchLambdaPass = rule.MatchLambda == null;
                        if (rule.MatchLambda != null)
                        {
                            if (rule.MatchLambda(blc, rule, wDoc, settings))
                                matchLambdaPass = true;
                        }
                    }

                    if (stylePass && styleRegexPass && regexPass && matchLambdaPass)
                    {
                        AddContentTypeToBlockContent(settings, part, blc, rule.ContentType);
                        if (rule.ApplyRunContentTypes)
                            ApplyRunContentTypes(settings, ctai, wDoc, blc, settings.RunContentTypeRules, part, partXDoc);
                        break;
                    }
                }
            }

            if (settings.ProgressFunction != null)
            {
                WmlToXmlProgressInfo pi = new WmlToXmlProgressInfo()
                {
                    ContentTotal = totalCount,
                    ContentCount = totalCount,
                    InProgressMessage = Environment.NewLine + "  Done" + Environment.NewLine,
                };
                settings.ProgressFunction(pi);
            }

            part.PutXDocument();
            var mainPart = part as MainDocumentPart;
            if (mainPart != null)
            {
                if (mainPart.WordprocessingCommentsPart != null)
                    mainPart.WordprocessingCommentsPart.PutXDocument();
            }
        }

        private static XElement RemoveContentAfterBR(XElement clonedBlc)
        {
            if (clonedBlc.Name != W.p)
                return clonedBlc;
            var cloned2 = new XElement(clonedBlc.Name,
                clonedBlc.Attributes(),
                clonedBlc.Elements().TakeWhile(r => r.Element(W.br) == null));
            return cloned2;
        }

        private static void ApplyRunContentTypes(WmlToXmlSettings settings, ContentTypeApplierInfo ctai, WordprocessingDocument wDoc,
            XElement blockLevelContent, List<ContentTypeRule> runContentTypeRuleList, OpenXmlPart part, XDocument mainXDoc)
        {
            var runContent = blockLevelContent.Descendants()
                .Where(d => d.Name == W.r || d.Name == W.hyperlink || d.Name == W.sdt || d.Name == W.bookmarkStart);
            foreach (var rlc in runContent)
            {
                if (rlc.Name == W.r || rlc.Name == W.sdt)
                {
                    var runStyle = (string)rlc.Elements(W.rPr).Elements(W.rStyle).Attributes(W.val).FirstOrDefault();
                    if (runStyle == null)
                        runStyle = ctai.DefaultCharacterStyleName;
                    foreach (var rule in runContentTypeRuleList)
                    {
                        if (rule.StyleName != null && rule.StyleName != runStyle)
                            continue;

                        if (rule.RegexArray != null)
                            throw new OpenXmlPowerToolsException("Invalid Run ContentType Rule - Regex not allowed");
                        if (rule.MatchLambda != null)
                        {
                            if (rule.MatchLambda(rlc, rule, wDoc, settings))
                            {
                                AddContentTypeToRunContent(settings, part, rlc, rule.ContentType);
                                break;
                            }
                            continue;
                        }
                        AddContentTypeToRunContent(settings, part, rlc, rule.ContentType);
                        break;
                    }
                }
                else if (rlc.Name == W.hyperlink)
                {
                    foreach (var run in rlc.Descendants(W.r))
                        AddContentTypeToRunContent(settings, part, run, "Hyperlink");
                }
                else if (rlc.Name == W.bookmarkStart)
                {
                    AddContentTypeToRunContent(settings, part, rlc, "Anchor");
                }
            }
        }

        private static XAttribute[] NamespaceAttributes =
        {
            new XAttribute(XNamespace.Xmlns + "wpc", WPC.wpc),
            new XAttribute(XNamespace.Xmlns + "mc", MC.mc),
            new XAttribute(XNamespace.Xmlns + "o", O.o),
            new XAttribute(XNamespace.Xmlns + "r", R.r),
            new XAttribute(XNamespace.Xmlns + "m", M.m),
            new XAttribute(XNamespace.Xmlns + "v", VML.vml),
            new XAttribute(XNamespace.Xmlns + "wp14", WP14.wp14),
            new XAttribute(XNamespace.Xmlns + "wp", WP.wp),
            new XAttribute(XNamespace.Xmlns + "w10", W10.w10),
            new XAttribute(XNamespace.Xmlns + "w", W.w),
            new XAttribute(XNamespace.Xmlns + "w14", W14.w14),
            new XAttribute(XNamespace.Xmlns + "w15", W15.w15),
            new XAttribute(XNamespace.Xmlns + "w16se", W16SE.w16se),
            new XAttribute(XNamespace.Xmlns + "wpg", WPG.wpg),
            new XAttribute(XNamespace.Xmlns + "wpi", WPI.wpi),
            new XAttribute(XNamespace.Xmlns + "wne", WNE.wne),
            new XAttribute(XNamespace.Xmlns + "wps", WPS.wps),
            new XAttribute(XNamespace.Xmlns + "pt", PtOpenXml.pt),
            new XAttribute(MC.Ignorable, "w14 wp14 w15 w16se pt"),
        };

        private static void AddContentTypeToBlockContent(WmlToXmlSettings settings, OpenXmlPart part, XElement blc, string contentType)
        {
            // add the attribute to the block content
            blc.Add(new XAttribute(PtOpenXml.ContentType, contentType));

            var mainPart = part as MainDocumentPart;
            if (mainPart != null)
            {
                // add a comment, if appropriate
                int commentNumber = 1;
                XDocument newComments = null;
                if (settings.InjectCommentForContentTypes != null && (bool)settings.InjectCommentForContentTypes)
                {
                    if (mainPart.WordprocessingCommentsPart != null)
                    {
                        newComments = mainPart.WordprocessingCommentsPart.GetXDocument();
                        newComments.Declaration.Standalone = "yes";
                        newComments.Declaration.Encoding = "UTF-8";
                        var ids = newComments.Root.Elements(W.comment).Select(f => (int)f.Attribute(W.id));
                        if (ids.Any())
                            commentNumber = ids.Max() + 1;
                    }
                    else
                    {
                        part.AddNewPart<WordprocessingCommentsPart>();
                        newComments = mainPart.WordprocessingCommentsPart.GetXDocument();
                        newComments.Declaration.Standalone = "yes";
                        newComments.Declaration.Encoding = "UTF-8";
                        newComments.Add(new XElement(W.comments, NamespaceAttributes));
                        commentNumber = 1;
                    }
#if false
  <w:comment w:id="12"
             w:author="Eric White"
             w:date="2016-03-20T18:50:00Z"
             w:initials="EW">
    <w:p w14:paraId="7E227B98"
         w14:textId="6FA2BE6B"
         w:rsidR="00425889"
         w:rsidRDefault="00425889">
      <w:pPr>
        <w:pStyle w:val="CommentText"/>
      </w:pPr>
      <w:r>
        <w:rPr>
          <w:rStyle w:val="CommentReference"/>
        </w:rPr>
        <w:annotationRef/>
      </w:r>
      <w:r>
        <w:t>Nil</w:t>
      </w:r>
    </w:p>
  </w:comment>
#endif
                    XElement newElement = new XElement(W.comment,
                        new XAttribute(W.id, commentNumber),
                        new XElement(W.p,
                            new XElement(W.pPr,
                                new XElement(W.pStyle,
                                    new XAttribute(W.val, "CommentText"))),
                            new XElement(W.r,
                                new XElement(W.rPr,
                                    new XElement(W.rStyle,
                                        new XAttribute(W.val, "CommentReference"))),
                                        new XElement(W.annotationRef)),
                            new XElement(W.r,
                                new XElement(W.t,
                                    new XText(contentType)))));
                    newComments.Root.Add(newElement);

#if false
      <w:r>
        <w:rPr>
          <w:rStyle w:val="CommentReference"/>
        </w:rPr>
        <w:commentReference w:id="12"/>
      </w:r>
#endif

                    XElement commentRun = new XElement(W.r,
                        new XElement(W.rPr,
                            new XElement(W.rStyle, new XAttribute(W.val, "CommentReference"))),
                        new XElement(W.commentReference,
                            new XAttribute(W.id, commentNumber)));
                    var firstRunInParagraph = blc
                        .DescendantsTrimmed(W.txbxContent)
                        .Where(r => r.Name == W.r)
                        .FirstOrDefault();
                    if (firstRunInParagraph != null)
                    {
                        // for now, only do the work of inserting a comment if it is easy.  For content types for tables, rows and cells, not inserting a comment.
                        if (firstRunInParagraph.Parent.Name == W.p)
                            firstRunInParagraph.AddBeforeSelf(commentRun);
                    }
                    else
                    {
                        // for now, only do the work of inserting a comment if it is easy.  For content types for tables, rows and cells, not inserting a comment.
                        if (blc.Name == W.p)
                            blc.Add(commentRun);
                    }

                    if (mainPart.StyleDefinitionsPart == null)
                    {
                        throw new ContentApplierException("Document does not have styles definition part");
                    }
                    XDocument stylesXDoc = mainPart.StyleDefinitionsPart.GetXDocument();

                    var style =
@"<w:style w:type=""paragraph""
           w:styleId=""CommentText""
           xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:name w:val=""annotation text""/>
    <w:basedOn w:val=""Normal""/>
    <w:link w:val=""CommentTextChar""/>
    <w:semiHidden/>
    <w:rPr>
      <w:sz w:val=""20""/>
      <w:szCs w:val=""20""/>
    </w:rPr>
  </w:style>
";
                    AddIfMissing(stylesXDoc, style);
                    style =
@"<w:style w:type=""paragraph""
           w:styleId=""CommentSubject""
           xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:name w:val=""annotation subject""/>
    <w:basedOn w:val=""CommentText""/>
    <w:next w:val=""CommentText""/>
    <w:semiHidden/>
    <w:rPr>
      <w:b/>
      <w:bCs/>
    </w:rPr>
  </w:style>
";
                    AddIfMissing(stylesXDoc, style);
                    style =
@"<w:style w:type=""character""
           w:styleId=""CommentReference""
           xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:name w:val=""annotation reference""/>
    <w:basedOn w:val=""DefaultParagraphFont""/>
    <w:uiPriority w:val=""99""/>
    <w:semiHidden/>
    <w:unhideWhenUsed/>
    <w:rsid w:val=""00872729""/>
    <w:rPr>
      <w:sz w:val=""16""/>
      <w:szCs w:val=""16""/>
    </w:rPr>
  </w:style>
";
                    AddIfMissing(stylesXDoc, style);
                    style =
@"<w:style w:type=""character""
           w:customStyle=""1""
           w:styleId=""CommentTextChar""
           xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:name w:val=""Comment Text Char""/>
    <w:basedOn w:val=""DefaultParagraphFont""/>
    <w:link w:val=""CommentText""/>
    <w:semiHidden/>
    <w:rsid w:val=""00A43CEC""/>
    <w:rPr>
      <w:lang w:val=""en-GB""
              w:eastAsia=""zh-CN""/>
    </w:rPr>
  </w:style>
";
                    AddIfMissing(stylesXDoc, style);
                    mainPart.StyleDefinitionsPart.PutXDocument();
                }
            }

            var root = blc.Ancestors().LastOrDefault();
            if (root == null)
                throw new ContentApplierException("Internal error");
            var ptNamespace = root.Attribute(XNamespace.Xmlns + "pt");
            if (ptNamespace == null)
            {
                root.Add(new XAttribute(XNamespace.Xmlns + "pt", PtOpenXml.pt.NamespaceName));
            }
            var ignorable = (string)root.Attribute(MC.Ignorable);
            if (ignorable != null)
            {
                var list = ignorable.Split(' ');
                if (!list.Contains("pt"))
                {
                    ignorable += " pt";
                    root.Attribute(MC.Ignorable).Value = ignorable;
                }
            }
            else
            {
                root.Add(new XAttribute(MC.Ignorable, "pt"));
            }
        }

        private static void AddContentTypeToRunContent(WmlToXmlSettings settings, OpenXmlPart part, XElement rlc, string contentType)
        {
            // if there is already a content type for this run level content, then nothing to do.  First one wins.
            if (rlc.Attribute(PtOpenXml.ContentType) != null)
                return;

            // add the attribute to the block level content
            rlc.Add(new XAttribute(PtOpenXml.ContentType, contentType));

            var mainPart = part as MainDocumentPart;
            if (mainPart != null)
            {
                // add a comment, if appropriate
                int commentNumber = 1;
                XDocument newComments = null;
                if (settings.InjectCommentForContentTypes != null && (bool)settings.InjectCommentForContentTypes)
                {
                    if (mainPart.WordprocessingCommentsPart != null)
                    {
                        newComments = mainPart.WordprocessingCommentsPart.GetXDocument();
                        newComments.Declaration.Standalone = "yes";
                        newComments.Declaration.Encoding = "UTF-8";
                        var ids = newComments.Root.Elements(W.comment).Select(f => (int)f.Attribute(W.id));
                        if (ids.Any())
                            commentNumber = ids.Max() + 1;
                    }
                    else
                    {
                        mainPart.AddNewPart<WordprocessingCommentsPart>();
                        newComments = mainPart.WordprocessingCommentsPart.GetXDocument();
                        newComments.Declaration.Standalone = "yes";
                        newComments.Declaration.Encoding = "UTF-8";
                        newComments.Add(new XElement(W.comments, NamespaceAttributes));
                        commentNumber = 1;
                    }
                    XElement newElement = new XElement(W.comment,
                        new XAttribute(W.id, commentNumber),
                        new XElement(W.p,
                            new XElement(W.pPr,
                                new XElement(W.pStyle,
                                    new XAttribute(W.val, "CommentText"))),
                            new XElement(W.r,
                                new XElement(W.rPr,
                                    new XElement(W.rStyle,
                                        new XAttribute(W.val, "CommentReference"))),
                                        new XElement(W.annotationRef)),
                            new XElement(W.r,
                                new XElement(W.t,
                                    new XText(contentType)))));
                    newComments.Root.Add(newElement);
                    XElement commentRun = new XElement(W.r,
                        new XElement(W.rPr,
                            new XElement(W.rStyle, new XAttribute(W.val, "CommentReference"))),
                        new XElement(W.commentReference,
                            new XAttribute(W.id, commentNumber)));
                    var firstRunInParagraph = rlc
                        .DescendantsTrimmed(W.txbxContent)
                        .Where(r => r.Name == W.r)
                        .FirstOrDefault();

                    // for now, only do the work of inserting a comment if it is easy.  For content types for tables, rows and cells, not inserting a comment.
                    if (rlc.Parent.Name == W.p)
                        rlc.AddBeforeSelf(commentRun);
                    if (mainPart.StyleDefinitionsPart == null)
                    {
                        throw new ContentApplierException("Document does not have styles definition part");
                    }
                    XDocument stylesXDoc = mainPart.StyleDefinitionsPart.GetXDocument();

                    var style =
@"<w:style w:type=""paragraph""
           w:styleId=""CommentText""
           xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:name w:val=""annotation text""/>
    <w:basedOn w:val=""Normal""/>
    <w:link w:val=""CommentTextChar""/>
    <w:semiHidden/>
    <w:rPr>
      <w:sz w:val=""20""/>
      <w:szCs w:val=""20""/>
    </w:rPr>
  </w:style>
";
                    AddIfMissing(stylesXDoc, style);
                    style =
@"<w:style w:type=""paragraph""
           w:styleId=""CommentSubject""
           xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:name w:val=""annotation subject""/>
    <w:basedOn w:val=""CommentText""/>
    <w:next w:val=""CommentText""/>
    <w:semiHidden/>
    <w:rPr>
      <w:b/>
      <w:bCs/>
    </w:rPr>
  </w:style>
";
                    AddIfMissing(stylesXDoc, style);
                    style =
@"<w:style w:type=""character""
           w:styleId=""CommentReference""
           xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:name w:val=""annotation reference""/>
    <w:basedOn w:val=""DefaultParagraphFont""/>
    <w:uiPriority w:val=""99""/>
    <w:semiHidden/>
    <w:unhideWhenUsed/>
    <w:rsid w:val=""00872729""/>
    <w:rPr>
      <w:sz w:val=""16""/>
      <w:szCs w:val=""16""/>
    </w:rPr>
  </w:style>
";
                    AddIfMissing(stylesXDoc, style);
                    style =
@"<w:style w:type=""character""
           w:customStyle=""1""
           w:styleId=""CommentTextChar""
           xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:name w:val=""Comment Text Char""/>
    <w:basedOn w:val=""DefaultParagraphFont""/>
    <w:link w:val=""CommentText""/>
    <w:semiHidden/>
    <w:rsid w:val=""00A43CEC""/>
    <w:rPr>
      <w:lang w:val=""en-GB""
              w:eastAsia=""zh-CN""/>
    </w:rPr>
  </w:style>
";
                    AddIfMissing(stylesXDoc, style);
                    mainPart.StyleDefinitionsPart.PutXDocument();
                }
            }

            var root = rlc.Ancestors().LastOrDefault();
            if (root == null)
                throw new ContentApplierException("Internal error");
            var ptNamespace = root.Attribute(XNamespace.Xmlns + "pt");
            if (ptNamespace == null)
            {
                root.Add(new XAttribute(XNamespace.Xmlns + "pt", PtOpenXml.pt.NamespaceName));
            }
            var ignorable = (string)root.Attribute(MC.Ignorable);
            if (ignorable != null)
            {
                var list = ignorable.Split(' ');
                if (!list.Contains("pt"))
                {
                    ignorable += " pt";
                    root.Attribute(MC.Ignorable).Value = ignorable;
                }
            }
            else
            {
                root.Add(new XAttribute(MC.Ignorable, "pt"));
            }
        }

        private static void AddIfMissing(XDocument stylesXDoc, string commentStyle)
        {
            XElement e1 = XElement.Parse(commentStyle);
#if false
  <w:style w:type=""character""
           w:customStyle=""1""
           w:styleId=""CommentTextChar""
#endif
            var existingStyle = stylesXDoc
                .Root
                .Elements(W.style)
                .FirstOrDefault(e2 =>
                {
                    XName name = W.type;
                    string v1 = (string)e1.Attribute(name);
                    string v2 = (string)e2.Attribute(name);
                    if (v1 != v2)
                        return false;
                    name = W.customStyle;
                    v1 = (string)e1.Attribute(name);
                    v2 = (string)e2.Attribute(name);
                    if (v1 != v2)
                        return false;
                    name = W.styleId;
                    v1 = (string)e1.Attribute(name);
                    v2 = (string)e2.Attribute(name);
                    if (v1 != v2)
                        return false;
                    return true;
                });
            if (existingStyle != null)
                return;
            stylesXDoc.Root.Add(e1);
        }

        private static void AssembleListItemInformation(WordprocessingDocument wordDoc, ListItemRetrieverSettings settings)
        {
            XDocument xDoc = wordDoc.MainDocumentPart.GetXDocument();
            foreach (var para in xDoc.Descendants(W.p))
            {
                ListItemRetriever.RetrieveListItem(wordDoc, para, settings);
            }
        }

        private class ContentTypeApplierInfo
        {
            public string DefaultParagraphStyleName;
            public string DefaultCharacterStyleName;
            public string DefaultTableStyleName;
            public ContentTypeApplierInfo()
            {
            }
        }

        public class ContentApplierException : Exception
        {
            public ContentApplierException(string message) : base(message) { }
        }

        public static List<WmlToXmlValidationError> ValidateContentTypeXml(WmlDocument wmlRawSourceDocument, WmlDocument wmlWithContentTypeApplied, XElement contentTypeXml, WmlToXmlSettings settings)
        {
            List<WmlToXmlValidationError> errorList = new List<WmlToXmlValidationError>();

            using (MemoryStream msContentTypeApplied = new MemoryStream())
            using (MemoryStream msRawSourceDocument = new MemoryStream())
            {
                msContentTypeApplied.Write(wmlWithContentTypeApplied.DocumentByteArray, 0, wmlWithContentTypeApplied.DocumentByteArray.Length);
                msRawSourceDocument.Write(wmlRawSourceDocument.DocumentByteArray, 0, wmlRawSourceDocument.DocumentByteArray.Length);
                using (WordprocessingDocument wDocContentTypeApplied = WordprocessingDocument.Open(msContentTypeApplied, true))
                using (WordprocessingDocument wDocRawSourceDocument = WordprocessingDocument.Open(msRawSourceDocument, true))
                {
                    foreach (var vr in settings.GlobalValidationRules)
                    {
                        if (vr.GlobalRuleLambda != null)
                        {
                            var valErrors = vr.GlobalRuleLambda(vr, wDocRawSourceDocument, wDocContentTypeApplied, contentTypeXml, settings);
                            if (valErrors != null && valErrors.Any())
                            {
                                foreach (var ve in valErrors)
                                {
                                    errorList.Add(ve);
                                }
                            }
                        }
                    }
                    var mXDoc = wDocContentTypeApplied.MainDocumentPart.GetXDocument();
                    var sXDoc = wDocContentTypeApplied.MainDocumentPart.StyleDefinitionsPart.GetXDocument();

                    var defaultParagraphStyle = sXDoc
                        .Root
                        .Elements(W.style)
                        .FirstOrDefault(s => (string)s.Attribute(W._default) == "1");

                    string defaultParagraphStyleName = null;
                    if (defaultParagraphStyle != null)
                        defaultParagraphStyleName = (string)defaultParagraphStyle.Attribute(W.styleId);

                    foreach (var blc in mXDoc.Root.Descendants().Where(d => d.Name == W.p || d.Name == W.tbl || d.Name == W.tr || d.Name == W.tc))
                    {
                        var styleId = (string)blc
                            .Elements(W.pPr)
                            .Elements(W.pStyle)
                            .Attributes(W.val)
                            .FirstOrDefault();
                        var styleName = (string)sXDoc
                            .Root
                            .Elements(W.style)
                            .Where(s => (string)s.Attribute(W.styleId) == styleId)
                            .Elements(W.name)
                            .Attributes(W.val)
                            .FirstOrDefault();

                        if (styleName == null && blc.Name == W.p)
                            styleName = defaultParagraphStyleName;

                        foreach (var vr in settings.BlockLevelContentValidationRules)
                        {
                            bool matchStyle = true;
                            if (vr.StyleNameRegex != null)
                            {
                                if (styleName == null)
                                {
                                    matchStyle = false;
                                }
                                else
                                {
                                    var match = vr.StyleNameRegex.Match(styleName);
                                    matchStyle = match.Success;
                                }
                            }
                            if (matchStyle && vr.BlockLevelContentRuleLambda != null)
                            {
                                var valErrors = vr.BlockLevelContentRuleLambda(blc, vr, wDocContentTypeApplied, contentTypeXml, settings);
                                if (valErrors != null && valErrors.Any())
                                {
                                    foreach (var ve in valErrors)
                                    {
                                        errorList.Add(ve);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return errorList;
        }
    }

    public static class WmlToXmlUtil
    {
        public static WmlDocument AssignUnidToBlc(WmlDocument document)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Write(document.DocumentByteArray, 0, document.DocumentByteArray.Length);
                using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true))
                {
                    var xDoc = wDoc.MainDocumentPart.GetXDocument();
                    List<XElement> elementsInOrder = new List<XElement>();
                    DetermineElementOrder(xDoc.Root.Descendants(W.body).FirstOrDefault(), elementsInOrder);
                    var unid = 1;
                    foreach (var b in elementsInOrder)
                    {
                        var unidString = unid.ToString();
                        if (b.Attribute(PtOpenXml.Unid) != null)
                            b.Attribute(PtOpenXml.Unid).Value = unidString;
                        else
                            b.Add(new XAttribute(PtOpenXml.Unid, unidString));
                        unid++;
                    }
                    IgnorePt14Namespace(xDoc.Root);
                    wDoc.MainDocumentPart.PutXDocument();
                }
                var result = new WmlDocument(document.FileName, ms.ToArray());
                return result;
            }
        }

        private static void DetermineElementOrder(XElement element, List<XElement> elementList)
        {
            foreach (var childElement in element.Elements())
            {
                if (childElement.Name == W.p)
                {
                    elementList.Add(childElement);
                    continue;
                }
                else if (childElement.Name == W.tbl || childElement.Name == W.tc || childElement.Name == W.sdt ||
                    childElement.Name == W.sdtContent)
                {
                    DetermineElementOrder(childElement, elementList);
                    continue;
                }
                else if (childElement.Name == W.tr)
                {
                    foreach (var tc in childElement.Elements())
                        DetermineElementOrder(tc, elementList);
                    elementList.Add(childElement);
                    continue;
                }
            }
        }

        private static void IgnorePt14Namespace(XElement root)
        {
            if (root.Attribute(XNamespace.Xmlns + "pt14") == null)
            {
                root.Add(new XAttribute(XNamespace.Xmlns + "pt14", PtOpenXml.pt.NamespaceName));
            }
            var ignorable = (string)root.Attribute(MC.Ignorable);
            if (ignorable != null)
            {
                var list = ignorable.Split(' ');
                if (!list.Contains("pt14"))
                {
                    ignorable += " pt14";
                    root.Attribute(MC.Ignorable).Value = ignorable;
                }
            }
            else
            {
                root.Add(new XAttribute(MC.Ignorable, "pt14"));
            }
        }
    }
}
