/// <summary>
        /// count occurrences of numbered lists, save that as a hint on the numbered list node
        /// </summary>
        /// <param name="mainDoc"></param>
        /// <param name="nsm"></param>
        private static void HandleNumberedLists(XmlDocument mainDoc, XmlNamespaceManager nsm)
        {
            // count the number of different list numbering schemes
            XmlNodeList numberNodes = mainDoc.SelectNodes("/w:document/w:numbering/w:num", nsm);

            if (numberNodes.Count == 0)
            {
                return;
            }

            // initialize the abstract number list
            XmlNodeList abstractNumNodes = mainDoc.SelectNodes("/w:document/w:numbering/w:abstractNum", nsm);
            Dictionary<string, AbstractListNumberingDefinition> abstractListDefinitions = new Dictionary<string, AbstractListNumberingDefinition>(abstractNumNodes.Count);
            Dictionary<string, ListNumberingDefinition> instanceListDefinitions = new Dictionary<string, ListNumberingDefinition>(numberNodes.Count);

            // store the abstract list type definitions
            foreach (XmlNode abstractNumNode in abstractNumNodes)
            {
                AbstractListNumberingDefinition absNumDef = new AbstractListNumberingDefinition(abstractNumNode, nsm);

                abstractListDefinitions[absNumDef.ID] = absNumDef;
            }

            // now go through the abstract list definitions and update those that are linked to other styles
            foreach (KeyValuePair<string, AbstractListNumberingDefinition> absNumDef in abstractListDefinitions)
            {
                if (absNumDef.Value.HasLinkedStyle)
                {
                    // find the linked style
                    string linkStyleXPath = "/w:document/w:numbering/w:abstractNum/w:styleLink[@w:val=\"" + absNumDef.Value.LinkedStyleId + "\"]";
                    XmlNode linkedStyleNode = mainDoc.SelectSingleNode(linkStyleXPath, nsm);

                    if (linkedStyleNode != null)
                    {
                        absNumDef.Value.UpdateDefinitionFromLinkedStyle(linkedStyleNode.ParentNode, nsm);
                    }
                }
            }

            // instantiate the list number definitions
            foreach (XmlNode numNode in numberNodes)
            {
                ListNumberingDefinition listDef = new ListNumberingDefinition(numNode, nsm, abstractListDefinitions);

                instanceListDefinitions[listDef.ListNumberId] = listDef;
            }

            // Get styles with numbering definitions
            XmlNodeList stylesWithNumbers = mainDoc.SelectNodes("/w:document/w:styles/w:style/w:pPr/w:numPr", nsm);
            Dictionary<string, StyleDefinition> styleDefinitions = new Dictionary<string, StyleDefinition>(stylesWithNumbers.Count);
            foreach (XmlNode styleNode in stylesWithNumbers)
            {
                // Check to see if it is based on a style that is not in the definitions list yet?
                StyleDefinition styleDef = new StyleDefinition(styleNode, nsm, styleDefinitions);
                styleDefinitions[styleDef.Name] = styleDef;
            }

            XmlNodeList styleParagraphs = mainDoc.SelectNodes("//w:pPr/w:pStyle", nsm);
            foreach (XmlNode paragraph in styleParagraphs)
            {
                string styleName = getAttributeValue(paragraph, ValAttrName);
                if (!String.IsNullOrEmpty(styleName) && styleDefinitions.ContainsKey(styleName))
                {
                    XmlNode oldNode = paragraph.ParentNode.SelectSingleNode("./w:numPr", nsm);
                    if (oldNode == null)
                        styleDefinitions[styleName].AddNumbering(mainDoc, paragraph.ParentNode);
                }
            }

            XmlNodeList listNodes = mainDoc.SelectNodes("//w:numPr/w:ilvl", nsm);

            foreach (XmlNode node in listNodes)
            {
                string levelId = getAttributeValue(node, ValAttrName);
                XmlNode numIdNode = node.ParentNode.SelectSingleNode("./w:numId", nsm);

                if (!String.IsNullOrEmpty(levelId) && numIdNode != null)
                {
                    string numId = getAttributeValue(numIdNode, ValAttrName);

                    if (!String.IsNullOrEmpty(numId) && instanceListDefinitions.ContainsKey(numId) && instanceListDefinitions[numId].LevelExists(levelId))
                    {
                        XmlAttribute counterAttr = mainDoc.CreateAttribute("numString");

                        instanceListDefinitions[numId].IncrementCounter(levelId);
                        counterAttr.Value = instanceListDefinitions[numId].GetCurrentNumberString(levelId) + " ";

                        node.Attributes.Append(counterAttr);

                        string font = instanceListDefinitions[numId].GetFont(levelId);

                        if (!String.IsNullOrEmpty(font))
                        {
                            XmlAttribute fontAttr = mainDoc.CreateAttribute("numFont");

                            fontAttr.Value = font;

                            node.Attributes.Append(fontAttr);
                        }

                        if (instanceListDefinitions[numId].IsBullet(levelId))
                        {
                            XmlAttribute bulletAttr = mainDoc.CreateAttribute("isBullet");

                            bulletAttr.Value = "true";

                            node.Attributes.Append(bulletAttr);
                        }
                    }
                }
            }
        }
            /// <summary>
            /// constructor
            /// </summary>
            /// <param name="numNode"></param>
            /// <param name="nsm"></param>
            /// <param name="abstractListDefinitions"></param>
            public ListNumberingDefinition(XmlNode numNode, XmlNamespaceManager nsm, Dictionary<string, AbstractListNumberingDefinition> abstractListDefinitions)
            {
                this.listNumberId = getAttributeValue(numNode, "w:numId");

                XmlNode abstractNumNode = numNode.SelectSingleNode("./w:abstractNumId", nsm);

                if (abstractNumNode != null)
                {
                    this.abstractListDefinition = abstractListDefinitions[getAttributeValue(abstractNumNode, ValAttrName)];

                    // Create local overrides for the list number levels
                    overrideLevels = new Dictionary<string, ListLevel>();

                    // propagate the level overrides into the current list number level definition
                    XmlNodeList levelOverrideNodes = numNode.SelectNodes("./w:lvlOverride", nsm);

                    if (levelOverrideNodes != null)
                    {
                        foreach (XmlNode overrideNode in levelOverrideNodes)
                        {
                            string overrideLevelId = getAttributeValue(overrideNode, "w:ilvl");
                            XmlNode node = overrideNode.SelectSingleNode("./w:lvl", nsm);
                            if (node == null)
                                node = overrideNode;

                            if (!String.IsNullOrEmpty(overrideLevelId))
                            {
                                ListLevel newLevel = new ListLevel(this.abstractListDefinition.ListLevels[overrideLevelId]);
                                newLevel.SetOverrides(node, nsm);
                                overrideLevels.Add(overrideLevelId, newLevel);
                            }
                        }
                    }
                }
            }
        /// <summary>
        /// count occurrences of numbered lists, save that as a hint on the numbered list node
        /// </summary>
        /// <param name="mainDoc"></param>
        /// <param name="nsm"></param>
        private static void HandleNumberedLists(XmlDocument mainDoc, XmlNamespaceManager nsm)
        {
            // count the number of different list numbering schemes
            XmlNodeList numberNodes = mainDoc.SelectNodes("/w:document/w:numbering/w:num", nsm);

            if (numberNodes.Count == 0)
            {
                return;
            }

            // initialize the abstract number list
            XmlNodeList abstractNumNodes = mainDoc.SelectNodes("/w:document/w:numbering/w:abstractNum", nsm);
            Dictionary <string, AbstractListNumberingDefinition> abstractListDefinitions = new Dictionary <string, AbstractListNumberingDefinition>(abstractNumNodes.Count);
            Dictionary <string, ListNumberingDefinition>         instanceListDefinitions = new Dictionary <string, ListNumberingDefinition>(numberNodes.Count);

            // store the abstract list type definitions
            foreach (XmlNode abstractNumNode in abstractNumNodes)
            {
                AbstractListNumberingDefinition absNumDef = new AbstractListNumberingDefinition(abstractNumNode, nsm);

                abstractListDefinitions[absNumDef.ID] = absNumDef;
            }

            // now go through the abstract list definitions and update those that are linked to other styles
            foreach (KeyValuePair <string, AbstractListNumberingDefinition> absNumDef in abstractListDefinitions)
            {
                if (absNumDef.Value.HasLinkedStyle)
                {
                    // find the linked style
                    string  linkStyleXPath  = "/w:document/w:numbering/w:abstractNum/w:styleLink[@w:val=\"" + absNumDef.Value.LinkedStyleId + "\"]";
                    XmlNode linkedStyleNode = mainDoc.SelectSingleNode(linkStyleXPath, nsm);

                    if (linkedStyleNode != null)
                    {
                        absNumDef.Value.UpdateDefinitionFromLinkedStyle(linkedStyleNode.ParentNode, nsm);
                    }
                }
            }

            // instantiate the list number definitions
            foreach (XmlNode numNode in numberNodes)
            {
                ListNumberingDefinition listDef = new ListNumberingDefinition(numNode, nsm, abstractListDefinitions);

                instanceListDefinitions[listDef.ListNumberId] = listDef;
            }

            // Get styles with numbering definitions
            XmlNodeList stylesWithNumbers = mainDoc.SelectNodes("/w:document/w:styles/w:style/w:pPr/w:numPr", nsm);
            Dictionary <string, StyleDefinition> styleDefinitions = new Dictionary <string, StyleDefinition>(stylesWithNumbers.Count);

            foreach (XmlNode styleNode in stylesWithNumbers)
            {
                // Check to see if it is based on a style that is not in the definitions list yet?
                StyleDefinition styleDef = new StyleDefinition(styleNode, nsm, styleDefinitions);
                styleDefinitions[styleDef.Name] = styleDef;
            }

            XmlNodeList styleParagraphs = mainDoc.SelectNodes("//w:pPr/w:pStyle", nsm);

            foreach (XmlNode paragraph in styleParagraphs)
            {
                string styleName = getAttributeValue(paragraph, ValAttrName);
                if (!String.IsNullOrEmpty(styleName) && styleDefinitions.ContainsKey(styleName))
                {
                    XmlNode oldNode = paragraph.ParentNode.SelectSingleNode("./w:numPr", nsm);
                    if (oldNode == null)
                    {
                        styleDefinitions[styleName].AddNumbering(mainDoc, paragraph.ParentNode);
                    }
                }
            }

            XmlNodeList listNodes = mainDoc.SelectNodes("//w:numPr/w:ilvl", nsm);

            foreach (XmlNode node in listNodes)
            {
                string  levelId   = getAttributeValue(node, ValAttrName);
                XmlNode numIdNode = node.ParentNode.SelectSingleNode("./w:numId", nsm);

                if (!String.IsNullOrEmpty(levelId) && numIdNode != null)
                {
                    string numId = getAttributeValue(numIdNode, ValAttrName);

                    if (!String.IsNullOrEmpty(numId) && instanceListDefinitions.ContainsKey(numId) && instanceListDefinitions[numId].LevelExists(levelId))
                    {
                        XmlAttribute counterAttr = mainDoc.CreateAttribute("numString");

                        instanceListDefinitions[numId].IncrementCounter(levelId);
                        counterAttr.Value = instanceListDefinitions[numId].GetCurrentNumberString(levelId) + " ";

                        node.Attributes.Append(counterAttr);

                        string font = instanceListDefinitions[numId].GetFont(levelId);

                        if (!String.IsNullOrEmpty(font))
                        {
                            XmlAttribute fontAttr = mainDoc.CreateAttribute("numFont");

                            fontAttr.Value = font;

                            node.Attributes.Append(fontAttr);
                        }

                        if (instanceListDefinitions[numId].IsBullet(levelId))
                        {
                            XmlAttribute bulletAttr = mainDoc.CreateAttribute("isBullet");

                            bulletAttr.Value = "true";

                            node.Attributes.Append(bulletAttr);
                        }
                    }
                }
            }
        }