public static ParseResult ParseFrom(
                ParseInput lines,
                bool innerParagraph
                )
            {
                ParseResult result = new ParseResult();
                ParseResult innerResult;
                IHtmlable   returnedElement;

                // If the list items content contains another list
                if (MarkdownList.CanParseFrom(lines))
                {
                    innerResult     = MarkdownList.ParseFrom(lines);
                    returnedElement = new MarkdownListItem(
                        innerResult.GetContent()
                        );
                }
                else
                {
                    // Otherwise, if the item content should go in a paragraph
                    if (innerParagraph)
                    {
                        innerResult     = MarkdownParagraph.ParseFrom(lines);
                        returnedElement = new MarkdownListItem(
                            innerResult.GetContent()
                            );
                    }
                    else
                    {
                        // line item content should not go in a paragraph
                        returnedElement = new MarkdownListItem(
                            MarkdownParser.ParseInnerText(lines)
                            );
                    }
                }
                result.Success = true;
                result.AddContent(
                    returnedElement
                    );
                return(result);
            }
        public static ParseResult ParseFrom(
            ParseInput input
            )
        {
            ArraySegment <string> lines  = input.Lines();
            ParseResult           result = new ParseResult();

            if (!CanParseFrom(input))
            {
                return(result);
            }

            /*
             * Work out the list type from the first line
             * before we start to mangle the line contents
             */
            MarkdownElementType type;

            if (regexOrderedListLine.Match(input.FirstLine).Success)
            {
                type = MarkdownElementType.OrderedList;
            }
            else
            {
                type = MarkdownElementType.UnorderedList;
            }
            int endListSection = FindEndOfListSection(
                lines
                );
            // New array segment with only parsed content
            ArraySegment <string> listLines = new ArraySegment <string>(
                lines.Array,
                lines.Offset,
                endListSection
                );
            // Need to split into groups per list item
            int currentIndex = 0;
            // Hold the parsed list items as we go
            LinkedList <IHtmlable> listItems = new LinkedList <IHtmlable>();
            // Track whether list item contents should be in a paragraph
            bool whitespaceLineBefore = false;
            bool whitespaceLineAfter  = false;

            while (currentIndex < endListSection)
            {
                int endIndex = FindEndOfListItem(
                    listLines,
                    currentIndex
                    );

                /*
                 * There is a whitespace line between
                 * this list item and the following one
                 * and this list item isn't the final one
                 */
                whitespaceLineAfter = (
                    (endIndex < listLines.Count) &&
                    (
                        ContainsOnlyWhitespace(
                            listLines[endIndex - 1]
                            )
                    )
                    );
                // Create new parse input for this list item
                ParseInput listItemLines = new ParseInput(
                    input.Urls,
                    listLines.Array,
                    listLines.Offset + currentIndex,
                    endIndex - currentIndex
                    );
                RemoveListIndicators(
                    listItemLines
                    );
                ParseResult nextListItem = MarkdownListItem.ParseFrom(
                    listItemLines,
                    whitespaceLineBefore || whitespaceLineAfter
                    );
                foreach (
                    IHtmlable entry
                    in nextListItem.GetContent()
                    )
                {
                    listItems.AddLast(
                        entry
                        );
                }
                // Jump over lines just parsed
                currentIndex += (endIndex - currentIndex);
                // Whitespace after previous entry becomes before next entry
                whitespaceLineBefore = whitespaceLineAfter;

                /*
                 * If there's further whitespace after parsed section
                 * (for some reason) then jump over this too
                 */
                while (
                    (currentIndex < listLines.Count) &&
                    (
                        ContainsOnlyWhitespace(
                            lines[currentIndex]
                            )
                    )
                    )
                {
                    currentIndex++;
                }
            }
            result.Success = true;
            result.AddContent(
                new MarkdownList(
                    Utils.LinkedListToArray(
                        listItems
                        ),
                    type
                    )
                );
            return(result);
        }