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

Copyright (c) Microsoft Corporation 2012-2015.

This code is licensed using the Microsoft Public License (Ms-PL).  The text of the license can be found here:

http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx

Published at http://OpenXmlDeveloper.org
Resource Center and Documentation: http://openxmldeveloper.org/wiki/w/wiki/powertools-for-open-xml.aspx

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.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
using System.Drawing;

namespace OpenXmlPowerTools
{
    public class FormattingAssemblerSettings
    {
        public bool RemoveStyleNamesFromParagraphAndRunProperties;
        public bool ClearStyles;
        public bool OrderElementsPerStandard;
        public bool CreateHtmlConverterAnnotationAttributes;
        public bool RestrictToSupportedNumberingFormats;
        public bool RestrictToSupportedLanguages;
        public ListItemRetrieverSettings ListItemRetrieverSettings;

        public FormattingAssemblerSettings()
        {
            RemoveStyleNamesFromParagraphAndRunProperties = true;
            ClearStyles = true;
            OrderElementsPerStandard = true;
            CreateHtmlConverterAnnotationAttributes = true;
            RestrictToSupportedNumberingFormats = false;
            RestrictToSupportedLanguages = false;
            ListItemRetrieverSettings = new ListItemRetrieverSettings();
        }
    }

    public static class FormattingAssembler
    {
        public static WmlDocument AssembleFormatting(WmlDocument document, FormattingAssemblerSettings settings)
        {
            using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(document))
            {
                using (WordprocessingDocument doc = streamDoc.GetWordprocessingDocument())
                {
                    AssembleFormatting(doc, settings);
                }
                return streamDoc.GetModifiedWmlDocument();
            }
        }

        public static void AssembleFormatting(WordprocessingDocument wDoc, FormattingAssemblerSettings settings)
        {
            FormattingAssemblerInfo fai = new FormattingAssemblerInfo();
            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)
                fai.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)
                fai.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)
                fai.DefaultTableStyleName = (string)defaultTableStyle.Attribute(W.styleId);
            ListItemRetrieverSettings listItemRetrieverSettings = new ListItemRetrieverSettings();
            AssembleListItemInformation(wDoc, settings.ListItemRetrieverSettings);
            foreach (var part in wDoc.ContentParts())
            {
                var pxd = part.GetXDocument();
                FixNonconformantHexValues(pxd.Root);
                AnnotateWithGlobalDefaults(wDoc, pxd.Root, settings);
                AnnotateTablesWithTableStyles(wDoc, pxd.Root);
                AnnotateParagraphs(fai, wDoc, pxd.Root, settings);
                AnnotateRuns(fai, wDoc, pxd.Root, settings);
            }
            NormalizeListItems(fai, wDoc, settings);
            if (settings.ClearStyles)
                ClearStyles(wDoc);
            foreach (var part in wDoc.ContentParts())
            {
                var pxd = part.GetXDocument();
                pxd.Root.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
                FormattingAssembler.NormalizePropsForPart(pxd, settings);
                var newRoot = (XElement)CleanupTransform(pxd.Root);
                pxd.Root.ReplaceWith(newRoot);
                part.PutXDocument();
            }
        }

        private static void FixNonconformantHexValues(XElement root)
        {
            foreach (var tblLook in root.Descendants(W.tblLook))
            {
                if (tblLook.Attributes().Any(a => a.Name != W.val))
                    continue;
                if (tblLook.Attribute(W.val) == null)
                    continue;
                string hexValue = tblLook.Attribute(W.val).Value;
                int val = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
                tblLook.Add(new XAttribute(W.firstRow, (val & 0x0020) != 0 ? "1" : "0"));
                tblLook.Add(new XAttribute(W.lastRow, (val & 0x0040) != 0 ? "1" : "0"));
                tblLook.Add(new XAttribute(W.firstColumn, (val & 0x0080) != 0 ? "1" : "0"));
                tblLook.Add(new XAttribute(W.lastColumn, (val & 0x0100) != 0 ? "1" : "0"));
                tblLook.Add(new XAttribute(W.noHBand, (val & 0x0200) != 0 ? "1" : "0"));
                tblLook.Add(new XAttribute(W.noVBand, (val & 0x0400) != 0 ? "1" : "0"));
            }
            foreach (var cnfStyle in root.Descendants(W.cnfStyle))
            {
                if (cnfStyle.Attributes().Any(a => a.Name != W.val))
                    continue;
                if (cnfStyle.Attribute(W.val) == null)
                    continue;
                var va = cnfStyle.Attribute(W.val).Value.ToArray();
                cnfStyle.Add(new XAttribute(W.firstRow, va[0]));
                cnfStyle.Add(new XAttribute(W.lastRow, va[1]));
                cnfStyle.Add(new XAttribute(W.firstColumn, va[2]));
                cnfStyle.Add(new XAttribute(W.lastColumn, va[3]));
                cnfStyle.Add(new XAttribute(W.oddVBand, va[4]));
                cnfStyle.Add(new XAttribute(W.evenVBand, va[5]));
                cnfStyle.Add(new XAttribute(W.oddHBand, va[6]));
                cnfStyle.Add(new XAttribute(W.evenHBand, va[7]));
                cnfStyle.Add(new XAttribute(W.firstRowLastColumn, va[8]));
                cnfStyle.Add(new XAttribute(W.firstRowFirstColumn, va[9]));
                cnfStyle.Add(new XAttribute(W.lastRowLastColumn, va[10]));
                cnfStyle.Add(new XAttribute(W.lastRowFirstColumn, va[11]));
            }
        }

        private static object CleanupTransform(XNode node)
        {
            XElement element = node as XElement;
            if (element != null)
            {
                if (element.Name == W.tabs && element.Element(W.tab) == null)
                    return null;

                if (element.Name == W.tblStyleRowBandSize || element.Name == W.tblStyleColBandSize)
                    return null;

                // a cleaner solution would be to not include the w:ins and w:del elements when rolling up the paragraph run properties into
                // the run properties.
                if ((element.Name == W.ins || element.Name == W.del) && element.Parent.Name == W.rPr)
                {
                    if (element.Parent.Parent.Name == W.r || element.Parent.Parent.Name == W.rPrChange)
                        return null;
                }

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

        private static void ClearStyles(WordprocessingDocument wDoc)
        {
            var stylePart = wDoc.MainDocumentPart.StyleDefinitionsPart;
            var sXDoc = stylePart.GetXDocument();

            var newRoot = new XElement(sXDoc.Root.Name,
                sXDoc.Root.Attributes(),
                sXDoc.Root.Elements().Select(e =>
                {
                    if (e.Name != W.style)
                        return e;
                    return new XElement(e.Name,
                        e.Attributes(),
                        e.Element(W.name),
                        new XElement(W.pPr),
                        new XElement(W.rPr));
                }));

            var globalrPr = newRoot
                .Elements(W.docDefaults)
                .Elements(W.rPrDefault)
                .Elements(W.rPr)
                .FirstOrDefault();
            if (globalrPr != null)
                globalrPr.ReplaceWith(new XElement(W.rPr));

            var globalpPr = newRoot
                .Elements(W.docDefaults)
                .Elements(W.pPrDefault)
                .Elements(W.pPr)
                .FirstOrDefault();
            if (globalpPr != null)
                globalpPr.ReplaceWith(new XElement(W.pPr));

            sXDoc.Root.ReplaceWith(newRoot);

            stylePart.PutXDocument();
        }

        private static void NormalizeListItems(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, FormattingAssemblerSettings settings)
        {
            foreach (var part in wDoc.ContentParts())
            {
                var pxd = part.GetXDocument();
                XElement newRoot = (XElement)NormalizeListItemsTransform(fai, wDoc, pxd.Root, settings);
                if (newRoot.Attribute(XNamespace.Xmlns + "pt14") == null)
                    newRoot.Add(new XAttribute(XNamespace.Xmlns + "pt14", PtOpenXml.pt.NamespaceName));
                if (newRoot.Attribute(XNamespace.Xmlns + "mc") == null)
                    newRoot.Add(new XAttribute(XNamespace.Xmlns + "mc", MC.mc.NamespaceName));
                pxd.Root.ReplaceWith(newRoot);
            }
        }

        private static object NormalizeListItemsTransform(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XNode node, FormattingAssemblerSettings settings)
        {
            var element = node as XElement;
            if (element != null)
            {
                if (element.Name == W.p)
                {
                    var li = ListItemRetriever.RetrieveListItem(wDoc, element, settings.ListItemRetrieverSettings);
                    if (li != null)
                    {
                        ListItemRetriever.ListItemInfo listItemInfo = element.Annotation<ListItemRetriever.ListItemInfo>();

                        var newParaProps = new XElement(W.pPr,
                            element.Elements(W.pPr).Elements().Where(e => e.Name != W.numPr)
                        );

                        XElement listItemRunProps = null;
                        int? abstractNumId = null;
                        if (listItemInfo != null)
                        {
                            abstractNumId = listItemInfo.AbstractNumId;

                            var paraStyleRunProps = CharStyleRollup(fai, wDoc, element);

                            var paragraphStyleName = (string)element
                                .Elements(W.pPr)
                                .Elements(W.pStyle)
                                .Attributes(W.val)
                                .FirstOrDefault();

                            string defaultStyleName = (string)wDoc
                                    .MainDocumentPart
                                    .StyleDefinitionsPart
                                    .GetXDocument()
                                    .Root
                                    .Elements(W.style)
                                    .Where(s => (string)s.Attribute(W.type) == "paragraph" && s.Attribute(W._default).ToBoolean() == true)
                                    .Attributes(W.styleId)
                                    .FirstOrDefault();

                            if (paragraphStyleName == null)
                                paragraphStyleName = defaultStyleName;

                            XDocument stylesXDoc = wDoc
                                .MainDocumentPart
                                .StyleDefinitionsPart
                                .GetXDocument();

                            // put together run props for list item.

                            XElement lvlStyleRpr = ParaStyleRunPropsStack(wDoc, paragraphStyleName)
                                .Aggregate(new XElement(W.rPr),
                                    (r, s) =>
                                    {
                                        var newCharStyleRunProps = MergeStyleElement(s, r);
                                        return newCharStyleRunProps;
                                    });

                            var mergedRunProps = MergeStyleElement(lvlStyleRpr, paraStyleRunProps);

                            var accumulatedRunProps = element.Elements(PtOpenXml.pPr).Elements(W.rPr).FirstOrDefault();
                            if (accumulatedRunProps != null)
                                mergedRunProps = MergeStyleElement(accumulatedRunProps, mergedRunProps);

                            var listItemLvl = listItemInfo.Lvl(ListItemRetriever.GetParagraphLevel(element));
                            var listItemLvlRunProps = listItemLvl.Elements(W.rPr).FirstOrDefault();
                            listItemRunProps = MergeStyleElement(listItemLvlRunProps, mergedRunProps);

                            if ((string)listItemLvl.Elements(W.numFmt).Attributes(W.val).FirstOrDefault() == "bullet")
                            {
                                listItemRunProps.Elements(W.rtl).Remove();
                            }
                            else
                            {
                                var pPr = element.Element(PtOpenXml.pPr);
                                if (pPr != null)
                                {
                                    XElement bidiel = pPr.Element(W.bidi);
                                    bool bidi = bidiel != null && (bidiel.Attribute(W.val) == null || bidiel.Attribute(W.val).ToBoolean() == true);
                                    if (bidi)
                                    {
                                        listItemRunProps = MergeStyleElement(new XElement(W.rPr,
                                            new XElement(W.rtl)), listItemRunProps);
                                    }
                                }
                            }
                        }

                        var paragraphLevel = ListItemRetriever.GetParagraphLevel(element);
                        ListItemRetriever.LevelNumbers levelNums = element.Annotation<ListItemRetriever.LevelNumbers>();
                        string levelNumsString = levelNums
                            .LevelNumbersArray
                            .Take(paragraphLevel + 1)
                            .Select(i => i.ToString() + ".")
                            .StringConcatenate()
                            .TrimEnd('.');

                        var listItemRun = new XElement(W.r,
                            new XAttribute(PtOpenXml.ListItemRun, levelNumsString),
                            element.Attribute(PtOpenXml.FontName),
                            element.Attribute(PtOpenXml.LanguageType),
                            listItemRunProps,
                            new XElement(W.t,
                                new XAttribute(XNamespace.Xml + "space", "preserve"),
                                li));

                        AdjustFontAttributes(wDoc, listItemRun, null, listItemRunProps, settings);

                        var lvl = listItemInfo.Lvl(ListItemRetriever.GetParagraphLevel(element));
                        XElement suffix = new XElement(W.tab);
                        var su = (string)lvl.Elements(W.suff).Attributes(W.val).FirstOrDefault();
                        if (su == "space")
                            suffix = new XElement(W.t,
                                new XAttribute(XNamespace.Xml + "space", "preserve"),
                                " ");
                        else if (su == "nothing")
                            suffix = null;

                        var jc = (string)lvl.Elements(W.lvlJc).Attributes(W.val).FirstOrDefault();
                        if (jc == "right")
                        {
                            var accumulatedParaProps = element.Element(PtOpenXml.pPr);

                            var hangingAtt = accumulatedParaProps.Elements(W.ind).Attributes(W.hanging).FirstOrDefault();
                            if (hangingAtt == null)
                            {
                                var listItemRunLength = WordprocessingMLUtil.CalcWidthOfRunInTwips(listItemRun);
                                var ind = accumulatedParaProps.Element(W.ind);
                                if (ind == null)
                                {
                                    ind = new XElement(W.ind);
                                    accumulatedParaProps.Add(ind);
                                }
                                ind.Add(new XAttribute(W.hanging, listItemRunLength.ToString()));
                            }
                            else
                            {
                                var hanging = (int)hangingAtt;
                                var listItemRunLength = WordprocessingMLUtil.CalcWidthOfRunInTwips(listItemRun);
                                hanging += listItemRunLength; // should be width of list item, in twips
                                hangingAtt.Value = hanging.ToString();
                            }
                        }
                        else if (jc == "center")
                        {
                            var accumulatedParaProps = element.Element(PtOpenXml.pPr);

                            var hangingAtt = accumulatedParaProps.Elements(W.ind).Attributes(W.hanging).FirstOrDefault();
                            if (hangingAtt == null)
                            {
                                var listItemRunLength = WordprocessingMLUtil.CalcWidthOfRunInTwips(listItemRun);
                                var ind = accumulatedParaProps.Element(W.ind);
                                if (ind == null)
                                {
                                    ind = new XElement(W.ind);
                                    accumulatedParaProps.Add(ind);
                                }
                                ind.Add(new XAttribute(W.hanging, (listItemRunLength / 2).ToString()));
                            }
                            else
                            {
                                var hanging = (int)hangingAtt;
                                var listItemRunLength = WordprocessingMLUtil.CalcWidthOfRunInTwips(listItemRun);
                                hanging += (listItemRunLength / 2); // should be half of width of list item, in twips
                                hangingAtt.Value = hanging.ToString();
                            }
                        }
                        AddTabAtLeftIndent(element.Element(PtOpenXml.pPr));

                        XElement newPara = new XElement(W.p,
                            element.Attribute(PtOpenXml.FontName),
                            element.Attribute(PtOpenXml.LanguageType),
                            element.Attribute(PtOpenXml.Unid),
                            new XAttribute(PtOpenXml.AbstractNumId, abstractNumId),
                            newParaProps,
                            listItemRun,
                            suffix != null ?
                                new XElement(W.r,
                                    new XAttribute(PtOpenXml.ListItemRun, levelNumsString),
                                    listItemRunProps,
                                    suffix) : null,
                            element.Elements().Where(e => e.Name != W.pPr).Select(n => NormalizeListItemsTransform(fai, wDoc, n, settings)));
                        return newPara;

                    }
                }

                return new XElement(element.Name,
                    element.Attributes(),
                    element.Nodes().Select(n => NormalizeListItemsTransform(fai, wDoc, n, settings)));
            }
            return node;
        }

        private static void AddTabAtLeftIndent(XElement pPr)
        {
            int left = 0;
            var ind = pPr.Element(W.ind);

            // todo need to handle W.start
            if (pPr.Attribute(W.left) != null)
                left = (int)pPr.Attribute(W.left);
            var tabs = pPr.Element(W.tabs);
            if (tabs == null)
            {
                tabs = new XElement(W.tabs);
                pPr.Add(tabs);
            }
            var tabAtLeft = tabs.Elements(W.tab).FirstOrDefault(t => (int)t.Attribute(W.pos) == left);
            if (tabAtLeft == null)
            {
                tabs.Add(
                    new XElement(W.tab,
                        new XAttribute(W.val, "left"),
                        new XAttribute(W.pos, left)));
            }
        }

        public static XName[] PtNamesToKeep = new[] {
            PtOpenXml.FontName,
            PtOpenXml.AbstractNumId,
            PtOpenXml.StyleName,
            PtOpenXml.LanguageType,
            PtOpenXml.ListItemRun,
            PtOpenXml.Unid,
        };

        public static void NormalizePropsForPart(XDocument pxd, FormattingAssemblerSettings settings)
        {
            if (settings.CreateHtmlConverterAnnotationAttributes)
            {
                pxd.Root.Descendants().Attributes().Where(d => d.Name.Namespace == PtOpenXml.pt &&
                    !PtNamesToKeep.Contains(d.Name)).Remove();
                if (pxd.Root.Attribute(XNamespace.Xmlns + "pt14") == null)
                    pxd.Root.Add(new XAttribute(XNamespace.Xmlns + "pt14", PtOpenXml.pt.NamespaceName));
                if (pxd.Root.Attribute(XNamespace.Xmlns + "mc") == null)
                    pxd.Root.Add(new XAttribute(XNamespace.Xmlns + "mc", MC.mc.NamespaceName));
                XAttribute mci = pxd.Root.Attribute(MC.Ignorable);
                if (mci != null)
                {
                    if (!pxd.Root.Attribute(MC.Ignorable).Value.Contains("pt14"))
                    {
                        var ig = pxd.Root.Attribute(MC.Ignorable).Value + " pt14";
                        mci.Value = ig;
                    }
                }
                else
                {
                    pxd.Root.Add(new XAttribute(MC.Ignorable, "pt14"));
                }
            }
            else
            {
                pxd.Root.Descendants().Attributes().Where(d => d.Name.Namespace == PtOpenXml.pt).Remove();
            }
            var runProps = pxd.Root.Descendants(PtOpenXml.rPr).ToList();
            foreach (var item in runProps)
            {
                XElement newRunProps = new XElement(W.rPr,
                    item.Attributes(),
                    item.Elements());
                XElement parent = item.Parent;
                if (parent.Name == W.p)
                {
                    XElement existingParaProps = parent.Element(W.pPr);
                    if (existingParaProps == null)
                    {
                        existingParaProps = new XElement(W.pPr);
                        parent.Add(existingParaProps);
                    }
                    XElement existingRunProps = existingParaProps.Element(W.rPr);
                    if (existingRunProps != null)
                    {
                        if (!settings.RemoveStyleNamesFromParagraphAndRunProperties)
                        {
                            if (newRunProps.Element(W.rStyle) == null)
                                newRunProps.Add(existingRunProps.Element(W.rStyle));
                        }
                        existingRunProps.ReplaceWith(newRunProps);
                    }
                    else
                        existingParaProps.Add(newRunProps);
                }
                else
                {
                    XElement existingRunProps = parent.Element(W.rPr);
                    if (existingRunProps != null)
                    {
                        if (!settings.RemoveStyleNamesFromParagraphAndRunProperties)
                        {
                            if (newRunProps.Element(W.rStyle) == null)
                                newRunProps.Add(existingRunProps.Element(W.rStyle));
                        }
                        existingRunProps.ReplaceWith(newRunProps);
                    }
                    else
                        parent.Add(newRunProps);
                }
            }
            var paraProps = pxd.Root.Descendants(PtOpenXml.pPr).ToList();
            foreach (var item in paraProps)
            {
                var paraRunProps = item.Parent.Elements(W.pPr).Elements(W.rPr).FirstOrDefault();
                var merged = MergeStyleElement(item.Element(W.rPr), paraRunProps);
                if (!settings.RemoveStyleNamesFromParagraphAndRunProperties)
                {
                    if (merged.Element(W.rStyle) == null)
                    {
                        merged.Add(paraRunProps.Element(W.rStyle));
                    }
                }

                XElement newParaProps = new XElement(W.pPr,
                    item.Attributes(),
                    item.Elements().Where(e => e.Name != W.rPr),
                    merged);
                XElement para = item.Parent;
                XElement existingParaProps = para.Element(W.pPr);
                if (existingParaProps != null)
                {
                    if (!settings.RemoveStyleNamesFromParagraphAndRunProperties)
                    {
                        if (newParaProps.Element(W.pStyle) == null)
                            newParaProps.Add(existingParaProps.Element(W.pStyle));
                    }
                    existingParaProps.ReplaceWith(newParaProps);
                }
                else
                    para.Add(newParaProps);
            }
            var tblProps = pxd.Root.Descendants(PtOpenXml.tblPr).ToList();
            foreach (var item in tblProps)
            {
                XElement newTblProps = new XElement(item);
                newTblProps.Name = W.tblPr;
                XElement table = item.Parent;
                XElement existingTableProps = table.Element(W.tblPr);
                if (existingTableProps != null)
                    existingTableProps.ReplaceWith(newTblProps);
                else
                    table.AddFirst(newTblProps);
            }
            var trProps = pxd.Root.Descendants(PtOpenXml.trPr).ToList();
            foreach (var item in trProps)
            {
                XElement newTrProps = new XElement(item);
                newTrProps.Name = W.trPr;
                XElement row = item.Parent;
                XElement existingRowProps = row.Element(W.trPr);
                if (existingRowProps != null)
                    existingRowProps.ReplaceWith(newTrProps);
                else
                    row.AddFirst(newTrProps);
            }
            var tcProps = pxd.Root.Descendants(PtOpenXml.tcPr).ToList();
            foreach (var item in tcProps)
            {
                XElement newTcProps = new XElement(item);
                newTcProps.Name = W.tcPr;
                XElement row = item.Parent;
                XElement existingRowProps = row.Element(W.tcPr);
                if (existingRowProps != null)
                    existingRowProps.ReplaceWith(newTcProps);
                else
                    row.AddFirst(newTcProps);
            }
            pxd.Root.Descendants(W.numPr).Remove();
            if (settings.RemoveStyleNamesFromParagraphAndRunProperties)
            {
                pxd.Root.Descendants(W.pStyle).Where(ps => ps.Parent.Name == W.pPr).Remove();
                pxd.Root.Descendants(W.rStyle).Where(ps => ps.Parent.Name == W.rPr).Remove();
            }
            pxd.Root.Descendants(W.tblStyle).Where(ps => ps.Parent.Name == W.tblPr).Remove();
            pxd.Root.Descendants().Where(d => d.Name.Namespace == PtOpenXml.pt).Remove();
            if (settings.OrderElementsPerStandard)
            {
                XElement newRoot = (XElement)WordprocessingMLUtil.WmlOrderElementsPerStandard(pxd.Root);
                pxd.Root.ReplaceWith(newRoot);
            }
        }

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

        private static void AnnotateWithGlobalDefaults(WordprocessingDocument wDoc, XElement rootElement, FormattingAssemblerSettings settings)
        {
            XElement globalDefaultParaProps = null;
            XElement globalDefaultParaPropsAsDefined = null;
            XElement globalDefaultRunProps = null;
            XElement globalDefaultRunPropsAsDefined = null;
            XDocument sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
            var defaultParaStyleName = (string)sXDoc
                .Root
                .Elements(W.style)
                .Where(st => (string)st.Attribute(W.type) == "paragraph" && st.Attribute(W._default).ToBoolean() == true)
                .Attributes(W.styleId)
                .FirstOrDefault();
            var defaultCharStyleName = (string)sXDoc
                .Root
                .Elements(W.style)
                .Where(st => (string)st.Attribute(W.type) == "character" && st.Attribute(W._default).ToBoolean() == true)
                .Attributes(W.styleId)
                .FirstOrDefault();
            XElement docDefaults = sXDoc.Root.Element(W.docDefaults);
            if (docDefaults != null)
            {
                globalDefaultParaPropsAsDefined = docDefaults.Elements(W.pPrDefault).Elements(W.pPr)
                    .FirstOrDefault();
                if (globalDefaultParaPropsAsDefined == null)
                    globalDefaultParaPropsAsDefined = new XElement(W.pPr,
                        new XElement(W.rPr));
                globalDefaultRunPropsAsDefined = docDefaults.Elements(W.rPrDefault).Elements(W.rPr)
                    .FirstOrDefault();
                if (globalDefaultRunPropsAsDefined == null)
                    globalDefaultRunPropsAsDefined = new XElement(W.rPr);
                if (globalDefaultRunPropsAsDefined.Element(W.rFonts) == null)
                    globalDefaultRunPropsAsDefined.Add(
                        new XElement(W.rFonts,
                            new XAttribute(W.ascii, "Times New Roman"),
                            new XAttribute(W.hAnsi, "Times New Roman"),
                            new XAttribute(W.cs, "Times New Roman")));
                if (globalDefaultRunPropsAsDefined.Element(W.sz) == null)
                    globalDefaultRunPropsAsDefined.Add(
                        new XElement(W.sz,
                            new XAttribute(W.val, "20")));
                if (globalDefaultRunPropsAsDefined.Element(W.szCs) == null)
                    globalDefaultRunPropsAsDefined.Add(
                        new XElement(W.szCs,
                            new XAttribute(W.val, "20")));

                var runPropsForGlobalDefaultParaProps = MergeStyleElement(globalDefaultRunPropsAsDefined, globalDefaultParaPropsAsDefined.Element(W.rPr));
                globalDefaultParaProps = new XElement(globalDefaultParaPropsAsDefined.Name,
                    globalDefaultParaPropsAsDefined.Attributes(),
                    globalDefaultParaPropsAsDefined.Elements().Where(e => e.Name != W.rPr),
                    runPropsForGlobalDefaultParaProps);
                globalDefaultRunProps = MergeStyleElement(globalDefaultParaPropsAsDefined.Element(W.rPr), globalDefaultRunPropsAsDefined);
            }
            var rPr = new XElement(W.rPr,
                        new XElement(W.rFonts,
                                new XAttribute(W.ascii, "Times New Roman"),
                                new XAttribute(W.hAnsi, "Times New Roman"),
                                new XAttribute(W.cs, "Times New Roman")),
                            new XElement(W.sz,
                                new XAttribute(W.val, "20")),
                            new XElement(W.szCs,
                                new XAttribute(W.val, "20")));

            if (globalDefaultParaProps == null)
                globalDefaultParaProps = new XElement(W.pPr, rPr);

            if (globalDefaultRunProps == null)
                globalDefaultRunProps = rPr;

            XElement ptGlobalDefaultParaProps = new XElement(globalDefaultParaProps);
            XElement ptGlobalDefaultRunProps = new XElement(globalDefaultRunProps);
            ptGlobalDefaultParaProps.Name = PtOpenXml.pPr;
            ptGlobalDefaultRunProps.Name = PtOpenXml.rPr;
            var parasAndRuns = rootElement.Descendants().Where(d =>
            {
                return d.Name == W.p || d.Name == W.r;
            });
            if (settings.CreateHtmlConverterAnnotationAttributes)
            {
                foreach (var d in parasAndRuns)
                {
                    if (d.Name == W.p)
                    {
                        var pStyle = (string)d.Elements(W.pPr).Elements(W.pStyle).Attributes(W.val).FirstOrDefault();
                        if (pStyle == null)
                            pStyle = defaultParaStyleName;
                        if (pStyle != null)
                        {
                            if (d.Attribute(PtOpenXml.StyleName) != null)
                                d.Attribute(PtOpenXml.StyleName).Value = pStyle;
                            else
                                d.Add(new XAttribute(PtOpenXml.StyleName, pStyle));
                        }
                        d.Add(ptGlobalDefaultParaProps);
                    }
                    else
                    {
                        var rStyle = (string)d.Elements(W.rPr).Elements(W.rStyle).Attributes(W.val).FirstOrDefault();
                        if (rStyle == null)
                            rStyle = defaultCharStyleName;
                        if (rStyle != null)
                        {
                            if (d.Attribute(PtOpenXml.StyleName) != null)
                                d.Attribute(PtOpenXml.StyleName).Value = rStyle;
                            else
                                d.Add(new XAttribute(PtOpenXml.StyleName, rStyle));
                        }
                        d.Add(ptGlobalDefaultRunProps);
                    }
                }
            }
            else
            {
                foreach (var d in parasAndRuns)
                {
                    if (d.Name == W.p)
                    {
                        d.Add(ptGlobalDefaultParaProps);
                    }
                    else
                    {
                        d.Add(ptGlobalDefaultRunProps);
                    }
                }
            }
        }

        private static XElement BlankTcBorders = new XElement(W.tcBorders,
            new XElement(W.top, new XAttribute(W.val, "nil")),
            new XElement(W.left, new XAttribute(W.val, "nil")),
            new XElement(W.bottom, new XAttribute(W.val, "nil")),
            new XElement(W.right, new XAttribute(W.val, "nil")));

        private static void AnnotateTablesWithTableStyles(WordprocessingDocument wDoc, XElement rootElement)
        {
            XDocument sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
            foreach (var tbl in rootElement.Descendants(W.tbl))
            {
                string tblStyleName = (string)tbl.Elements(W.tblPr).Elements(W.tblStyle).Attributes(W.val).FirstOrDefault();
                if (tblStyleName != null)
                {
                    XElement style = TableStyleRollup(wDoc, tblStyleName);

                    // annotate table with table style, in PowerTools namespace
                    style.Name = PtOpenXml.style;
                    tbl.Add(style);

                    // merge tblPr in table style with tblPr of the table
                    // annnotate in PowerTools namespace
                    XElement tblPr2 = style.Element(W.tblPr);
                    XElement tblPr3 = MergeStyleElement(tbl.Element(W.tblPr), tblPr2, true);
                    if (tblPr3 != null)
                    {
                        XElement newTblPr = new XElement(tblPr3);
                        newTblPr.Name = PtOpenXml.pt + "tblPr";
                        tbl.Add(newTblPr);
                    }

                    AddTcPrPtToEveryCell(tbl);
                    AddOuterBorders(tbl, style);

                    var tableTcPr = style.Element(W.tcPr);
                    if (tableTcPr != null)
                    {
                        foreach (var row in tbl.Elements(W.tr))
                        {
                            foreach (var cell in row.Elements(W.tc))
                            {
                                bool tcPrPtExists = false;
                                var tcPrPt = cell.Element(PtOpenXml.pt + "tcPr");
                                if (tcPrPt != null)
                                    tcPrPtExists = true;
                                else
                                    tcPrPt = new XElement(W.tcPr);
                                tcPrPt = MergeStyleElement(tableTcPr, tcPrPt);
                                var newTcPrPt = new XElement(tcPrPt);
                                newTcPrPt.Name = PtOpenXml.tcPr;
                                if (tcPrPtExists)
                                    cell.Element(PtOpenXml.tcPr).ReplaceWith(newTcPrPt);
                                else
                                    cell.Add(newTcPrPt);
                            }
                        }
                    }

                    // Iterate through every row and cell in the table, rolling up row properties and cell properties
                    // as appropriate per the cnfStyle element, then replacing the row and cell properties
                    foreach (var row in tbl.Elements(W.tr))
                    {
                        XElement trPr2 = null;
                        trPr2 = style.Element(W.trPr);
                        if (trPr2 == null)
                            trPr2 = new XElement(W.trPr);
                        XElement rowCnf = row.Elements(W.trPr).Elements(W.cnfStyle).FirstOrDefault();
                        if (rowCnf != null)
                        {
                            foreach (var ot in TableStyleOverrideTypes)
                            {
                                XName attName = TableStyleOverrideXNameMap[ot];
                                if (rowCnf != null && rowCnf.Attribute(attName).ToBoolean() == true)
                                {
                                    XElement o = style
                                        .Elements(W.tblStylePr)
                                        .Where(tsp => (string)tsp.Attribute(W.type) == ot)
                                        .FirstOrDefault();
                                    if (o != null)
                                    {
                                        XElement ottrPr = o.Element(W.trPr);
                                        trPr2 = MergeStyleElement(ottrPr, trPr2);
                                    }
                                }
                            }
                        }
                        trPr2 = MergeStyleElement(row.Element(W.trPr), trPr2);
                        if (trPr2.HasElements)
                        {
                            trPr2.Name = PtOpenXml.pt + "trPr";
                            row.Add(trPr2);
                        }
                    }

                    foreach (var ot in TableStyleOverrideTypes)
                    {
                        XName attName = TableStyleOverrideXNameMap[ot];
                        if (attName == W.oddHBand ||
                            attName == W.evenHBand ||
                            attName == W.firstRow ||
                            attName == W.lastRow)
                        {
                            foreach (var row in tbl.Elements(W.tr))
                            {
                                XElement rowCnf = row.Elements(W.trPr).Elements(W.cnfStyle).FirstOrDefault();
                                if (rowCnf != null && rowCnf.Attribute(attName).ToBoolean() == true)
                                {
                                    XElement o = style
                                        .Elements(W.tblStylePr)
                                        .Where(tsp => (string)tsp.Attribute(W.type) == ot)
                                        .FirstOrDefault();
                                    if (o != null)
                                    {
                                        foreach (var cell in row.Elements(W.tc))
                                        {
                                            bool tcPrPtExists = false;
                                            var tcPrPt = cell.Element(PtOpenXml.pt + "tcPr");
                                            if (tcPrPt != null)
                                                tcPrPtExists = true;
                                            else
                                                tcPrPt = new XElement(W.tcPr);
                                            tcPrPt = MergeStyleElement(o.Element(W.tcPr), tcPrPt);
                                            var newTcPrPt = new XElement(tcPrPt);
                                            newTcPrPt.Name = PtOpenXml.pt + "tcPr";
                                            if (tcPrPtExists)
                                                cell.Element(PtOpenXml.pt + "tcPr").ReplaceWith(newTcPrPt);
                                            else
                                                cell.Add(newTcPrPt);
                                        }
                                    }
                                }
                            }
                        }
                        else if (attName == W.firstColumn ||
                            attName == W.lastColumn ||
                            attName == W.oddVBand ||
                            attName == W.evenVBand)
                        {
                            foreach (var row in tbl.Elements(W.tr))
                            {
                                foreach (var cell in row.Elements(W.tc))
                                {
                                    ApplyCndFmtToCell(style, ot, attName, cell);
                                }
                            }
                        }
                        else if (attName == W.firstRowLastColumn)
                        {
                            var row = tbl.Elements(W.tr).FirstOrDefault();
                            if (row != null)
                            {
                                var cell = row.Elements(W.tc).LastOrDefault();
                                if (cell != null)
                                    ApplyCndFmtToCell(style, ot, attName, cell);
                            }
                        }
                        else if (attName == W.firstRowFirstColumn)
                        {
                            var row = tbl.Elements(W.tr).FirstOrDefault();
                            if (row != null)
                            {
                                var cell = row.Elements(W.tc).FirstOrDefault();
                                if (cell != null)
                                    ApplyCndFmtToCell(style, ot, attName, cell);
                            }
                        }
                        else if (attName == W.lastRowLastColumn)
                        {
                            var row = tbl.Elements(W.tr).LastOrDefault();
                            if (row != null)
                            {
                                var cell = row.Elements(W.tc).LastOrDefault();
                                if (cell != null)
                                    ApplyCndFmtToCell(style, ot, attName, cell);
                            }
                        }
                        else if (attName == W.lastRowFirstColumn)
                        {
                            var row = tbl.Elements(W.tr).LastOrDefault();
                            if (row != null)
                            {
                                var cell = row.Elements(W.tc).FirstOrDefault();
                                if (cell != null)
                                    ApplyCndFmtToCell(style, ot, attName, cell);
                            }
                        }
                    }
                    ProcessInnerBorders(tbl, style);
                }
                else
                {
                    var tblPr = new XElement(W.tblPr);
                    XElement tblPr3 = MergeStyleElement(tbl.Element(W.tblPr), tblPr, true);
                    if (tblPr3 != null)
                    {
                        XElement newTblPr = new XElement(tblPr3);
                        newTblPr.Name = PtOpenXml.pt + "tblPr";
                        tbl.Add(newTblPr);
                    }

                    AddTcPrPtToEveryCell(tbl);
                }
                RollInDirectFormatting(tbl); // it is important that this is last.  This merges in direct formatting.
            }
        }

        private static void AddTcPrPtToEveryCell(XElement tbl)
        {
            foreach (var row in tbl.Elements(W.tr))
            {
                foreach (var cell in row.Elements(W.tc))
                {
                    var tcPrPt = cell.Element(PtOpenXml.pt + "tcPr");
                    if (tcPrPt != null)
                        continue;
                    tcPrPt = new XElement(PtOpenXml.pt + "tcPr",
                        new XElement(W.tcBorders));
                    cell.Add(tcPrPt);
                }
            }
        }

        private static void ApplyCndFmtToCell(XElement style, string ot, XName attName, XElement cell)
        {
            XElement cellCnf = cell.Elements(W.tcPr).Elements(W.cnfStyle).FirstOrDefault();
            if (cellCnf != null && cellCnf.Attribute(attName).ToBoolean() == true)
            {
                XElement o = style
                    .Elements(W.tblStylePr)
                    .Where(tsp => (string)tsp.Attribute(W.type) == ot)
                    .FirstOrDefault();
                if (o != null)
                {
                    bool tcPrPtExists = false;
                    var tcPrPt = cell.Element(PtOpenXml.pt + "tcPr");
                    if (tcPrPt != null)
                        tcPrPtExists = true;
                    else
                        tcPrPt = new XElement(W.tcPr);
                    tcPrPt = MergeStyleElement(o.Element(W.tcPr), tcPrPt);
                    var newTcPrPt = new XElement(tcPrPt);
                    newTcPrPt.Name = PtOpenXml.pt + "tcPr";
                    if (tcPrPtExists)
                        cell.Element(PtOpenXml.pt + "tcPr").ReplaceWith(newTcPrPt);
                    else
                        cell.Add(newTcPrPt);
                }
            }
        }

        private static void RollInDirectFormatting(XElement tbl)
        {
            foreach (var row in tbl.Elements(W.tr))
            {
                foreach (var cell in row.Elements(W.tc))
                {
                    var ptTcPr = cell.Element(PtOpenXml.pt + "tcPr");
                    var tcPr = cell.Element(W.tcPr);
                    var mTcPr = MergeStyleElement(tcPr, ptTcPr);
                    if (mTcPr == null)
                    {
                        mTcPr = new XElement(PtOpenXml.pt + "tcPr");
                        cell.Add(tcPr);
                    }
                    var newTcPr = new XElement(mTcPr);
                    newTcPr.Name = PtOpenXml.pt + "tcPr";
                    var existing = cell.Element(PtOpenXml.pt + "tcPr");
                    if (existing != null)
                        existing.ReplaceWith(newTcPr);
                    else
                        cell.Add(newTcPr);
                }
            }
            var tblBorders = tbl.Elements(PtOpenXml.pt + "tblPr").Elements(W.tblBorders).FirstOrDefault();
            if (tblBorders != null && tblBorders.Attribute(PtOpenXml.pt + "fromDirect") != null)
            {
                ApplyTblBordersToTable(tbl, tblBorders);
                ProcessInnerBordersPerTblBorders(tbl, tblBorders);
            }
        }

        private static void ApplyTblBordersToTable(XElement tbl, XElement tblBorders)
        {
            var top = tblBorders.Element(W.top);
            if (top != null)
            {
                var firstRow = tbl.Elements(W.tr).FirstOrDefault();
                if (firstRow != null)
                {
                    foreach (var cell in firstRow.Elements(W.tc))
                    {
                        var cellTcBorders = cell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                        if (cellTcBorders != null)
                        {
                            var cellTop = cellTcBorders.Element(W.top);
                            if (cellTop == null)
                                cellTcBorders.Add(top);
                            else
                                cellTop.ReplaceAttributes(top.Attributes());
                        }
                    }
                }
            }
            var bottom = tblBorders.Element(W.bottom);
            if (bottom != null)
            {
                var lastRow = tbl.Elements(W.tr).LastOrDefault();
                if (lastRow != null)
                {
                    foreach (var cell in lastRow.Elements(W.tc))
                    {
                        var cellTcBorders = cell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                        if (cellTcBorders != null)
                        {
                            var cellBottom = cellTcBorders.Element(W.bottom);
                            if (cellBottom == null)
                                cellTcBorders.Add(bottom);
                            else
                                cellBottom.ReplaceAttributes(bottom.Attributes());
                        }
                    }
                }
            }
            foreach (var row in tbl.Elements(W.tr))
            {
                var left = tblBorders.Element(W.left);
                if (left != null)
                {
                    var firstCell = row.Elements(W.tc).FirstOrDefault();
                    if (firstCell != null)
                    {
                        var cellTcBorders = firstCell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                        if (cellTcBorders != null)
                        {
                            var firstCellLeft = cellTcBorders.Element(W.left);
                            if (firstCellLeft == null)
                                cellTcBorders.Add(left);
                            else
                                firstCellLeft.ReplaceAttributes(left.Attributes());
                        }
                    }
                }
                var right = tblBorders.Element(W.right);
                if (right != null)
                {
                    var lastCell = row.Elements(W.tc).LastOrDefault();
                    if (lastCell != null)
                    {
                        var cellTcBorders = lastCell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                        if (cellTcBorders != null)
                        {
                            var lastCellRight = cellTcBorders.Element(W.right);
                            if (lastCellRight == null)
                                cellTcBorders.Add(right);
                            else
                                lastCellRight.ReplaceAttributes(right.Attributes());
                        }
                    }
                }
            }
        }

        private static void AddOuterBorders(XElement tbl, XElement style)
        {
            var tblBorders = tbl.Elements(PtOpenXml.pt + "tblPr").Elements(W.tblBorders).FirstOrDefault();
            if (tblBorders != null)
                ApplyTblBordersToTable(tbl, tblBorders);
        }

        private static void ProcessInnerBorders(XElement tbl, XElement style)
        {
            var tblBorders = tbl.Elements(PtOpenXml.pt + "tblPr").Elements(W.tblBorders).FirstOrDefault();
            if (tblBorders != null)
                ProcessInnerBordersPerTblBorders(tbl, tblBorders);

            foreach (var attName in new[] { W.oddHBand, W.evenHBand, W.firstRow, W.lastRow })
            {
                int rowCount = tbl.Elements(W.tr).Count();
                int lastRow = rowCount - 1;
                XElement insideV = null;
                foreach (var row in tbl.Elements(W.tr))
                {
                    var rowCnfStyle = row.Elements(W.trPr).Elements(W.cnfStyle).FirstOrDefault();
                    if (rowCnfStyle != null)
                    {
                        var shouldApply = rowCnfStyle.Attribute(attName).ToBoolean();
                        if (shouldApply == true)
                        {
                            var cndType = TableStyleOverrideXNameRevMap[attName];
                            var cndStyle = style
                                .Elements(W.tblStylePr)
                                .FirstOrDefault(tsp => (string)tsp.Attribute(W.type) == cndType);
                            if (cndStyle != null)
                            {
                                var styleTcBorders = cndStyle.Elements(W.tcPr).Elements(W.tcBorders).FirstOrDefault();
                                if (styleTcBorders != null)
                                {
                                    var top = styleTcBorders.Element(W.top);
                                    var left = styleTcBorders.Element(W.left);
                                    var bottom = styleTcBorders.Element(W.bottom);
                                    var right = styleTcBorders.Element(W.right);
                                    insideV = cndStyle.Elements(W.tcPr).Elements(W.tcBorders).Elements(W.insideV).FirstOrDefault();
                                    if (insideV != null)
                                    {
                                        int lastCol = row.Elements(W.tc).Count() - 1;
                                        int colIdx = 0;
                                        foreach (var cell in row.Elements(W.tc))
                                        {
                                            var tcBorders = cell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                                            if (colIdx == 0)
                                            {
                                                ResolveInsideWithExisting(tcBorders, insideV, W.right);
                                            }
                                            else if (colIdx == lastCol)
                                            {
                                                ResolveInsideWithExisting(tcBorders, insideV, W.left);
                                            }
                                            else
                                            {
                                                ResolveInsideWithExisting(tcBorders, insideV, W.left);
                                                ResolveInsideWithExisting(tcBorders, insideV, W.right);
                                            }
                                            colIdx++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            foreach (var attName in new[] { W.oddVBand, W.evenVBand, W.firstColumn, W.lastColumn })
            {
                int rowIdx = 0;
                int lastRow = tbl.Elements(W.tr).Count() - 1;
                foreach (var row in tbl.Elements(W.tr))
                {
                    foreach (var cell in row.Elements(W.tc))
                    {
                        var cellCnfStyle = cell.Elements(W.tcPr).Elements(W.cnfStyle).FirstOrDefault();
                        if (cellCnfStyle != null)
                        {
                            var shouldApply = cellCnfStyle.Attribute(attName).ToBoolean();
                            if (shouldApply == true)
                            {
                                var cndType = TableStyleOverrideXNameRevMap[attName];
                                var cndStyle = style
                                    .Elements(W.tblStylePr)
                                    .FirstOrDefault(tsp => (string)tsp.Attribute(W.type) == cndType);
                                if (cndStyle != null)
                                {
                                    var insideH = cndStyle.Elements(W.tcPr).Elements(W.tcBorders).Elements(W.insideH).FirstOrDefault();
                                    if (insideH != null)
                                    {
                                        var tcBorders = cell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                                        if (rowIdx == 0)
                                        {
                                            ResolveInsideWithExisting(tcBorders, insideH, W.bottom);
                                        }
                                        else if (rowIdx == lastRow)
                                        {
                                            ResolveInsideWithExisting(tcBorders, insideH, W.top);
                                        }
                                        else
                                        {
                                            ResolveInsideWithExisting(tcBorders, insideH, W.bottom);
                                            ResolveInsideWithExisting(tcBorders, insideH, W.top);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    rowIdx++;
                }
            }
        }

        private static void ProcessInnerBordersPerTblBorders(XElement tbl, XElement tblBorders)
        {
            var tblInsideV = tblBorders.Elements(W.insideV).FirstOrDefault();
            if (tblInsideV != null)
            {
                foreach (var row in tbl.Elements(W.tr))
                {
                    var lastCell = row.Elements(W.tc).Count() - 1;
                    int cellIdx = 0;
                    foreach (var cell in row.Elements(W.tc))
                    {
                        var tcPr = cell.Element(PtOpenXml.pt + "tcPr");
                        if (tcPr == null)
                        {
                            tcPr = new XElement(PtOpenXml.pt + "tcPr");
                            cell.Add(tcPr);
                        }
                        var tcBorders = tcPr.Element(W.tcBorders);
                        if (tcBorders == null)
                        {
                            tcBorders = new XElement(W.tcBorders);
                            tcPr.Add(tcBorders);
                        }
                        if (cellIdx == 0)
                        {
                            ResolveInsideWithExisting(tcBorders, tblInsideV, W.right);
                        }
                        else if (cellIdx == lastCell)
                        {
                            ResolveInsideWithExisting(tcBorders, tblInsideV, W.left);
                        }
                        else
                        {
                            ResolveInsideWithExisting(tcBorders, tblInsideV, W.left);
                            ResolveInsideWithExisting(tcBorders, tblInsideV, W.right);
                        }
                        cellIdx++;
                    }
                }
            }
            var tblInsideH = tblBorders.Elements(W.insideH).FirstOrDefault();
            if (tblInsideH != null)
            {
                int rowIdx1 = 0;
                int lastRow1 = tbl.Elements(W.tr).Count() - 1;
                foreach (var row in tbl.Elements(W.tr))
                {
                    if (rowIdx1 == 0)
                    {
                        foreach (var cell in row.Elements(W.tc))
                        {
                            var tcBorders = cell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                            ResolveInsideWithExisting(tcBorders, tblInsideH, W.bottom);
                        }
                    }
                    else if (rowIdx1 == lastRow1)
                    {
                        foreach (var cell in row.Elements(W.tc))
                        {
                            var tcBorders = cell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                            ResolveInsideWithExisting(tcBorders, tblInsideH, W.top);
                        }
                    }
                    else
                    {
                        foreach (var cell in row.Elements(W.tc))
                        {
                            var tcBorders = cell.Elements(PtOpenXml.pt + "tcPr").Elements(W.tcBorders).FirstOrDefault();
                            ResolveInsideWithExisting(tcBorders, tblInsideH, W.top);
                            ResolveInsideWithExisting(tcBorders, tblInsideH, W.bottom);
                        }
                    }
                    rowIdx1++;
                }
            }
        }

        private static void ResolveInsideWithExisting(XElement tcBorders, XElement inside, XName whichSide)
        {
            if (tcBorders.Element(whichSide) != null)
            {
                var newInsideH = ResolveInsideBorder(inside, tcBorders.Element(whichSide));
                tcBorders.Element(whichSide).ReplaceAttributes(
                    newInsideH.Attributes());
            }
            else
            {
                tcBorders.Add(
                    new XElement(whichSide,
                        inside.Attributes()));
            }
        }

        private static Dictionary<string, int> BorderTypePriority = new Dictionary<string, int>()
        {
            { "single", 1 },
            { "thick", 2 },
            { "double", 3 },
            { "dotted", 4 },
        };

        private static Dictionary<string, int> BorderNumber = new Dictionary<string, int>()
        {
            {"single", 1 },
            {"thick", 2 },
            {"double", 3 },
            {"dotted", 4 },
            {"dashed", 5 },
            {"dotDash", 6 },
            {"dotDotDash", 7 },
            {"triple", 8 },
            {"thinThickSmallGap", 9 },
            {"thickThinSmallGap", 10 },
            {"thinThickThinSmallGap", 11 },
            {"thinThickMediumGap", 12 },
            {"thickThinMediumGap", 13 },
            {"thinThickThinMediumGap", 14 },
            {"thinThickLargeGap", 15 },
            {"thickThinLargeGap", 16 },
            {"thinThickThinLargeGap", 17 },
            {"wave", 18 },
            {"doubleWave", 19 },
            {"dashSmallGap", 20 },
            {"dashDotStroked", 21 },
            {"threeDEmboss", 22 },
            {"threeDEngrave", 23 },
            {"outset", 24 },
            {"inset", 25 },
        };

        private static XElement ResolveInsideBorder(XElement inside1, XElement sideToReplace)
        {
            if (inside1 == null && sideToReplace == null)
                return null;
            if (inside1 == null)
                return sideToReplace;
            if (sideToReplace == null)
                return inside1;

            // The following handles the situation where
            // if table innerV is set, and cnd format for first row specifies nill border, then nil border wins.
            // if table innerH is set, and cnd format for first columns specifies nil border, then table innerH wins.
            if (sideToReplace.Name == W.left ||
                sideToReplace.Name == W.right)
            {
                if ((string)inside1.Attribute(W.val) == "nil")
                    return inside1;
                if ((string)sideToReplace.Attribute(W.val) == "nil")
                    return sideToReplace;
            }
            else
            {
                if ((string)inside1.Attribute(W.val) == "nil")
                    return sideToReplace;
                if ((string)sideToReplace.Attribute(W.val) == "nil")
                    return inside1;
            }

            var inside1Val = (string)inside1.Attribute(W.val);
            var border1Weight = 1;
            if (BorderNumber.ContainsKey(inside1Val))
                border1Weight = BorderNumber[inside1Val];

            var sideToReplaceVal = (string)sideToReplace.Attribute(W.val);
            var sideToReplaceWeight = 1;
            if (BorderNumber.ContainsKey(sideToReplaceVal))
                sideToReplaceWeight = BorderNumber[sideToReplaceVal];

            if (border1Weight != sideToReplaceWeight)
            {
                if (border1Weight < sideToReplaceWeight)
                    return sideToReplace;
                else
                    return inside1;
            }

            if ((int)inside1.Attribute(W.sz) > (int)sideToReplace.Attribute(W.sz))
                return inside1;

            if ((int)sideToReplace.Attribute(W.sz) > (int)inside1.Attribute(W.sz))
                return sideToReplace;

            if (BorderTypePriority.ContainsKey(inside1Val) &&
                BorderTypePriority.ContainsKey(sideToReplaceVal))
            {
                var inside1Pri = BorderTypePriority[inside1Val];
                var inside2Pri = BorderTypePriority[sideToReplaceVal];
                if (inside1Pri > inside2Pri)
                    return inside1;
                if (inside2Pri > inside1Pri)
                    return sideToReplace;
            }

            if ((int)inside1.Attribute(W.sz) > (int)sideToReplace.Attribute(W.sz))
                return inside1;

            if ((int)sideToReplace.Attribute(W.sz) > (int)inside1.Attribute(W.sz))
                return sideToReplace;

            var color1str = (string)inside1.Attribute(W.color);
            if (color1str == "auto")
                color1str = "000000";
            var color2str = (string)sideToReplace.Attribute(W.color);
            if (color2str == "auto")
                color2str = "000000";
            if (color1str != null && color2str != null && color1str != color2str)
            {
                Int32 color1;
                Int32 color2;
                try
                {
                    color1 = Convert.ToInt32(color1str, 16);
                }
                // if the above throws ArgumentException, FormatException, or OverflowException, then abort
                catch (Exception) 
                {
                    return sideToReplace;
                }
                try
                {
                    color2 = Convert.ToInt32(color2str, 16);
                }
                // if the above throws ArgumentException, FormatException, or OverflowException, then abort
                catch (Exception)
                {
                    return inside1;
                }
                if (color1 < color2)
                    return inside1;
                if (color2 < color1)
                    return sideToReplace;
                return inside1;
            }
            return inside1;
        }

        private static XElement TableStyleRollup(WordprocessingDocument wDoc, string tblStyleName)
        {
            var tblStyleChain = TableStyleStack(wDoc, tblStyleName)
                .Reverse();
            XElement rolledStyle = new XElement(W.style);
            foreach (var style in tblStyleChain)
            {
                rolledStyle = MergeStyleElement(style, rolledStyle);
            }
            return rolledStyle;
        }

        private static XName[] SpecialCaseChildProperties =
        {
            W.tblPr,
            W.trPr,
            W.tcPr,
            W.pPr,
            W.rPr,
            W.pBdr,
            W.tabs,
            W.rFonts,
            W.ind,
            W.spacing,
            W.tblStylePr,
            W.tcBorders,
            W.tblBorders,
            W.lang,
            W.numPr,
        };

        private static XName[] MergeChildProperties =
        {
            W.tblPr,
            W.trPr,
            W.tcPr,
            W.pPr,
            W.rPr,
            W.pBdr,
            W.tcBorders,
            W.tblBorders,
            W.numPr,
        };

        private static string[] TableStyleOverrideTypes =
        {
            "band1Vert",
            "band2Vert",
            "band1Horz",
            "band2Horz",
            "firstCol",
            "lastCol",
            "firstRow",
            "lastRow",
            "neCell",
            "nwCell",
            "seCell",
            "swCell",
        };

        private static Dictionary<string, XName> TableStyleOverrideXNameMap = new Dictionary<string, XName>
        {
            {"band1Vert", W.oddVBand},
            {"band2Vert", W.evenVBand},
            {"band1Horz", W.oddHBand},
            {"band2Horz", W.evenHBand},
            {"firstCol", W.firstColumn},
            {"lastCol", W.lastColumn},
            {"firstRow", W.firstRow},
            {"lastRow", W.lastRow},
            {"neCell", W.firstRowLastColumn},
            {"nwCell", W.firstRowFirstColumn},
            {"seCell", W.lastRowLastColumn},
            {"swCell", W.lastRowFirstColumn},
        };

        private static Dictionary<XName, string> TableStyleOverrideXNameRevMap = new Dictionary<XName, string>
        {
            {W.oddVBand, "band1Vert"},
            {W.evenVBand, "band2Vert"},
            {W.oddHBand, "band1Horz"},
            {W.evenHBand, "band2Horz"},
            {W.firstColumn, "firstCol"},
            {W.lastColumn, "lastCol"},
            {W.firstRow, "firstRow"},
            {W.lastRow, "lastRow"},
        };

        private static XElement MergeStyleElement(XElement higherPriorityElement, XElement lowerPriorityElement)
        {
            return MergeStyleElement(higherPriorityElement, lowerPriorityElement, null);
        }

        private static XElement MergeStyleElement(XElement higherPriorityElement, XElement lowerPriorityElement, bool? highPriIsDirectFormatting)
        {
            // If, when in the process of merging, the source element doesn't have a
            // corresponding element in the merged element, then include the source element
            // in the merged element.
            if (lowerPriorityElement == null)
                return higherPriorityElement;
            if (higherPriorityElement == null)
                return lowerPriorityElement;

            var hpe = higherPriorityElement
                .Elements()
                .Where(e => !SpecialCaseChildProperties.Contains(e.Name))
                .ToArray();
            if (highPriIsDirectFormatting == true)
            {
                hpe = hpe
                    .Select(e =>
                        new XElement(e.Name,
                            e.Attributes(),
                            new XAttribute(PtOpenXml.pt + "fromDirect", true),
                            e.Elements()))
                    .ToArray();
            }
            var lpe = lowerPriorityElement
                .Elements()
                .Where(e => !SpecialCaseChildProperties.Contains(e.Name) && !hpe.Select(z => z.Name).Contains(e.Name))
                .ToArray();
            var ma = SpacingMerge(higherPriorityElement.Element(W.spacing), lowerPriorityElement.Element(W.spacing));
            var rFonts = FontMerge(higherPriorityElement.Element(W.rFonts), lowerPriorityElement.Element(W.rFonts));
            var tabs = TabsMerge(higherPriorityElement.Element(W.tabs), lowerPriorityElement.Element(W.tabs));
            var ind = IndMerge(higherPriorityElement.Element(W.ind), lowerPriorityElement.Element(W.ind));
            var lang = LangMerge(higherPriorityElement.Element(W.lang), lowerPriorityElement.Element(W.lang));
            var mcp = MergeChildProperties
                .Select(e =>
                {
                    // test is here to prevent unnecessary recursion to make debugging easier
                    var h = higherPriorityElement.Element(e);
                    var l = lowerPriorityElement.Element(e);
                    if (h == null && l == null)
                        return null;
                    if (h == null && l != null)
                        return l;
                    if (h != null && l == null)
                    {
                        var newH = new XElement(h.Name,
                            h.Attributes(),
                            highPriIsDirectFormatting == true ? new XAttribute(PtOpenXml.pt + "fromDirect", true) : null,
                            h.Elements());
                        return newH;
                    }
                    return MergeStyleElement(h, l, highPriIsDirectFormatting);
                })
                .Where(m => m != null)
                .ToArray();
            var tsor = TableStyleOverrideTypes
                .Select(e =>
                {
                    // test is here to prevent unnecessary recursion to make debugging easier
                    var h = higherPriorityElement.Elements(W.tblStylePr).FirstOrDefault(tsp => (string)tsp.Attribute(W.type) == e);
                    var l = lowerPriorityElement.Elements(W.tblStylePr).FirstOrDefault(tsp => (string)tsp.Attribute(W.type) == e);
                    if (h == null && l == null)
                        return null;
                    if (h == null && l != null)
                        return l;
                    if (h != null && l == null)
                        return h;
                    return MergeStyleElement(h, l);
                })
                .Where(m => m != null)
                .ToArray();

            XElement newMergedElement = new XElement(higherPriorityElement.Name,
                new XAttribute(XNamespace.Xmlns + "w", W.w),
                higherPriorityElement.Attributes().Where(a => !a.IsNamespaceDeclaration),
                hpe,  // higher priority elements
                lpe,  // lower priority elements where there is not a higher priority element of same name
                ind,  // w:ind has very special rules
                ma,   // elements that require merged attributes
                lang,
                rFonts,  // font merge is special case
                tabs,    // tabs merge is special case
                mcp,  // elements that need child properties to be merged
                tsor // merged table style override elements
            );

            return newMergedElement;
        }

        private static XElement LangMerge(XElement hLang, XElement lLang)
        {
            if (hLang == null && lLang == null)
                return null;
            if (hLang != null && lLang == null)
                return hLang;
            if (lLang != null && hLang == null)
                return lLang;
            return new XElement(W.lang,
                hLang.Attribute(W.val) != null ? hLang.Attribute(W.val) : lLang.Attribute(W.val),
                hLang.Attribute(W.bidi) != null ? hLang.Attribute(W.bidi) : lLang.Attribute(W.bidi),
                hLang.Attribute(W.eastAsia) != null ? hLang.Attribute(W.eastAsia) : lLang.Attribute(W.eastAsia));
        }

        private enum IndAttType
        {
            End,
            FirstLineOrHanging,
            Start,
            Left,
            Right,
            None,
        };

        private static XElement IndMerge(XElement higherPriorityElement, XElement lowerPriorityElement)
        {
            if (higherPriorityElement == null && lowerPriorityElement == null)
                return null;
            if (higherPriorityElement != null && lowerPriorityElement == null)
                return higherPriorityElement;
            if (lowerPriorityElement != null && higherPriorityElement == null)
                return lowerPriorityElement;

            XElement hpe = new XElement(higherPriorityElement);
            XElement lpe = new XElement(lowerPriorityElement);

            if (hpe.Attribute(W.firstLine) != null)
                lpe.Attributes(W.hanging).Remove();

            if (hpe.Attribute(W.firstLineChars) != null)
                lpe.Attributes(W.hangingChars).Remove();

            if (hpe.Attribute(W.hanging) != null)
                lpe.Attributes(W.firstLine).Remove();

            if (hpe.Attribute(W.hangingChars) != null)
                lpe.Attributes(W.firstLineChars).Remove();

            var highPriAtts = hpe
                .Attributes()
                .Where(a => !a.IsNamespaceDeclaration)
                .ToList();

            var highPriAttNames = highPriAtts
                .Select(a => a.Name);

            var lowPriAtts = lpe
                .Attributes()
                .Where(a => !a.IsNamespaceDeclaration)
                .Where(a => !highPriAttNames.Contains(a.Name))
                .ToList();

            var mergedElement = new XElement(higherPriorityElement.Name,
                highPriAtts,
                lowPriAtts);

            return mergedElement;
        }

        // merge child tab elements
        // they are additive, with the exception that if there are two elements at the same location,
        // we need to take the higher, and not take the lower.
        private static XElement TabsMerge(XElement higherPriorityElement, XElement lowerPriorityElement)
        {
            if (higherPriorityElement != null && lowerPriorityElement == null)
                return higherPriorityElement;
            if (higherPriorityElement == null && lowerPriorityElement != null)
                return lowerPriorityElement;
            if (higherPriorityElement == null && lowerPriorityElement == null)
                return null;
            var hps = higherPriorityElement.Elements().Select(e =>
                new
                {
                    Pos = (int)e.Attribute(W.pos),
                    Pri = 1,
                    Element = e,
                }
            );
            var lps = lowerPriorityElement.Elements().Select(e =>
                new
                {
                    Pos = (int)e.Attribute(W.pos),
                    Pri = 2,
                    Element = e,
                }
            );
            var newTabElements = hps.Concat(lps)
                .GroupBy(s => s.Pos)
                .Select(g => g.OrderBy(s => s.Pri).First().Element)
                .Where(e => (string)e.Attribute(W.val) != "clear")
                .OrderBy(e => (int)e.Attribute(W.pos));
            var newTabs = new XElement(W.tabs, newTabElements);
            return newTabs;
        }

        private static XElement SpacingMerge(XElement hn, XElement ln)
        {
            if (hn == null && ln == null)
                return null;
            if (hn != null && ln == null)
                return hn;
            if (hn == null && ln != null)
                return ln;
            var mn1 = new XElement(W.spacing,
                hn.Attributes(),
                ln.Attributes().Where(a => hn.Attribute(a.Name) == null));
            return mn1;
        }

        private static IEnumerable<XElement> TableStyleStack(WordprocessingDocument wDoc, string tblStyleName)
        {
            XDocument sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
            string currentStyle = tblStyleName;
            while (true)
            {
                XElement style = sXDoc
                    .Root
                    .Elements(W.style).Where(s => (string)s.Attribute(W.type) == "table" &&
                        (string)s.Attribute(W.styleId) == currentStyle)
                    .FirstOrDefault();
                if (style == null)
                    yield break;
                yield return style;
                currentStyle = (string)style.Elements(W.basedOn).Attributes(W.val).FirstOrDefault();
                if (currentStyle == null)
                    yield break;
            }
        }

        private static XElement FontMerge(XElement higherPriorityFont, XElement lowerPriorityFont)
        {
            XElement rFonts;

            if (higherPriorityFont == null)
                return lowerPriorityFont;
            if (lowerPriorityFont == null)
                return higherPriorityFont;
            if (higherPriorityFont == null && lowerPriorityFont == null)
                return null;

            rFonts = new XElement(W.rFonts,
                (higherPriorityFont.Attribute(W.ascii) != null || higherPriorityFont.Attribute(W.asciiTheme) != null) ?
                    new[] { higherPriorityFont.Attribute(W.ascii), higherPriorityFont.Attribute(W.asciiTheme) } :
                    new[] { lowerPriorityFont.Attribute(W.ascii), lowerPriorityFont.Attribute(W.asciiTheme) },
                (higherPriorityFont.Attribute(W.hAnsi) != null || higherPriorityFont.Attribute(W.hAnsiTheme) != null) ?
                    new[] { higherPriorityFont.Attribute(W.hAnsi), higherPriorityFont.Attribute(W.hAnsiTheme) } :
                    new[] { lowerPriorityFont.Attribute(W.hAnsi), lowerPriorityFont.Attribute(W.hAnsiTheme) },
                (higherPriorityFont.Attribute(W.eastAsia) != null || higherPriorityFont.Attribute(W.eastAsiaTheme) != null) ?
                    new[] { higherPriorityFont.Attribute(W.eastAsia), higherPriorityFont.Attribute(W.eastAsiaTheme) } :
                    new[] { lowerPriorityFont.Attribute(W.eastAsia), lowerPriorityFont.Attribute(W.eastAsiaTheme) },
                (higherPriorityFont.Attribute(W.cs) != null || higherPriorityFont.Attribute(W.cstheme) != null) ?
                    new[] { higherPriorityFont.Attribute(W.cs), higherPriorityFont.Attribute(W.cstheme) } :
                    new[] { lowerPriorityFont.Attribute(W.cs), lowerPriorityFont.Attribute(W.cstheme) },
                (higherPriorityFont.Attribute(W.hint) != null ? higherPriorityFont.Attribute(W.hint) :
                    lowerPriorityFont.Attribute(W.hint))
            );

            return rFonts;
        }

        private static void AnnotateParagraphs(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement root, FormattingAssemblerSettings settings)
        {
            foreach (var para in root.Descendants(W.p))
            {
                AnnotateParagraph(fai, wDoc, para, settings);
            }
        }

        private static void AnnotateParagraph(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement para, FormattingAssemblerSettings settings)
        {
            XElement localParaProps = para.Element(W.pPr);
            if (localParaProps == null)
            {
                localParaProps = new XElement(W.pPr);
            }

            // get para table props, to be merged.
            XElement tablepPr = null;

            var blockLevelContentContainer = para
                .Ancestors()
                .FirstOrDefault(a => a.Name == W.body ||
                    a.Name == W.tbl ||
                    a.Name == W.txbxContent ||
                    a.Name == W.ftr ||
                    a.Name == W.hdr ||
                    a.Name == W.footnote ||
                    a.Name == W.endnote);
            if (blockLevelContentContainer.Name == W.tbl)
            {
                XElement tbl = blockLevelContentContainer;
                XElement style = tbl.Element(PtOpenXml.pt + "style");
                XElement cellCnf = para.Ancestors(W.tc).Take(1).Elements(W.tcPr).Elements(W.cnfStyle).FirstOrDefault();
                XElement rowCnf = para.Ancestors(W.tr).Take(1).Elements(W.trPr).Elements(W.cnfStyle).FirstOrDefault();

                if (style != null)
                {
                    // roll up tblPr, trPr, and tcPr from within a specific style.
                    // add each of these to the table, in PowerTools namespace.
                    tablepPr = style.Element(W.pPr);
                    if (tablepPr == null)
                        tablepPr = new XElement(W.pPr);

                    foreach (var ot in TableStyleOverrideTypes)
                    {
                        XName attName = TableStyleOverrideXNameMap[ot];
                        if ((cellCnf != null && cellCnf.Attribute(attName).ToBoolean() == true) ||
                            (rowCnf != null && rowCnf.Attribute(attName).ToBoolean() == true))
                        {
                            XElement o = style
                                .Elements(W.tblStylePr)
                                .Where(tsp => (string)tsp.Attribute(W.type) == ot)
                                .FirstOrDefault();
                            if (o != null)
                            {
                                XElement otpPr = o.Element(W.pPr);
                                tablepPr = MergeStyleElement(otpPr, tablepPr);
                            }
                        }
                    }
                }
            }
            var stylesPart = wDoc.MainDocumentPart.StyleDefinitionsPart;
            XDocument sXDoc = null;
            if (stylesPart != null)
                sXDoc = stylesPart.GetXDocument();

            ListItemRetriever.ListItemInfo lif = para.Annotation<ListItemRetriever.ListItemInfo>();

            XElement rolledParaProps = ParagraphStyleRollup(para, sXDoc, fai.DefaultParagraphStyleName);
            if (lif != null && lif.IsZeroNumId)
                rolledParaProps.Elements(W.ind).Remove();
            XElement toggledParaProps = MergeStyleElement(rolledParaProps, tablepPr);
            XElement mergedParaProps = MergeStyleElement(localParaProps, toggledParaProps);

            string li = ListItemRetriever.RetrieveListItem(wDoc, para, settings.ListItemRetrieverSettings);
            if (lif != null && lif.IsListItem)
            {
                if (settings.RestrictToSupportedNumberingFormats)
                {
                    string numFmtForLevel = (string)lif.Lvl(ListItemRetriever.GetParagraphLevel(para)).Elements(W.numFmt).Attributes(W.val).FirstOrDefault();
                    if (numFmtForLevel == null)
                    {
                        var numFmtElement = lif.Lvl(ListItemRetriever.GetParagraphLevel(para)).Elements(MC.AlternateContent).Elements(MC.Choice).Elements(W.numFmt).FirstOrDefault();
                        if (numFmtElement != null && (string)numFmtElement.Attribute(W.val) == "custom")
                            numFmtForLevel = (string)numFmtElement.Attribute(W.format);
                    }
                    bool isLgl = lif.Lvl(ListItemRetriever.GetParagraphLevel(para)).Elements(W.isLgl).Any();
                    if (isLgl && numFmtForLevel != "decimalZero")
                        numFmtForLevel = "decimal";
                    if (!AcceptableNumFormats.Contains(numFmtForLevel))
                        throw new UnsupportedNumberingFormatException(numFmtForLevel + " is not a supported numbering format");
                }

                int paragraphLevel = ListItemRetriever.GetParagraphLevel(para);
                var numberingParaProps = lif
                    .Lvl(paragraphLevel)
                    .Elements(W.pPr)
                    .FirstOrDefault();
                if (numberingParaProps == null)
                {
                    numberingParaProps = new XElement(W.pPr);
                }
                else
                {
                    numberingParaProps
                        .Elements()
                        .Where(e => e.Name != W.ind)
                        .Remove();
                }

                // have:
                // - localParaProps
                // - toggledParaProps
                // - numberingParaProps

                // if a paragraph contains a numPr with a numId=0, in other words, it is NOT a numbered item, then the indentation from the style
                // hierarchy is ignored.

                ListItemRetriever.ListItemInfo lii = para.Annotation<ListItemRetriever.ListItemInfo>();
                if (lii.FromParagraph != null)
                {
                    // order
                    // - toggledParaProps
                    // - numberingParaProps
                    // - localParaProps

                    mergedParaProps = MergeStyleElement(numberingParaProps, toggledParaProps);
                    mergedParaProps = MergeStyleElement(localParaProps, mergedParaProps);
                }
                else if (lii.FromStyle != null)
                {
                    // order
                    // - numberingParaProps
                    // - toggledParaProps
                    // - localParaProps
                    mergedParaProps = MergeStyleElement(toggledParaProps, numberingParaProps);
                    mergedParaProps = MergeStyleElement(localParaProps, mergedParaProps);
                }
            }
            else
            {
                mergedParaProps = MergeStyleElement(localParaProps, toggledParaProps);
            }

            // merge mergedParaProps with existing accumulatedParaProps, with mergedParaProps as high pri
            // replace accumulatedParaProps with newly merged

            XElement accumulatedParaProps = para.Element(PtOpenXml.pt + "pPr");
            XElement newAccumulatedParaProps = MergeStyleElement(mergedParaProps, accumulatedParaProps);

            AdjustFontAttributes(wDoc, para, newAccumulatedParaProps, newAccumulatedParaProps.Element(W.rPr), settings);
            newAccumulatedParaProps.Name = PtOpenXml.pt + "pPr";
            if (accumulatedParaProps != null)
            {
                accumulatedParaProps.ReplaceWith(newAccumulatedParaProps);
            }
            else
            {
                para.Add(newAccumulatedParaProps);
            }
        }

        private static string[] AcceptableNumFormats = new[] {
            "decimal",
            "decimalZero",
            "upperRoman",
            "lowerRoman",
            "upperLetter",
            "lowerLetter",
            "ordinal",
            "cardinalText",
            "ordinalText",
            "bullet",
            "0001, 0002, 0003, ...",
            "none",
        };

        public static XElement ParagraphStyleRollup(XElement paragraph, XDocument stylesXDoc, string defaultParagraphStyleName)
        {
            var paraStyle = (string)paragraph
                .Elements(W.pPr)
                .Elements(W.pStyle)
                .Attributes(W.val)
                .FirstOrDefault();
            if (paraStyle == null)
                paraStyle = defaultParagraphStyleName;
            var rolledUpParaStyleParaProps = new XElement(W.pPr);
            if (stylesXDoc == null)
                return rolledUpParaStyleParaProps;
            if (paraStyle != null)
            {
                rolledUpParaStyleParaProps = ParaStyleParaPropsStack(stylesXDoc, paraStyle, paragraph)
                    .Reverse()
                    .Aggregate(new XElement(W.pPr),
                        (r, s) =>
                        {
                            var newParaProps = MergeStyleElement(s, r);
                            return newParaProps;
                        });
            }
            return rolledUpParaStyleParaProps;
        }

        private static IEnumerable<XElement> ParaStyleParaPropsStack(XDocument stylesXDoc, string paraStyleName, XElement para)
        {
            if (stylesXDoc == null)
                yield break;
            var localParaStyleName = paraStyleName;
            while (localParaStyleName != null)
            {
                XElement paraStyle = stylesXDoc.Root.Elements(W.style).FirstOrDefault(s =>
                    s.Attribute(W.type).Value == "paragraph" &&
                    s.Attribute(W.styleId).Value == localParaStyleName);
                if (paraStyle == null)
                {
                    yield break;
                }
                if (paraStyle.Element(W.pPr) == null)
                {
                    if (paraStyle.Element(W.rPr) != null)
                    {
                        var elementToYield2 = new XElement(W.pPr,
                            paraStyle.Element(W.rPr));
                        yield return elementToYield2;
                    }
                    localParaStyleName = (string)(paraStyle
                        .Elements(W.basedOn)
                        .Attributes(W.val)
                        .FirstOrDefault());
                    continue;
                }

                var elementToYield = new XElement(W.pPr,
                    paraStyle.Element(W.pPr).Attributes(),
                    paraStyle.Element(W.pPr).Elements(),
                    paraStyle.Element(W.rPr));
                yield return (elementToYield);

                var listItemInfo = para.Annotation<ListItemRetriever.ListItemInfo>();
                if (listItemInfo != null)
                {
                    if (listItemInfo.IsListItem)
                    {
                        XElement lipPr = listItemInfo.Lvl(ListItemRetriever.GetParagraphLevel(para)).Element(W.pPr);
                        if (lipPr == null)
                            lipPr = new XElement(W.pPr);
                        XElement lirPr = listItemInfo.Lvl(ListItemRetriever.GetParagraphLevel(para)).Element(W.rPr);
                        var elementToYield2 = new XElement(W.pPr,
                            lipPr.Attributes(),
                            lipPr.Elements(),
                            lirPr);
                        yield return (elementToYield2);
                    }
                }

                localParaStyleName = (string)paraStyle
                    .Elements(W.basedOn)
                    .Attributes(W.val)
                    .FirstOrDefault();
            }
            yield break;
        }

        private static void AnnotateRuns(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement root, FormattingAssemblerSettings settings)
        {
            var runsOrParas = root.Descendants()
                .Where(rp =>
                {
                    return rp.Name == W.r || rp.Name == W.p;
                });
            foreach (var runOrPara in runsOrParas)
            {
                AnnotateRunProperties(fai, wDoc, runOrPara, settings);
            }
        }

        private static void AnnotateRunProperties(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement runOrPara, FormattingAssemblerSettings settings)
        {
            XElement localRunProps = null;
            if (runOrPara.Name == W.p)
            {
                var rPr = runOrPara.Elements(W.pPr).Elements(W.rPr).FirstOrDefault();
                if (rPr != null)
                {
                    localRunProps = rPr;
                }
            }
            else
            {
                localRunProps = runOrPara.Element(W.rPr);
            }
            if (localRunProps == null)
            {
                localRunProps = new XElement(W.rPr);
            }

            // get run table props, to be merged.
            XElement tablerPr = null;
            var blockLevelContentContainer = runOrPara
                .Ancestors()
                .FirstOrDefault(a => a.Name == W.body ||
                    a.Name == W.tbl ||
                    a.Name == W.txbxContent ||
                    a.Name == W.ftr ||
                    a.Name == W.hdr ||
                    a.Name == W.footnote ||
                    a.Name == W.endnote);
            if (blockLevelContentContainer.Name == W.tbl)
            {
                XElement tbl = blockLevelContentContainer;
                XElement style = tbl.Element(PtOpenXml.pt + "style");
                XElement cellCnf = runOrPara.Ancestors(W.tc).Take(1).Elements(W.tcPr).Elements(W.cnfStyle).FirstOrDefault();
                XElement rowCnf = runOrPara.Ancestors(W.tr).Take(1).Elements(W.trPr).Elements(W.cnfStyle).FirstOrDefault();

                if (style != null)
                {
                    tablerPr = style.Element(W.rPr);
                    if (tablerPr == null)
                        tablerPr = new XElement(W.rPr);

                    foreach (var ot in TableStyleOverrideTypes)
                    {
                        XName attName = TableStyleOverrideXNameMap[ot];
                        if ((cellCnf != null && cellCnf.Attribute(attName).ToBoolean() == true) ||
                            (rowCnf != null && rowCnf.Attribute(attName).ToBoolean() == true))
                        {
                            XElement o = style
                                .Elements(W.tblStylePr)
                                .Where(tsp => (string)tsp.Attribute(W.type) == ot)
                                .FirstOrDefault();
                            if (o != null)
                            {
                                XElement otrPr = o.Element(W.rPr);
                                tablerPr = MergeStyleElement(otrPr, tablerPr);
                            }
                        }
                    }
                }
            }
            XElement rolledRunProps = CharStyleRollup(fai, wDoc, runOrPara);
            var toggledRunProps = ToggleMergeRunProps(rolledRunProps, tablerPr);
            var currentRunProps = runOrPara.Element(PtOpenXml.rPr); // this is already stored on the run from previous aggregation of props
            var mergedRunProps = MergeStyleElement(toggledRunProps, currentRunProps);
            var newMergedRunProps = MergeStyleElement(localRunProps, mergedRunProps);
            XElement pPr = null;
            if (runOrPara.Name == W.p)
                pPr = runOrPara.Element(PtOpenXml.pPr);
            AdjustFontAttributes(wDoc, runOrPara, pPr, newMergedRunProps, settings);

            newMergedRunProps.Name = PtOpenXml.rPr;
            if (currentRunProps != null)
            {
                currentRunProps.ReplaceWith(newMergedRunProps);
            }
            else
            {
                runOrPara.Add(newMergedRunProps);
            }
        }

        private static XElement CharStyleRollup(FormattingAssemblerInfo fai, WordprocessingDocument wDoc, XElement runOrPara)
        {
            var sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();

            string charStyle = null;
            string paraStyle = null;
            XElement rPr = null;
            XElement pPr = null;
            XElement pStyle = null;
            XElement rStyle = null;
            CachedParaInfo cpi = null; // CachedParaInfo is an optimization for the case where a paragraph contains thousands of runs.

            if (runOrPara.Name == W.p)
            {
                cpi = runOrPara.Annotation<CachedParaInfo>();
                if (cpi != null)
                    pPr = cpi.ParagraphProperties;
                else
                {
                    pPr = runOrPara.Element(W.pPr);
                    if (pPr != null)
                    {
                        paraStyle = (string)pPr.Elements(W.pStyle).Attributes(W.val).FirstOrDefault();
                    }
                    else
                    {
                        paraStyle = fai.DefaultParagraphStyleName;
                    }
                    cpi = new CachedParaInfo
                    {
                        ParagraphProperties = pPr,
                        ParagraphStyleName = paraStyle,
                    };
                    runOrPara.AddAnnotation(cpi);
                }
                if (pPr != null)
                {
                    rPr = pPr.Element(W.rPr);
                }
            }
            else
            {
                rPr = runOrPara.Element(W.rPr);
            }
            if (rPr != null)
            {
                rStyle = rPr.Element(W.rStyle);
                if (rStyle != null)
                {
                    charStyle = (string)rStyle.Attribute(W.val);
                }
                else
                {
                    if (runOrPara.Name == W.r)
                        charStyle = (string)runOrPara
                            .Ancestors(W.p)
                            .Take(1)
                            .Elements(W.pPr)
                            .Elements(W.pStyle)
                            .Attributes(W.val)
                            .FirstOrDefault();
                    else
                        charStyle = (string)runOrPara
                            .Elements(W.pPr)
                            .Elements(W.pStyle)
                            .Attributes(W.val)
                            .FirstOrDefault();
                }
            }

            if (charStyle == null)
            {
                if (runOrPara.Name == W.r)
                {
                    var ancestorPara = runOrPara.Ancestors(W.p).First();
                    cpi = ancestorPara.Annotation<CachedParaInfo>();
                    if (cpi != null)
                        charStyle = cpi.ParagraphStyleName;
                    else
                        charStyle = (string)runOrPara.Ancestors(W.p).First().Elements(W.pPr).Elements(W.pStyle).Attributes(W.val).FirstOrDefault();
                }
                if (charStyle == null)
                {
                    charStyle = fai.DefaultParagraphStyleName;
                }
            }

            // A run always must have an ancestor paragraph.
            XElement para = null;
            var rolledUpParaStyleRunProps = new XElement(W.rPr);
            if (runOrPara.Name == W.r)
            {
                para = runOrPara.Ancestors(W.p).FirstOrDefault();
            }
            else
            {
                para = runOrPara;
            }

            cpi = para.Annotation<CachedParaInfo>();
            if (cpi != null)
            {
                pPr = cpi.ParagraphProperties;
            }
            else
            {
                pPr = para.Element(W.pPr);
            }
            if (pPr != null)
            {
                pStyle = pPr.Element(W.pStyle);
                if (pStyle != null)
                {
                    paraStyle = (string)pStyle.Attribute(W.val);
                }
                else
                {
                    paraStyle = fai.DefaultParagraphStyleName;
                }
            }
            else
                paraStyle = fai.DefaultParagraphStyleName;

            string key = (paraStyle == null ? "[null]" : paraStyle) + "~|~" +
                (charStyle == null ? "[null]" : charStyle);
            XElement rolledRunProps = null;

            if (fai.RolledCharacterStyles.ContainsKey(key))
                rolledRunProps = fai.RolledCharacterStyles[key];
            else
            {
                XElement rolledUpCharStyleRunProps = new XElement(W.rPr);
                if (charStyle != null)
                {
                    rolledUpCharStyleRunProps =
                        CharStyleStack(wDoc, charStyle)
                            .Aggregate(new XElement(W.rPr),
                                (r, s) =>
                                {
                                    var newRunProps = MergeStyleElement(s, r);
                                    return newRunProps;
                                });
                }

                if (paraStyle != null)
                {
                    rolledUpParaStyleRunProps = ParaStyleRunPropsStack(wDoc, paraStyle)
                        .Aggregate(new XElement(W.rPr),
                            (r, s) =>
                            {
                                var newCharStyleRunProps = MergeStyleElement(s, r);
                                return newCharStyleRunProps;
                            });
                }
                rolledRunProps = MergeStyleElement(rolledUpCharStyleRunProps, rolledUpParaStyleRunProps);
                fai.RolledCharacterStyles.Add(key, rolledRunProps);
            }

            return rolledRunProps;
        }

        private static IEnumerable<XElement> ParaStyleRunPropsStack(WordprocessingDocument wDoc, string paraStyleName)
        {
            var localParaStyleName = paraStyleName;
            var sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
            var rValue = new Stack<XElement>();
            while (localParaStyleName != null)
            {
                var paraStyle = sXDoc.Root.Elements(W.style).FirstOrDefault(s =>
                {
                    return (string)s.Attribute(W.type) == "paragraph" &&
                        (string)s.Attribute(W.styleId) == localParaStyleName;
                });
                if (paraStyle == null)
                {
                    return rValue;
                }
                if (paraStyle.Element(W.rPr) != null)
                {
                    rValue.Push(paraStyle.Element(W.rPr));
                }
                localParaStyleName = (string)paraStyle
                    .Elements(W.basedOn)
                    .Attributes(W.val)
                    .FirstOrDefault();
            }
            return rValue;
        }

        // returns collection of run properties
        private static IEnumerable<XElement> CharStyleStack(WordprocessingDocument wDoc, string charStyleName)
        {
            var localCharStyleName = charStyleName;
            var sXDoc = wDoc.MainDocumentPart.StyleDefinitionsPart.GetXDocument();
            var rValue = new Stack<XElement>();
            while (localCharStyleName != null)
            {
                XElement basedOn = null;
                // first look for character style
                var charStyle = sXDoc.Root.Elements(W.style).FirstOrDefault(s =>
                {
                    return (string)s.Attribute(W.type) == "character" &&
                        (string)s.Attribute(W.styleId) == localCharStyleName;
                });
                // if not found, look for paragraph style
                if (charStyle == null)
                {
                    charStyle = sXDoc.Root.Elements(W.style).FirstOrDefault(s =>
                    {
                        return (string)s.Attribute(W.styleId) == localCharStyleName;
                    });
                }
                if (charStyle == null)
                {
                    return rValue;
                }
                if (charStyle.Element(W.rPr) == null)
                {
                    basedOn = charStyle.Element(W.basedOn);
                    if (basedOn != null)
                    {
                        localCharStyleName = (string)basedOn.Attribute(W.val);
                    }
                    else
                    {
                        return rValue;
                    }
                }
                rValue.Push(charStyle.Element(W.rPr));
                localCharStyleName = null;
                basedOn = charStyle.Element(W.basedOn);
                if (basedOn != null)
                {
                    localCharStyleName = (string)basedOn.Attribute(W.val);
                }
            }
            return rValue;
        }

        private static XElement ToggleMergeRunProps(XElement higherPriorityElement, XElement lowerPriorityElement)
        {
            if (lowerPriorityElement == null)
                return higherPriorityElement;
            if (higherPriorityElement == null)
                return lowerPriorityElement;

            var hpe = higherPriorityElement.Elements().Select(e => e.Name).ToArray();

            var newMergedElement = new XElement(higherPriorityElement.Name,
                higherPriorityElement.Attributes(),

                // process toggle properties
                higherPriorityElement.Elements()
                    .Where(e => { return e.Name != W.rFonts; })
                    .Select(higherChildElement =>
                    {
                        if (TogglePropertyNames.Contains(higherChildElement.Name))
                        {
                            var lowerChildElement = lowerPriorityElement.Element(higherChildElement.Name);
                            if (lowerChildElement == null)
                            {
                                return higherChildElement;
                            }

                            var bHigher = higherChildElement.Attribute(W.val) == null || higherChildElement.Attribute(W.val).ToBoolean() == true;

                            var bLower = lowerChildElement.Attribute(W.val) == null || lowerChildElement.Attribute(W.val).ToBoolean() == true;

                            // if higher is true and lower is false, then return true element
                            if (bHigher && !bLower)
                            {
                                return higherChildElement;
                            }

                            // if higher is false and lower is true, then return false element
                            if (!bHigher && bLower)
                            {
                                return higherChildElement;
                            }

                            // if higher and lower are both true, then return false
                            if (bHigher && bLower)
                            {
                                return new XElement(higherChildElement.Name,
                                    new XAttribute(W.val, "0"));
                            }

                            // otherwise, both higher and lower are false so can return higher element.
                            return higherChildElement;
                        }
                        return higherChildElement;
                    }),

                    FontMerge(higherPriorityElement.Element(W.rFonts), lowerPriorityElement.Element(W.rFonts)),

                    // take lower priority elements where there is not a higher priority element of same name
                    lowerPriorityElement.Elements()
                        .Where(e =>
                        {
                            return e.Name != W.rFonts && !hpe.Contains(e.Name);
                        }));

            return newMergedElement;
        }

        private static XName[] TogglePropertyNames = new[] {
            W.b,
            W.bCs,
            W.caps,
            W.emboss,
            W.i,
            W.iCs,
            W.imprint,
            W.outline,
            W.shadow,
            W.smallCaps,
            W.strike,
            W.vanish
        };

        private static XName[] PropertyNames = new[] {
            W.cs,
            W.rtl,
            W.u,
            W.color,
            W.highlight,
            W.shd
        };

        public class CharStyleAttributes
        {
            public string AsciiFont;
            public string HAnsiFont;
            public string EastAsiaFont;
            public string CsFont;
            public string Hint;
            public bool Rtl;

            public string LatinLang;
            public string BidiLang;
            public string EastAsiaLang;

            public Dictionary<XName, bool?> ToggleProperties;
            public Dictionary<XName, XElement> Properties;

            public CharStyleAttributes(XElement pPr, XElement rPr)
            {
                ToggleProperties = new Dictionary<XName, bool?>();
                Properties = new Dictionary<XName, XElement>();

                if (rPr == null)
                    return;
                foreach (XName xn in TogglePropertyNames)
                {
                    ToggleProperties[xn] = GetBoolProperty(rPr, xn);
                }
                foreach (XName xn in PropertyNames)
                {
                    Properties[xn] = GetXmlProperty(rPr, xn);
                }
                var rFonts = rPr.Element(W.rFonts);
                if (rFonts == null)
                {
                    this.AsciiFont = null;
                    this.HAnsiFont = null;
                    this.EastAsiaFont = null;
                    this.CsFont = null;
                    this.Hint = null;
                }
                else
                {
                    this.AsciiFont = (string)(rFonts.Attribute(W.ascii));
                    this.HAnsiFont = (string)(rFonts.Attribute(W.hAnsi));
                    this.EastAsiaFont = (string)(rFonts.Attribute(W.eastAsia));
                    this.CsFont = (string)(rFonts.Attribute(W.cs));
                    this.Hint = (string)(rFonts.Attribute(W.hint));
                }
                XElement csel = this.Properties[W.cs];
                bool cs = csel != null && (csel.Attribute(W.val) == null || csel.Attribute(W.val).ToBoolean() == true);
                XElement rtlel = this.Properties[W.rtl];
                bool rtl = rtlel != null && (rtlel.Attribute(W.val) == null || rtlel.Attribute(W.val).ToBoolean() == true);
                var bidi = false;
                if (pPr != null)
                {
                    XElement bidiel = pPr.Element(W.bidi);
                    bidi = bidiel != null && (bidiel.Attribute(W.val) == null || bidiel.Attribute(W.val).ToBoolean() == true);
                }
                Rtl = cs || rtl || bidi;
                var lang = rPr.Element(W.lang);
                if (lang != null)
                {
                    LatinLang = (string)lang.Attribute(W.val);
                    BidiLang = (string)lang.Attribute(W.bidi);
                    EastAsiaLang = (string)lang.Attribute(W.eastAsia);
                }
            }

            private static bool? GetBoolProperty(XElement rPr, XName propertyName)
            {
                if (rPr.Element(propertyName) == null)
                    return null;
                var s = (string)rPr.Element(propertyName).Attribute(W.val);
                if (s == null)
                    return true;
                if (s == "1")
                    return true;
                if (s == "0")
                    return false;
                if (s == "true")
                    return true;
                if (s == "false")
                    return false;
                if (s == "on")
                    return true;
                if (s == "off")
                    return false;
                return (bool)(rPr.Element(propertyName).Attribute(W.val));
            }

            private static XElement GetXmlProperty(XElement rPr, XName propertyName)
            {
                return rPr.Element(propertyName);
            }

            private static XName[] TogglePropertyNames = new[] {
                W.b,
                W.bCs,
                W.caps,
                W.emboss,
                W.i,
                W.iCs,
                W.imprint,
                W.outline,
                W.shadow,
                W.smallCaps,
                W.strike,
                W.vanish
            };

            private static XName[] PropertyNames = new[] {
                W.cs,
                W.rtl,
                W.u,
                W.color,
                W.highlight,
                W.shd
            };

        }

        private static HashSet<char> WeakAndNeutralDirectionalCharacters = new HashSet<char>() {
            '0',
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            '+',
            '-',
            ':',
            ',',
            '.',
            '|',
            '\t',
            '\r',
            '\n',
            ' ',
            '\x00A0', // non breaking space

            '\x00B0', // degree sign
            '\x066B', // arabic decimal separator
            '\x066C', // arabic thousands separator

            '\x0627', // arabic pipe 

            '\x20A0', // start currency symbols
            '\x20A1',
            '\x20A2',
            '\x20A3',
            '\x20A4',
            '\x20A5',
            '\x20A6',
            '\x20A7',
            '\x20A8',
            '\x20A9',
            '\x20AA',
            '\x20AB',
            '\x20AC',
            '\x20AD',
            '\x20AE',
            '\x20AF',
            '\x20B0',
            '\x20B1',
            '\x20B2',
            '\x20B3',
            '\x20B4',
            '\x20B5',
            '\x20B6',
            '\x20B7',
            '\x20B8',
            '\x20B9',
            '\x20BA',
            '\x20BB',
            '\x20BC',
            '\x20BD',
            '\x20BE',
            '\x20BF',
            '\x20C0',
            '\x20C1',
            '\x20C2',
            '\x20C3',
            '\x20C4',
            '\x20C5',
            '\x20C6',
            '\x20C7',
            '\x20C8',
            '\x20C9',
            '\x20CA',
            '\x20CB',
            '\x20CC',
            '\x20CD',
            '\x20CE',
            '\x20CF',  // end currency symbols

            '\x0660', // "Arabic" Indic Numeral Forms Iraq and West
            '\x0661',
            '\x0662',
            '\x0663',
            '\x0664',
            '\x0665',
            '\x0666',
            '\x0667',
            '\x0668',
            '\x0669',

            '\x06F0', // "Arabic" Indic Numberal Forms Iran and East
            '\x06F1',
            '\x06F2',
            '\x06F3',
            '\x06F4',
            '\x06F5',
            '\x06F6',
            '\x06F7',
            '\x06F8',
            '\x06F9',
        };

        private static void AdjustFontAttributes(WordprocessingDocument wDoc, XElement paraOrRun, XElement pPr,
            XElement rPr, FormattingAssemblerSettings settings)
        {
            XDocument themeXDoc = null;
            if (wDoc.MainDocumentPart.ThemePart != null)
                themeXDoc = wDoc.MainDocumentPart.ThemePart.GetXDocument();

            XElement fontScheme = null;
            XElement majorFont = null;
            XElement minorFont = null;
            if (themeXDoc != null)
            {
                fontScheme = themeXDoc.Root.Element(A.themeElements).Element(A.fontScheme);
                majorFont = fontScheme.Element(A.majorFont);
                minorFont = fontScheme.Element(A.minorFont);
            }
            var rFonts = rPr.Element(W.rFonts);
            if (rFonts == null)
            {
                return;
            }
            var asciiTheme = (string)rFonts.Attribute(W.asciiTheme);
            var hAnsiTheme = (string)rFonts.Attribute(W.hAnsiTheme);
            var eastAsiaTheme = (string)rFonts.Attribute(W.eastAsiaTheme);
            var cstheme = (string)rFonts.Attribute(W.cstheme);
            string ascii = null;
            string hAnsi = null;
            string eastAsia = null;
            string cs = null;

            XElement minorLatin = null;
            string minorLatinTypeface = null;
            XElement majorLatin = null;
            string majorLatinTypeface = null;

            if (minorFont != null)
            {
                minorLatin = minorFont.Element(A.latin);
                minorLatinTypeface = (string)minorLatin.Attribute("typeface");
            }

            if (majorFont != null)
            {
                majorLatin = majorFont.Element(A.latin);
                majorLatinTypeface = (string)majorLatin.Attribute("typeface");
            }
            if (asciiTheme != null)
            {
                if (asciiTheme.StartsWith("minor") && minorLatinTypeface != null)
                {
                    ascii = minorLatinTypeface;
                }
                else if (asciiTheme.StartsWith("major") && majorLatinTypeface != null)
                {
                    ascii = majorLatinTypeface;
                }
            }
            if (hAnsiTheme != null)
            {
                if (hAnsiTheme.StartsWith("minor") && minorLatinTypeface != null)
                {
                    hAnsi = minorLatinTypeface;
                }
                else if (hAnsiTheme.StartsWith("major") && majorLatinTypeface != null)
                {
                    hAnsi = majorLatinTypeface;
                }
            }
            if (eastAsiaTheme != null)
            {
                if (eastAsiaTheme.StartsWith("minor") && minorLatinTypeface != null)
                {
                    eastAsia = minorLatinTypeface;
                }
                else if (eastAsiaTheme.StartsWith("major") && majorLatinTypeface != null)
                {
                    eastAsia = majorLatinTypeface;
                }
            }
            if (cstheme != null)
            {
                if (cstheme.StartsWith("minor") && minorFont != null)
                {
                    cs = (string)minorFont.Element(A.cs).Attribute("typeface");
                }
                else if (cstheme.StartsWith("major") && majorFont != null)
                {
                    cs = (string)majorFont.Element(A.cs).Attribute("typeface");
                }
            }

            if (ascii != null)
            {
                rFonts.SetAttributeValue(W.ascii, ascii);
            }
            if (hAnsi != null)
            {
                rFonts.SetAttributeValue(W.hAnsi, hAnsi);
            }
            if (eastAsia != null)
            {
                rFonts.SetAttributeValue(W.eastAsia, eastAsia);
            }
            if (cs != null)
            {
                rFonts.SetAttributeValue(W.cs, cs);
            }

            var firstTextNode = paraOrRun.Descendants(W.t).FirstOrDefault(t => t.Value.Length > 0);
            string str = " ";

            // if there is a run with no text in it, then no need to do any of the rest of this method.
            if (firstTextNode == null && paraOrRun.Name == W.r)
                return;

            if (firstTextNode != null)
                str = firstTextNode.Value;

            var csa = new CharStyleAttributes(pPr, rPr);

            // This module determines the font based on just the first character.
            // Technically, a run can contain characters from different Unicode code blocks, and hence should be rendered with different fonts.
            // However, Word breaks up runs that use more than one font into multiple runs.  Other producers of WordprocessingML may not, so in
            // that case, this routine may need to be augmented to look at all characters in a run.

            /*
            old code
            var fontFamilies = str.select(function (c) {
                var ft = Pav.DetermineFontTypeFromCharacter(c, csa);
                switch (ft) {
                    case Pav.FontType.Ascii:
                        return cast(rFonts.attribute(W.ascii));
                    case Pav.FontType.HAnsi:
                        return cast(rFonts.attribute(W.hAnsi));
                    case Pav.FontType.EastAsia:
                        return cast(rFonts.attribute(W.eastAsia));
                    case Pav.FontType.CS:
                        return cast(rFonts.attribute(W.cs));
                    default:
                        return null;
                }
            })
                .where(function (f) { return f != null && f != ""; })
                .distinct()
                .select(function (f) { return new Pav.FontFamily(f); })
                .toArray();
            */

            var charToExamine = str.FirstOrDefault(c => ! WeakAndNeutralDirectionalCharacters.Contains(c));
            if (charToExamine == '\0')
                charToExamine = str[0];

            var ft = DetermineFontTypeFromCharacter(charToExamine, csa);
            string fontType = null;
            string languageType = null;
            switch (ft)
            {
                case FontType.Ascii:
                    fontType = (string)rFonts.Attribute(W.ascii);
                    languageType = "western";
                    break;
                case FontType.HAnsi:
                    fontType = (string)rFonts.Attribute(W.hAnsi);
                    languageType = "western";
                    break;
                case FontType.EastAsia:
                    if (settings.RestrictToSupportedLanguages)
                        throw new UnsupportedLanguageException("EastAsia languages are not supported");
                    fontType = (string)rFonts.Attribute(W.eastAsia);
                    languageType = "eastAsia";
                    break;
                case FontType.CS:
                    if (settings.RestrictToSupportedLanguages)
                        throw new UnsupportedLanguageException("Complex script (RTL) languages are not supported");
                    fontType = (string)rFonts.Attribute(W.cs);
                    languageType = "bidi";
                    break;
            }

            if (fontType != null)
            {
                if (paraOrRun.Attribute(PtOpenXml.FontName) == null)
                {
                    XAttribute fta = new XAttribute(PtOpenXml.FontName, fontType.ToString());
                    paraOrRun.Add(fta);
                }
                else
                {
                    paraOrRun.Attribute(PtOpenXml.FontName).Value = fontType.ToString();
                }
            }
            if (languageType != null)
            {
                if (paraOrRun.Attribute(PtOpenXml.LanguageType) == null)
                {
                    XAttribute lta = new XAttribute(PtOpenXml.LanguageType, languageType);
                    paraOrRun.Add(lta);
                }
                else
                {
                    paraOrRun.Attribute(PtOpenXml.LanguageType).Value = languageType;
                }
            }
        }

        public enum FontType
        {
            Ascii,
            HAnsi,
            EastAsia,
            CS
        };

        // The algorithm for this method comes from the implementer notes in [MS-OI29500].pdf
        // section 2.1.87

        // The implementer notes are at:
        // http://msdn.microsoft.com/en-us/library/ee908652.aspx

        public static FontType DetermineFontTypeFromCharacter(char ch, CharStyleAttributes csa)
        {
            // If the run has the cs element ("[ISO/IEC-29500-1] §17.3.2.7; cs") or the rtl element ("[ISO/IEC-29500-1] §17.3.2.30; rtl"),
            // then the cs (or cstheme if defined) font is used, regardless of the Unicode character values of the run’s content.
            if (csa.Rtl)
            {
                return FontType.CS;
            }

            // A large percentage of characters will fall in the following rule.

            // Unicode Block: Basic Latin
            if (ch >= 0x00 && ch <= 0x7f)
            {
                return FontType.Ascii;
            }

            // If the eastAsia (or eastAsiaTheme if defined) attribute’s value is “Times New Roman” and the ascii (or asciiTheme if defined)
            // and hAnsi (or hAnsiTheme if defined) attributes are equal, then the ascii (or asciiTheme if defined) font is used.
            if (csa.EastAsiaFont == "Times New Roman" &&
                csa.AsciiFont == csa.HAnsiFont)
            {
                return FontType.Ascii;
            }

            // Unicode BLock: Latin-1 Supplement
            if (ch >= 0xA0 && ch <= 0xFF)
            {
                if (csa.Hint == "eastAsia")
                {
                    if (ch == 0xA1 ||
                        ch == 0xA4 ||
                        ch == 0xA7 ||
                        ch == 0xA8 ||
                        ch == 0xAA ||
                        ch == 0xAD ||
                        ch == 0xAF ||
                        (ch >= 0xB0 && ch <= 0xB4) ||
                        (ch >= 0xB6 && ch <= 0xBA) ||
                        (ch >= 0xBC && ch <= 0xBF) ||
                        ch == 0xD7 ||
                        ch == 0xF7)
                    {
                        return FontType.EastAsia;
                    }
                    if (csa.EastAsiaLang == "zh-hant" ||
                        csa.EastAsiaLang == "zh-hans")
                    {
                        if (ch == 0xE0 ||
                            ch == 0xE1 ||
                            (ch >= 0xE8 && ch <= 0xEA) ||
                            (ch >= 0xEC && ch <= 0xED) ||
                            (ch >= 0xF2 && ch <= 0xF3) ||
                            (ch >= 0xF9 && ch <= 0xFA) ||
                            ch == 0xFC)
                        {
                            return FontType.EastAsia;
                        }
                    }
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Latin Extended-A
            if (ch >= 0x0100 && ch <= 0x017F)
            {
                if (csa.Hint == "eastAsia")
                {
                    if (csa.EastAsiaLang == "zh-hant" ||
                        csa.EastAsiaLang == "zh-hans"
                        /* || the character set of the east Asia (or east Asia theme) font is Chinese5 || GB2312 todo */)
                    {
                        return FontType.EastAsia;
                    }
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Latin Extended-B
            if (ch >= 0x0180 && ch <= 0x024F)
            {
                if (csa.Hint == "eastAsia")
                {
                    if (csa.EastAsiaLang == "zh-hant" ||
                        csa.EastAsiaLang == "zh-hans"
                        /* || the character set of the east Asia (or east Asia theme) font is Chinese5 || GB2312 todo */)
                    {
                        return FontType.EastAsia;
                    }
                }
                return FontType.HAnsi;
            }

            // Unicode Block: IPA Extensions
            if (ch >= 0x0250 && ch <= 0x02AF)
            {
                if (csa.Hint == "eastAsia")
                {
                    if (csa.EastAsiaLang == "zh-hant" ||
                        csa.EastAsiaLang == "zh-hans"
                        /* || the character set of the east Asia (or east Asia theme) font is Chinese5 || GB2312 todo */)
                    {
                        return FontType.EastAsia;
                    }
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Spacing Modifier Letters
            if (ch >= 0x02B0 && ch <= 0x02FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Combining Diacritic Marks
            if (ch >= 0x0300 && ch <= 0x036F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Greek
            if (ch >= 0x0370 && ch <= 0x03CF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Cyrillic
            if (ch >= 0x0400 && ch <= 0x04FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Hebrew
            if (ch >= 0x0590 && ch <= 0x05FF)
            {
                return FontType.Ascii;
            }

            // Unicode Block: Arabic
            if (ch >= 0x0600 && ch <= 0x06FF)
            {
                return FontType.Ascii;
            }

            // Unicode Block: Syriac
            if (ch >= 0x0700 && ch <= 0x074F)
            {
                return FontType.Ascii;
            }

            // Unicode Block: Arabic Supplement
            if (ch >= 0x0750 && ch <= 0x077F)
            {
                return FontType.Ascii;
            }

            // Unicode Block: Thanna
            if (ch >= 0x0780 && ch <= 0x07BF)
            {
                return FontType.Ascii;
            }

            // Unicode Block: Hangul Jamo
            if (ch >= 0x1100 && ch <= 0x11FF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Latin Extended Additional
            if (ch >= 0x1E00 && ch <= 0x1EFF)
            {
                if (csa.Hint == "eastAsia" &&
                    (csa.EastAsiaLang == "zh-hant" ||
                    csa.EastAsiaLang == "zh-hans"))
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: General Punctuation
            if (ch >= 0x2000 && ch <= 0x206F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Superscripts and Subscripts
            if (ch >= 0x2070 && ch <= 0x209F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Currency Symbols
            if (ch >= 0x20A0 && ch <= 0x20CF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Combining Diacritical Marks for Symbols
            if (ch >= 0x20D0 && ch <= 0x20FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Letter-like Symbols
            if (ch >= 0x2100 && ch <= 0x214F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Number Forms
            if (ch >= 0x2150 && ch <= 0x218F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Arrows
            if (ch >= 0x2190 && ch <= 0x21FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Mathematical Operators
            if (ch >= 0x2200 && ch <= 0x22FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Miscellaneous Technical
            if (ch >= 0x2300 && ch <= 0x23FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Control Pictures
            if (ch >= 0x2400 && ch <= 0x243F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Optical Character Recognition
            if (ch >= 0x2440 && ch <= 0x245F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Enclosed Alphanumerics
            if (ch >= 0x2460 && ch <= 0x24FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Box Drawing
            if (ch >= 0x2500 && ch <= 0x257F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Block Elements
            if (ch >= 0x2580 && ch <= 0x259F)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Geometric Shapes
            if (ch >= 0x25A0 && ch <= 0x25FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Miscellaneous Symbols
            if (ch >= 0x2600 && ch <= 0x26FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Dingbats
            if (ch >= 0x2700 && ch <= 0x27BF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: CJK Radicals Supplement
            if (ch >= 0x2E80 && ch <= 0x2EFF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Kangxi Radicals
            if (ch >= 0x2F00 && ch <= 0x2FDF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Ideographic Description Characters
            if (ch >= 0x2FF0 && ch <= 0x2FFF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: CJK Symbols and Punctuation
            if (ch >= 0x3000 && ch <= 0x303F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Hiragana
            if (ch >= 0x3040 && ch <= 0x309F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Katakana
            if (ch >= 0x30A0 && ch <= 0x30FF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Bopomofo
            if (ch >= 0x3100 && ch <= 0x312F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Hangul Compatibility Jamo
            if (ch >= 0x3130 && ch <= 0x318F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Kanbun
            if (ch >= 0x3190 && ch <= 0x319F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Enclosed CJK Letters and Months
            if (ch >= 0x3200 && ch <= 0x32FF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: CJK Compatibility
            if (ch >= 0x3300 && ch <= 0x33FF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: CJK Unified Ideographs Extension A
            if (ch >= 0x3400 && ch <= 0x4DBF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: CJK Unified Ideographs
            if (ch >= 0x4E00 && ch <= 0x9FAF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Yi Syllables
            if (ch >= 0xA000 && ch <= 0xA48F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Yi Radicals
            if (ch >= 0xA490 && ch <= 0xA4CF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Hangul Syllables
            if (ch >= 0xAC00 && ch <= 0xD7AF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: High Surrogates
            if (ch >= 0xD800 && ch <= 0xDB7F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: High Private Use Surrogates
            if (ch >= 0xDB80 && ch <= 0xDBFF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Low Surrogates
            if (ch >= 0xDC00 && ch <= 0xDFFF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Private Use Area
            if (ch >= 0xE000 && ch <= 0xF8FF)
            {
                if (csa.Hint == "eastAsia")
                {
                    return FontType.EastAsia;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: CJK Compatibility Ideographs
            if (ch >= 0xF900 && ch <= 0xFAFF)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Alphabetic Presentation Forms
            if (ch >= 0xFB00 && ch <= 0xFB4F)
            {
                if (csa.Hint == "eastAsia")
                {
                    if (ch >= 0xFB00 && ch <= 0xFB1C)
                        return FontType.EastAsia;
                    if (ch >= 0xFB1D && ch <= 0xFB4F)
                        return FontType.Ascii;
                }
                return FontType.HAnsi;
            }

            // Unicode Block: Arabic Presentation Forms-A
            if (ch >= 0xFB50 && ch <= 0xFDFF)
            {
                return FontType.Ascii;
            }

            // Unicode Block: CJK Compatibility Forms
            if (ch >= 0xFE30 && ch <= 0xFE4F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Small Form Variants
            if (ch >= 0xFE50 && ch <= 0xFE6F)
            {
                return FontType.EastAsia;
            }

            // Unicode Block: Arabic Presentation Forms-B
            if (ch >= 0xFE70 && ch <= 0xFEFE)
            {
                return FontType.Ascii;
            }

            // Unicode Block: Halfwidth and Fullwidth Forms
            if (ch >= 0xFF00 && ch <= 0xFFEF)
            {
                return FontType.EastAsia;
            }
            return FontType.HAnsi;
        }

        private class FormattingAssemblerInfo
        {
            public string DefaultParagraphStyleName;
            public string DefaultCharacterStyleName;
            public string DefaultTableStyleName;
            public Dictionary<string, XElement> RolledCharacterStyles;
            public FormattingAssemblerInfo()
            {
                RolledCharacterStyles = new Dictionary<string, XElement>();
            }
        }

        // CachedParaInfo is an optimization for the case where a paragraph contains thousands of runs.
        private class CachedParaInfo
        {
            public string ParagraphStyleName;
            public XElement ParagraphProperties;
        }

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

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