private int GetMatchedMarkList(FormatState formatState, MarkerList mlHave, MarkerList mlWant)
        {
            // The ones we have are only "good" if the styles match what we want.
            int nMatch = 0;
            for (; nMatch < mlHave.Count && nMatch < mlWant.Count; nMatch++)
            {
                if (!formatState.IsContinue)
                {
                    MarkerListEntry eHave = mlHave.EntryAt(nMatch);
                    MarkerListEntry eWant = mlWant.EntryAt(nMatch);

                    if (eHave.Marker != eWant.Marker
                        || eHave.ILS != eWant.ILS
                        || eHave.StartIndexDefault != eWant.StartIndexDefault
                        || eWant.StartIndexOverride >= 0)
                    {
                        break;
                    }
                }
            }

            return nMatch;
        }
        private void EnsureListAndListItem(FormatState formatState, DocumentNodeArray dna, MarkerList mlHave, MarkerList mlWant, int nMatch)
        {
            int nInsertAt;

            bool added = false;

            int nLists = mlHave.Count;
            int nLevel = mlWant.Count;

            // Close any open lists that don't match the ones we want.
            bool bInField = dna.FindUnmatched(DocumentNodeType.dnFieldBegin) >= 0;
            if (nLists > nMatch)
            {
                DocumentNode documentNodePara = dna.Pop();
                while (nLists > nMatch)
                {
                    int nOpen = dna.FindPending(DocumentNodeType.dnList);
                    if (nOpen >= 0)
                    {
                        dna.CloseAt(nOpen);

                        // Only coalesce if this is a top-level list.  Otherwise I want to get
                        // the full structure to use for margin fixups so I delay coalescing.
                        // No, don't coalesce since a later list may need to get merged with this one.
                        // if (!bInField && dna.FindPending(DocumentNodeType.dnList) < 0)
                        //    dna.CoalesceChildren(_converterState, nOpen);
                    }
                    nLists--;
                    mlHave.RemoveRange(mlHave.Count - 1, 1);
                }
                dna.Push(documentNodePara);
            }

            if (nLists < nLevel)
            {
                // Multiple immediately nested lists are handled poorly in Avalon and are usually an indication
                // of bad input from Word (or some other word processor).  Clip the number of lists we'll create here.
                if (nLevel != nLists + 1)
                {
                    // I'm going to truncate, but make the list I create here of the specific type at this level.
                    if (nLevel <= mlWant.Count)
                    {
                        mlWant[nLists] = mlWant[mlWant.Count - 1];
                    }
                    nLevel = nLists + 1;
                }

                // Ensure sufficient lists are open - this may be our first indication
                // Insert the list nodes right before the current paragraph
                nInsertAt = dna.Count - 1;

                while (nLists < nLevel)
                {
                    added = true;

                    DocumentNode dnList = new DocumentNode(DocumentNodeType.dnList);
                    DocumentNode dnLI = new DocumentNode(DocumentNodeType.dnListItem);

                    dna.InsertNode(nInsertAt, dnLI);
                    dna.InsertNode(nInsertAt, dnList);

                    // Set the list properties
                    MarkerListEntry mle = mlWant.EntryAt(nLists);
                    dnList.FormatState.Marker = mle.Marker;
                    dnList.FormatState.StartIndex = mle.StartIndexToUse;
                    dnList.FormatState.StartIndexDefault = mle.StartIndexDefault;
                    dnList.VirtualListLevel = mle.VirtualListLevel;
                    dnList.FormatState.ILS = mle.ILS;
                    nLists++;
                }
            }

            // Ensure listitem is open
            nInsertAt = dna.Count - 1;
            int nList = dna.FindPending(DocumentNodeType.dnList);
            if (nList >= 0)
            {
                int nLI = dna.FindPending(DocumentNodeType.dnListItem, nList);

                if (nLI >= 0 && !added && !formatState.IsContinue)
                {
                    DocumentNode documentNodePara = dna.Pop();
                    dna.CloseAt(nLI);
                    // Don't coalesce - I may need to do margin fixup.
                    // dna.CoalesceChildren(_converterState, nLI);
                    dna.Push(documentNodePara);

                    nLI = -1;
                    nInsertAt = dna.Count - 1;
                }
                if (nLI == -1)
                {
                    DocumentNode dnLI = new DocumentNode(DocumentNodeType.dnListItem);

                    dna.InsertNode(nInsertAt, dnLI);
                }
            }
        }
        internal MarkerList GetMarkerStylesOfParagraph(MarkerList mlHave, FormatState fs, bool bMarkerPresent)
        {
            MarkerList mlWant = new MarkerList();
            long nVirtualListLevel = fs.ListLevel;
            long nStartIndexOverride = -1;

            // No list?
            if (nVirtualListLevel < 1)
            {
                return mlWant;
            }

            // Use currently open list styles for all levels below requested one
            for (int i = 0; i < mlHave.Count; i++)
                if (mlHave.EntryAt(i).VirtualListLevel < nVirtualListLevel || fs.IsContinue)
                {
                    MarkerListEntry mle = mlHave.EntryAt(i);
                    mlWant.AddEntry(mle.Marker, mle.ILS, -1, mle.StartIndexDefault, mle.VirtualListLevel);
                }
                else
                {
                    break;
                }

            // If I'm a continuation paragraph, I'm done.
            if (fs.IsContinue)
            {
                return mlWant;
            }

            // Now determine the list style for the list level I'm going to add.
            ListOverrideTable lot = _converterState.ListOverrideTable;
            ListOverride lo = lot.FindEntry((int)fs.ILS);
            if (lo != null)
            {
                ListLevelTable levels = lo.Levels;
                if (levels == null || levels.Count == 0)
                {
                    ListTableEntry lte = _converterState.ListTable.FindEntry(lo.ID);
                    if (lte != null)
                    {
                        levels = lte.Levels;
                    }

                    // Did the list override specify a start index?
                    if (lo.StartIndex > 0)
                    {
                        nStartIndexOverride = lo.StartIndex;
                    }
                }

                if (levels != null)
                {
                    ListLevel listLevel = levels.EntryAt((int)nVirtualListLevel - 1);
                    if (listLevel != null)
                    {
                        // If there was a marker present, we ignore the "Hidden" style in the list table.
                        MarkerStyle ms = listLevel.Marker;
                        if (ms == MarkerStyle.MarkerHidden && bMarkerPresent)
                        {
                            ms = MarkerStyle.MarkerBullet;
                        }

                        mlWant.AddEntry(ms, fs.ILS, nStartIndexOverride, listLevel.StartIndex, nVirtualListLevel);
                        return mlWant;
                    }
                }
            }

            // If there wasn't a list definition, use the marker type in the formatstate.
            mlWant.AddEntry(fs.Marker, fs.ILS, nStartIndexOverride, fs.StartIndex, nVirtualListLevel);
            return mlWant;
        }