package org.apache.maven.doxia.module.apt;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.maven.doxia.macro.MacroExecutionException;
import org.apache.maven.doxia.macro.MacroRequest;
import org.apache.maven.doxia.macro.manager.MacroNotFoundException;
import org.apache.maven.doxia.parser.AbstractTextParser;
import org.apache.maven.doxia.parser.ParseException;
import org.apache.maven.doxia.parser.Parser;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.SinkAdapter;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.doxia.util.DoxiaUtils;

import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;

/**
 * The APT parser.
 * <br>
 * Based on the <a href="http://www.xmlmind.com/aptconvert.html">APTconvert</a> project.
 *
 * @version $Id$
 * @since 1.0
 */
@Component( role = Parser.class, hint = "apt" )
public class AptParser
    extends AbstractTextParser
    implements AptMarkup
{
    /** Title event id */
    private static final int TITLE = 0;

    /** Section 1 event id */
    private static final int SECTION1 = 1;

    /** Section 2 event id */
    private static final int SECTION2 = 2;

    /** Section 3 event id */
    private static final int SECTION3 = 3;

    /** Section 4 event id */
    private static final int SECTION4 = 4;

    /** Section 5 event id */
    private static final int SECTION5 = 5;

    /** Paragraph event id */
    private static final int PARAGRAPH = 6;

    /** Verbatim event id */
    private static final int VERBATIM = 7;

    /** Figure event id */
    private static final int FIGURE = 8;

    /** Table event id */
    private static final int TABLE = 9;

    /** List event id */
    private static final int LIST_ITEM = 10;

    /** Numbered list event id */
    private static final int NUMBERED_LIST_ITEM = 11;

    /** Definition list event id */
    private static final int DEFINITION_LIST_ITEM = 12;

    /** Horizontal rule event id */
    private static final int HORIZONTAL_RULE = 13;

    /** Page break event id */
    private static final int PG_BREAK = 14;

    /** List break event id */
    private static final int LIST_BREAK = 15;

    /** Macro event id */
    private static final int MACRO = 16;

    /** Comment event id. */
    private static final int COMMENT_BLOCK = 17;

    /** String representations of event ids */
    private static final String[] TYPE_NAMES = {
        "TITLE",
        "SECTION1",
        "SECTION2",
        "SECTION3",
        "SECTION4",
        "SECTION5",
        "PARAGRAPH",
        "VERBATIM",
        "FIGURE",
        "TABLE",
        "LIST_ITEM",
        "NUMBERED_LIST_ITEM",
        "DEFINITION_LIST_ITEM",
        "HORIZONTAL_RULE",
        "PG_BREAK",
        "LIST_BREAK",
        "MACRO",
        "COMMENT_BLOCK" };

    /** An array of 85 spaces. */
    protected static final char[] SPACES;

    /** Default tab width. */
    public static final int TAB_WIDTH = 8;

    // ----------------------------------------------------------------------
    // Instance fields
    // ----------------------------------------------------------------------

    /** the AptSource. */
    private AptSource source;

    /** a block of AptSource. */
    private Block block;

    /** blockFileName. */
    private String blockFileName;

    /** blockLineNumber. */
    private int blockLineNumber;

    /** sourceContent. */
    protected String sourceContent;

    /** the sink to receive the events. */
    protected Sink sink;

    /** a line of AptSource. */
    protected String line;

    /** Map of warn messages with a String as key to describe the error type and a Set as value.
     * Using to reduce warn messages. */
    protected Map<String, Set<String>> warnMessages;

    private static final int NUMBER_OF_SPACES = 85;

    static
    {
        SPACES = new char[NUMBER_OF_SPACES];

        for ( int i = 0; i < NUMBER_OF_SPACES; i++ )
        {
            SPACES[i] = ' ';
        }
    }

    // ----------------------------------------------------------------------
    // Public methods
    // ----------------------------------------------------------------------

    @Override
    public void parse( Reader source, Sink sink )
        throws ParseException
    {
        parse( source, sink, "" );
    }
    
    @Override
    public void parse( Reader source, Sink sink, String reference )
        throws ParseException
    {
        init();

        try
        {
            StringWriter contentWriter = new StringWriter();
            IOUtil.copy( source, contentWriter );
            sourceContent = contentWriter.toString();
        }
        catch ( IOException e )
        {
            throw new AptParseException( "IOException: " + e.getMessage(), e );
        }

        try
        {
            this.source = new AptReaderSource( new StringReader( sourceContent ), reference );

            this.sink = sink;
            sink.enableLogging( getLog() );

            blockFileName = null;

            blockLineNumber = -1;

            // Lookahead line.
            nextLine();

            // Lookahead block.
            nextBlock( /*first*/true );

            // traverse comments
            while ( ( block != null ) && ( block.getType() == COMMENT_BLOCK ) )
            {
                block.traverse();
                nextBlock( /*first*/true );
            }

            traverseHead();

            traverseBody();
        }
        catch ( AptParseException ape )
        {
            // TODO handle column number
            throw new AptParseException( ape.getMessage(), ape, getSourceName(), getSourceLineNumber(), -1 );
        }
        finally
        {
            logWarnings();

            setSecondParsing( false );
            init();
        }
    }

    /**
     * Returns the name of the Apt source document.
     *
     * @return the source name.
     */
    public String getSourceName()
    {
        // Use this rather than source.getName() to report errors.
        return blockFileName;
    }

    /**
     * Returns the current line number of the Apt source document.
     *
     * @return the line number.
     */
    public int getSourceLineNumber()
    {
        // Use this rather than source.getLineNumber() to report errors.
        return blockLineNumber;
    }

    // ----------------------------------------------------------------------
    // Protected methods
    // ----------------------------------------------------------------------

    /**
     * Parse the next line of the Apt source document.
     *
     * @throws org.apache.maven.doxia.module.apt.AptParseException if something goes wrong.
     */
    protected void nextLine()
        throws AptParseException
    {
        line = source.getNextLine();
    }

    /**
     * Parse the given text.
     *
     * @param text the text to parse.
     * @param begin offset.
     * @param end offset.
     * @param sink the sink to receive the events.
     * @throws org.apache.maven.doxia.module.apt.AptParseException if something goes wrong.
     */
    protected void doTraverseText( String text, int begin, int end, Sink sink )
        throws AptParseException
    {
        boolean anchor = false;
        boolean link = false;
        boolean italic = false;
        boolean bold = false;
        boolean monospaced = false;
        StringBuilder buffer = new StringBuilder( end - begin );

        for ( int i = begin; i < end; ++i )
        {
            char c = text.charAt( i );
            switch ( c )
            {
                case BACKSLASH:
                    if ( i + 1 < end )
                    {
                        char escaped = text.charAt( i + 1 );
                        switch ( escaped )
                        {
                            case SPACE:
                                ++i;
                                flushTraversed( buffer, sink );
                                sink.nonBreakingSpace();
                                break;
                            case '\r':
                            case '\n':
                                ++i;
                                // Skip white space which may follow a line break.
                                while ( i + 1 < end && Character.isWhitespace( text.charAt( i + 1 ) ) )
                                {
                                    ++i;
                                }
                                flushTraversed( buffer, sink );
                                sink.lineBreak();
                                break;
                            case BACKSLASH:
                            case PIPE:
                            case COMMENT:
                            case EQUAL:
                            case MINUS:
                            case PLUS:
                            case STAR:
                            case LEFT_SQUARE_BRACKET:
                            case RIGHT_SQUARE_BRACKET:
                            case LESS_THAN:
                            case GREATER_THAN:
                            case LEFT_CURLY_BRACKET:
                            case RIGHT_CURLY_BRACKET:
                                ++i;
                                buffer.append( escaped );
                                break;
                            case 'x':
                                if ( i + 3 < end && isHexChar( text.charAt( i + 2 ) )
                                    && isHexChar( text.charAt( i + 3 ) ) )
                                {
                                    int value = '?';
                                    try
                                    {
                                        value = Integer.parseInt( text.substring( i + 2, i + 4 ), 16 );
                                    }
                                    catch ( NumberFormatException e )
                                    {
                                        if ( getLog().isDebugEnabled() )
                                        {
                                            getLog().debug( "Not a number: " + text.substring( i + 2, i + 4 ) );
                                        }
                                    }

                                    i += 3;
                                    buffer.append( (char) value );
                                }
                                else
                                {
                                    buffer.append( BACKSLASH );
                                }
                                break;
                            case 'u':
                                if ( i + 5 < end && isHexChar( text.charAt( i + 2 ) )
                                    && isHexChar( text.charAt( i + 3 ) ) && isHexChar( text.charAt( i + 4 ) )
                                    && isHexChar( text.charAt( i + 5 ) ) )
                                {
                                    int value = '?';
                                    try
                                    {
                                        value = Integer.parseInt( text.substring( i + 2, i + 6 ), 16 );
                                    }
                                    catch ( NumberFormatException e )
                                    {
                                        if ( getLog().isDebugEnabled() )
                                        {
                                            getLog().debug( "Not a number: " + text.substring( i + 2, i + 6 ) );
                                        }
                                    }

                                    i += 5;
                                    buffer.append( (char) value );
                                }
                                else
                                {
                                    buffer.append( BACKSLASH );
                                }
                                break;
                            default:
                                if ( isOctalChar( escaped ) )
                                {
                                    int octalChars = 1;
                                    if ( isOctalChar( charAt( text, end, i + 2 ) ) )
                                    {
                                        ++octalChars;
                                        if ( isOctalChar( charAt( text, end, i + 3 ) ) )
                                        {
                                            ++octalChars;
                                        }
                                    }
                                    int value = '?';
                                    try
                                    {
                                        value = Integer.parseInt( text.substring( i + 1, i + 1 + octalChars ), 8 );
                                    }
                                    catch ( NumberFormatException e )
                                    {
                                        if ( getLog().isDebugEnabled() )
                                        {
                                            getLog().debug(
                                                            "Not a number: "
                                                                + text.substring( i + 1, i + 1 + octalChars ) );
                                        }
                                    }

                                    i += octalChars;
                                    buffer.append( (char) value );
                                }
                                else
                                {
                                    buffer.append( BACKSLASH );
                                }
                        }
                    }
                    else
                    {
                        buffer.append( BACKSLASH );
                    }
                    break;

                case LEFT_CURLY_BRACKET: /*}*/
                    if ( !anchor && !link )
                    {
                        if ( i + 1 < end && text.charAt( i + 1 ) == LEFT_CURLY_BRACKET /*}*/ )
                        {
                            ++i;
                            link = true;
                            flushTraversed( buffer, sink );

                            String linkAnchor = null;

                            if ( i + 1 < end && text.charAt( i + 1 ) == LEFT_CURLY_BRACKET /*}*/ )
                            {
                                ++i;
                                StringBuilder buf = new StringBuilder();
                                i = skipTraversedLinkAnchor( text, i + 1, end, buf );
                                linkAnchor = buf.toString();
                            }

                            if ( linkAnchor == null )
                            {
                                linkAnchor = getTraversedLink( text, i + 1, end );
                            }

                            if ( AptUtils.isInternalLink( linkAnchor ) )
                            {
                                linkAnchor = "#" + linkAnchor;
                            }

                            int hashIndex = linkAnchor.indexOf( "#" );

                            if ( hashIndex != -1 && !AptUtils.isExternalLink( linkAnchor ) )
                            {
                                String hash = linkAnchor.substring( hashIndex + 1 );

                                if ( hash.endsWith( ".html" ) && !hash.startsWith( "./" ) )
                                {
                                    String msg = "Ambiguous link: '" + hash
                                            + "'. If this is a local link, prepend \"./\"!";
                                    logMessage( "ambiguousLink", msg );
                                }

                                // link##anchor means literal
                                if ( hash.startsWith( "#" ) )
                                {
                                    linkAnchor = linkAnchor.substring( 0, hashIndex ) + hash;
                                }
                                else if ( !DoxiaUtils.isValidId( hash ) )
                                {
                                    linkAnchor =
                                        linkAnchor.substring( 0, hashIndex ) + "#"
                                            + DoxiaUtils.encodeId( hash, true );

                                    String msg = "Modified invalid link: '" + hash + "' to '" + linkAnchor + "'";
                                    logMessage( "modifiedLink", msg );
                                }
                            }

                            sink.link( linkAnchor );
                        }
                        else
                        {
                            anchor = true;
                            flushTraversed( buffer, sink );

                            String linkAnchor = getTraversedAnchor( text, i + 1, end );

                            linkAnchor = AptUtils.encodeAnchor( linkAnchor );

                            sink.anchor( linkAnchor );
                        }
                    }
                    else
                    {
                        buffer.append( c );
                    }
                    break;

                case /*{*/RIGHT_CURLY_BRACKET:
                    if ( link && i + 1 < end && text.charAt( i + 1 ) == /*{*/RIGHT_CURLY_BRACKET )
                    {
                        ++i;
                        link = false;
                        flushTraversed( buffer, sink );
                        sink.link_();
                    }
                    else if ( anchor )
                    {
                        anchor = false;
                        flushTraversed( buffer, sink );
                        sink.anchor_();
                    }
                    else
                    {
                        buffer.append( c );
                    }
                    break;

                case LESS_THAN:
                    if ( !italic && !bold && !monospaced )
                    {
                        if ( i + 1 < end && text.charAt( i + 1 ) == LESS_THAN )
                        {
                            if ( i + 2 < end && text.charAt( i + 2 ) == LESS_THAN )
                            {
                                i += 2;
                                monospaced = true;
                                flushTraversed( buffer, sink );
                                sink.monospaced();
                            }
                            else
                            {
                                ++i;
                                bold = true;
                                flushTraversed( buffer, sink );
                                sink.bold();
                            }
                        }
                        else
                        {
                            italic = true;
                            flushTraversed( buffer, sink );
                            sink.italic();
                        }
                    }
                    else
                    {
                        buffer.append( c );
                    }
                    break;

                case GREATER_THAN:
                    if ( monospaced && i + 2 < end && text.charAt( i + 1 ) == GREATER_THAN
                        && text.charAt( i + 2 ) == GREATER_THAN )
                    {
                        i += 2;
                        monospaced = false;
                        flushTraversed( buffer, sink );
                        sink.monospaced_();
                    }
                    else if ( bold && i + 1 < end && text.charAt( i + 1 ) == GREATER_THAN )
                    {
                        ++i;
                        bold = false;
                        flushTraversed( buffer, sink );
                        sink.bold_();
                    }
                    else if ( italic )
                    {
                        italic = false;
                        flushTraversed( buffer, sink );
                        sink.italic_();
                    }
                    else
                    {
                        buffer.append( c );
                    }
                    break;

                default:
                    if ( Character.isWhitespace( c ) )
                    {
                        buffer.append( SPACE );

                        // Skip to the last char of a sequence of white spaces.
                        while ( i + 1 < end && Character.isWhitespace( text.charAt( i + 1 ) ) )
                        {
                            ++i;
                        }
                    }
                    else
                    {
                        buffer.append( c );
                    }
            }
        }

        if ( monospaced )
        {
            throw new AptParseException( "missing '" + MONOSPACED_END_MARKUP + "'" );
        }
        if ( bold )
        {
            throw new AptParseException( "missing '" + BOLD_END_MARKUP + "'" );
        }
        if ( italic )
        {
            throw new AptParseException( "missing '" + ITALIC_END_MARKUP + "'" );
        }
        if ( link )
        {
            throw new AptParseException( "missing '" + LINK_END_MARKUP + "'" );
        }
        if ( anchor )
        {
            throw new AptParseException( "missing '" + ANCHOR_END_MARKUP + "'" );
        }

        flushTraversed( buffer, sink );
    }

    // -----------------------------------------------------------------------

    /**
     * Returns the character at position i of the given string.
     *
     * @param string the string.
     * @param length length.
     * @param i offset.
     * @return the character, or '\0' if i &gt; length.
     */
    protected static char charAt( String string, int length, int i )
    {
        return ( i < length ) ? string.charAt( i ) : '\0';
    }

    /**
     * Skip spaces.
     *
     * @param string string.
     * @param length length.
     * @param i offset.
     * @return int.
     */
    protected static int skipSpace( String string, int length, int i )
    {
        loop: for ( ; i < length; ++i )
        {
            switch ( string.charAt( i ) )
            {
                case SPACE:
                case TAB:
                    break;
                default:
                    break loop;
            }
        }
        return i;
    }

    /**
     * Replace part of a string.
     *
     * @param string the string
     * @param oldSub the substring to replace
     * @param newSub the replacement string
     * @return String
     */
    protected static String replaceAll( String string, String oldSub, String newSub )
    {
        StringBuilder replaced = new StringBuilder();
        int oldSubLength = oldSub.length();
        int begin, end;

        begin = 0;
        while ( ( end = string.indexOf( oldSub, begin ) ) >= 0 )
        {
            if ( end > begin )
            {
                replaced.append( string, begin, end );
            }
            replaced.append( newSub );
            begin = end + oldSubLength;
        }
        if ( begin < string.length() )
        {
            replaced.append( string.substring( begin ) );
        }

        return replaced.toString();
    }

    /** {@inheritDoc} */
    protected void init()
    {
        super.init();

        this.sourceContent = null;
        this.sink = null;
        this.source = null;
        this.block = null;
        this.blockFileName = null;
        this.blockLineNumber = 0;
        this.line = null;
        this.warnMessages = null;
    }

    // ----------------------------------------------------------------------
    // Private methods
    // ----------------------------------------------------------------------

    /**
     * Parse the head of the Apt source document.
     *
     * @throws AptParseException if something goes wrong.
     */
    private void traverseHead()
        throws AptParseException
    {
        sink.head();

        if ( block != null && block.getType() == TITLE )
        {
            block.traverse();
            nextBlock();
        }

        sink.head_();
    }

    /**
     * Parse the body of the Apt source document.
     *
     * @throws AptParseException if something goes wrong.
     */
    private void traverseBody()
        throws AptParseException
    {
        sink.body();

        if ( block != null )
        {
            traverseSectionBlocks();
        }

        while ( block != null )
        {
            traverseSection( 0 );
        }

        sink.body_();
    }

    /**
     * Parse a section of the Apt source document.
     *
     * @param level The section level.
     * @throws AptParseException if something goes wrong.
     */
    private void traverseSection( int level )
        throws AptParseException
    {
        if ( block == null )
        {
            return;
        }

        int type = SECTION1 + level;

        expectedBlock( type );

        switch ( level )
        {
            case 0:
                sink.section1();
                break;
            case 1:
                sink.section2();
                break;
            case 2:
                sink.section3();
                break;
            case 3:
                sink.section4();
                break;
            case 4:
                sink.section5();
                break;
            default:
                break;
        }

        block.traverse();

        nextBlock();

        traverseSectionBlocks();

        while ( block != null )
        {
            if ( block.getType() <= type )
            {
                break;
            }

            traverseSection( level + 1 );
        }

        switch ( level )
        {
            case 0:
                sink.section1_();
                break;
            case 1:
                sink.section2_();
                break;
            case 2:
                sink.section3_();
                break;
            case 3:
                sink.section4_();
                break;
            case 4:
                sink.section5_();
                break;
            default:
                break;
        }
    }

    /**
     * Parse the section blocks of the Apt source document.
     *
     * @throws AptParseException if something goes wrong.
     */
    private void traverseSectionBlocks()
        throws AptParseException
    {
        loop: while ( block != null )
        {
            switch ( block.getType() )
            {
                case PARAGRAPH:
                case VERBATIM:
                case FIGURE:
                case TABLE:
                case HORIZONTAL_RULE:
                case PG_BREAK:
                case MACRO:
                case COMMENT_BLOCK:
                    block.traverse();
                    nextBlock();
                    break;

                case LIST_ITEM:
                    traverseList();
                    break;

                case NUMBERED_LIST_ITEM:
                    traverseNumberedList();
                    break;

                case DEFINITION_LIST_ITEM:
                    traverseDefinitionList();
                    break;

                case LIST_BREAK:
                    // May be this is a list break which has not been indented
                    // very precisely.
                    nextBlock();
                    break;

                default:
                    // A section block which starts a new section.
                    break loop;
            }
        }
    }

    /**
     * Parse a list of the Apt source document.
     *
     * @throws AptParseException if something goes wrong.
     */
    private void traverseList()
        throws AptParseException
    {
        if ( block == null )
        {
            return;
        }

        expectedBlock( LIST_ITEM );

        int listIndent = block.getIndent();

        sink.list();

        sink.listItem();

        block.traverse();

        nextBlock();

        loop: while ( block != null )
        {
            int blockIndent = block.getIndent();

            switch ( block.getType() )
            {
                case PARAGRAPH:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }
                    /*FALLTHROUGH*/
                case VERBATIM:
                case MACRO:
                case FIGURE:
                case TABLE:
                case HORIZONTAL_RULE:
                case PG_BREAK:
                    block.traverse();
                    nextBlock();
                    break;

                case LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    if ( blockIndent > listIndent )
                    {
                        traverseList();
                    }
                    else
                    {
                        sink.listItem_();
                        sink.listItem();
                        block.traverse();
                        nextBlock();
                    }
                    break;

                case NUMBERED_LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    traverseNumberedList();
                    break;

                case DEFINITION_LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    traverseDefinitionList();
                    break;

                case LIST_BREAK:
                    if ( blockIndent >= listIndent )
                    {
                        nextBlock();
                    }
                    /*FALLTHROUGH*/
                default:
                    // A block which ends the list.
                    break loop;
            }
        }

        sink.listItem_();
        sink.list_();
    }

    /**
     * Parse a numbered list of the Apt source document.
     *
     * @throws AptParseException if something goes wrong.
     */
    private void traverseNumberedList()
        throws AptParseException
    {
        if ( block == null )
        {
            return;
        }
        expectedBlock( NUMBERED_LIST_ITEM );
        int listIndent = block.getIndent();

        sink.numberedList( ( (NumberedListItem) block ).getNumbering() );
        sink.numberedListItem();
        block.traverse();
        nextBlock();

        loop: while ( block != null )
        {
            int blockIndent = block.getIndent();

            switch ( block.getType() )
            {
                case PARAGRAPH:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }
                    /*FALLTHROUGH*/
                case VERBATIM:
                case FIGURE:
                case TABLE:
                case HORIZONTAL_RULE:
                case PG_BREAK:
                    block.traverse();
                    nextBlock();
                    break;

                case LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    traverseList();
                    break;

                case NUMBERED_LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    if ( blockIndent > listIndent )
                    {
                        traverseNumberedList();
                    }
                    else
                    {
                        sink.numberedListItem_();
                        sink.numberedListItem();
                        block.traverse();
                        nextBlock();
                    }
                    break;

                case DEFINITION_LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    traverseDefinitionList();
                    break;

                case LIST_BREAK:
                    if ( blockIndent >= listIndent )
                    {
                        nextBlock();
                    }
                    /*FALLTHROUGH*/
                default:
                    // A block which ends the list.
                    break loop;
            }
        }

        sink.numberedListItem_();
        sink.numberedList_();
    }

    /**
     * Parse a definition list of the Apt source document.
     *
     * @throws AptParseException if something goes wrong.
     */
    private void traverseDefinitionList()
        throws AptParseException
    {
        if ( block == null )
        {
            return;
        }
        expectedBlock( DEFINITION_LIST_ITEM );
        int listIndent = block.getIndent();

        sink.definitionList();
        sink.definitionListItem();
        block.traverse();
        nextBlock();

        loop: while ( block != null )
        {
            int blockIndent = block.getIndent();

            switch ( block.getType() )
            {
                case PARAGRAPH:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }
                    /*FALLTHROUGH*/
                case VERBATIM:
                case FIGURE:
                case TABLE:
                case HORIZONTAL_RULE:
                case PG_BREAK:
                    block.traverse();
                    nextBlock();
                    break;

                case LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    traverseList();
                    break;

                case NUMBERED_LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    traverseNumberedList();
                    break;

                case DEFINITION_LIST_ITEM:
                    if ( blockIndent < listIndent )
                    {
                        break loop;
                    }

                    if ( blockIndent > listIndent )
                    {
                        traverseDefinitionList();
                    }
                    else
                    {
                        sink.definition_();
                        sink.definitionListItem_();
                        sink.definitionListItem();
                        block.traverse();
                        nextBlock();
                    }
                    break;

                case LIST_BREAK:
                    if ( blockIndent >= listIndent )
                    {
                        nextBlock();
                    }
                    /*FALLTHROUGH*/
                default:
                    // A block which ends the list.
                    break loop;
            }
        }

        sink.definition_();
        sink.definitionListItem_();
        sink.definitionList_();
    }

    /**
     * Parse the next block of the Apt source document.
     *
     * @throws AptParseException if something goes wrong.
     */
    private void nextBlock()
        throws AptParseException
    {
        nextBlock( /*first*/false );
    }

    /**
     * Parse the next block of the Apt source document.
     *
     * @param firstBlock True if this is the first block of the Apt source document.
     * @throws AptParseException if something goes wrong.
     */
    private void nextBlock( boolean firstBlock )
        throws AptParseException
    {
        // Skip open lines.
        int length, indent, i;

        skipLoop: for ( ;; )
        {
            if ( line == null )
            {
                block = null;
                return;
            }

            length = line.length();
            indent = 0;
            for ( i = 0; i < length; ++i )
            {
                switch ( line.charAt( i ) )
                {
                    case SPACE:
                        ++indent;
                        break;
                    case TAB:
                        indent += 8;
                        break;
                    default:
                        break skipLoop;
                }
            }

            if ( i == length )
            {
                nextLine();
            }
        }

        blockFileName = source.getName();
        blockLineNumber = source.getLineNumber();
        block = null;
        switch ( line.charAt( i ) )
        {
            case STAR:
                if ( indent == 0 )
                {
                    if ( charAt( line, length, i + 1 ) == MINUS && charAt( line, length, i + 2 ) == MINUS )
                    {
                        block = new Table( indent, line );
                    }
                    else if ( charAt( line, length, i + 1 ) == STAR )
                    {
                        if ( charAt( line, length, i + 2 ) == STAR )
                        {
                            if ( charAt( line, length, i + 3 ) == STAR )
                            {
                                block = new Section5( indent, line );
                            }
                            else
                            {
                                block = new Section4( indent, line );
                            }
                        }
                        else
                        {
                            block = new Section3( indent, line );
                        }
                    }
                    else
                    {
                        block = new Section2( indent, line );
                    }
                }
                else
                {
                    block = new ListItem( indent, line );
                }
                break;
            case LEFT_SQUARE_BRACKET:
                if ( charAt( line, length, i + 1 ) == RIGHT_SQUARE_BRACKET )
                {
                    block = new ListBreak( indent, line );
                }
                else
                {
                    if ( indent == 0 )
                    {
                        block = new Figure( indent, line );
                    }
                    else
                    {
                        if ( charAt( line, length, i + 1 ) == LEFT_SQUARE_BRACKET )
                        {
                            int numbering;

                            switch ( charAt( line, length, i + 2 ) )
                            {
                                case NUMBERING_LOWER_ALPHA_CHAR:
                                    numbering = Sink.NUMBERING_LOWER_ALPHA;
                                    break;
                                case NUMBERING_UPPER_ALPHA_CHAR:
                                    numbering = Sink.NUMBERING_UPPER_ALPHA;
                                    break;
                                case NUMBERING_LOWER_ROMAN_CHAR:
                                    numbering = Sink.NUMBERING_LOWER_ROMAN;
                                    break;
                                case NUMBERING_UPPER_ROMAN_CHAR:
                                    numbering = Sink.NUMBERING_UPPER_ROMAN;
                                    break;
                                case NUMBERING:
                                default:
                                    // The first item establishes the numbering
                                    // scheme for the whole list.
                                    numbering = Sink.NUMBERING_DECIMAL;
                            }

                            block = new NumberedListItem( indent, line, numbering );
                        }
                        else
                        {
                            block = new DefinitionListItem( indent, line );
                        }
                    }
                }
                break;
            case MINUS:
                if ( charAt( line, length, i + 1 ) == MINUS && charAt( line, length, i + 2 ) == MINUS )
                {
                    if ( indent == 0 )
                    {
                        block = new Verbatim( indent, line );
                    }
                    else
                    {
                        if ( firstBlock )
                        {
                            block = new Title( indent, line );
                        }
                    }
                }
                break;
            case PLUS:
                if ( indent == 0 && charAt( line, length, i + 1 ) == MINUS && charAt( line, length, i + 2 ) == MINUS )
                {
                    block = new Verbatim( indent, line );
                }
                break;
            case EQUAL:
                if ( indent == 0 && charAt( line, length, i + 1 ) == EQUAL && charAt( line, length, i + 2 ) == EQUAL )
                {
                    block = new HorizontalRule( indent, line );
                }
                break;
            case PAGE_BREAK:
                if ( indent == 0 )
                {
                    block = new PageBreak( indent, line );
                }
                break;
            case PERCENT:
                if ( indent == 0 && charAt( line, length, i + 1 ) == LEFT_CURLY_BRACKET )
                {
                    block = new MacroBlock( indent, line );
                }
                break;
            case COMMENT:
                if ( charAt( line, length, i + 1 ) == COMMENT )
                {
                    block = new Comment( line.substring( i + 2 ) );
                }
                break;
            default:
                break;
        }

        if ( block == null )
        {
            if ( indent == 0 )
            {
                block = new Section1( indent, line );
            }
            else
            {
                block = new Paragraph( indent, line );
            }
        }
    }

    /**
     * Checks that the current block is of the expected type.
     *
     * @param type the expected type.
     * @throws AptParseException if something goes wrong.
     */
    private void expectedBlock( int type )
        throws AptParseException
    {
        int blockType = block.getType();

        if ( blockType != type )
        {
            throw new AptParseException( "expected " + TYPE_NAMES[type] + ", found " + TYPE_NAMES[blockType] );
        }
    }

    // -----------------------------------------------------------------------

    /**
     * Determine if c is an octal character.
     *
     * @param c the character.
     * @return boolean
     */
    private static boolean isOctalChar( char c )
    {
        return ( c >= '0' && c <= '7' );
    }

    /**
     * Determine if c is an hex character.
     *
     * @param c the character.
     * @return boolean
     */
    private static boolean isHexChar( char c )
    {
        return ( ( c >= '0' && c <= '9' ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) );
    }

    /**
     * Emits the text so far parsed into the given sink.
     *
     * @param buffer A StringBuilder that contains the text to be flushed.
     * @param sink The sink to receive the text.
     */
    private static void flushTraversed( StringBuilder buffer, Sink sink )
    {
        if ( buffer.length() > 0 )
        {
            sink.text( buffer.toString() );
            buffer.setLength( 0 );
        }
    }

    /**
     * Parse the given text.
     *
     * @param text the text to parse.
     * @param begin offset.
     * @param end offset.
     * @param linkAnchor a StringBuilder.
     * @return int
     * @throws AptParseException if something goes wrong.
     */
    private static int skipTraversedLinkAnchor( String text, int begin, int end, StringBuilder linkAnchor )
        throws AptParseException
    {
        int i;
        loop: for ( i = begin; i < end; ++i )
        {
            char c = text.charAt( i );
            switch ( c )
            {
                case RIGHT_CURLY_BRACKET:
                    break loop;
                case BACKSLASH:
                    if ( i + 1 < end )
                    {
                        ++i;
                        linkAnchor.append( text.charAt( i ) );
                    }
                    else
                    {
                        linkAnchor.append( BACKSLASH );
                    }
                    break;
                default:
                    linkAnchor.append( c );
            }
        }
        if ( i == end )
        {
            throw new AptParseException( "missing '" + RIGHT_CURLY_BRACKET + "'" );
        }

        return i;
    }

    /**
     * Parse the given text.
     *
     * @param text the text to parse.
     * @param begin offset.
     * @param end offset.
     * @return String
     * @throws AptParseException if something goes wrong.
     */
    private String getTraversedLink( String text, int begin, int end )
        throws AptParseException
    {
        char previous2 = LEFT_CURLY_BRACKET;
        char previous = LEFT_CURLY_BRACKET;
        int i;

        for ( i = begin; i < end; ++i )
        {
            char c = text.charAt( i );
            if ( c == RIGHT_CURLY_BRACKET && previous == RIGHT_CURLY_BRACKET && previous2 != BACKSLASH )
            {
                break;
            }

            previous2 = previous;
            previous = c;
        }
        if ( i == end )
        {
            throw new AptParseException( "missing '" + LEFT_CURLY_BRACKET + LEFT_CURLY_BRACKET + "'" );
        }

        return doGetTraversedLink( text, begin, i - 1 );
    }

    /**
     * Parse the given text.
     *
     * @param text the text to parse.
     * @param begin offset.
     * @param end offset.
     * @return String
     * @throws AptParseException if something goes wrong.
     */
    private String getTraversedAnchor( String text, int begin, int end )
        throws AptParseException
    {
        char previous = LEFT_CURLY_BRACKET;
        int i;

        for ( i = begin; i < end; ++i )
        {
            char c = text.charAt( i );
            if ( c == RIGHT_CURLY_BRACKET && previous != BACKSLASH )
            {
                break;
            }

            previous = c;
        }
        if ( i == end )
        {
            throw new AptParseException( "missing '" + RIGHT_CURLY_BRACKET + "'" );
        }

        return doGetTraversedLink( text, begin, i );
    }

    /**
     * Parse the given text.
     *
     * @param text the text to parse.
     * @param begin offset.
     * @param end offset.
     * @return String
     * @throws AptParseException if something goes wrong.
     */
    private String doGetTraversedLink( String text, int begin, int end )
        throws AptParseException
    {
        final StringBuilder buffer = new StringBuilder( end - begin );

        Sink linkSink = new SinkAdapter()
        {
            /** {@inheritDoc} */
            public void lineBreak()
            {
                buffer.append( SPACE );
            }

            /** {@inheritDoc} */
            public void nonBreakingSpace()
            {
                buffer.append( SPACE );
            }

            /** {@inheritDoc} */
            public void text( String text )
            {
                buffer.append( text );
            }
        };
        doTraverseText( text, begin, end, linkSink );

        return buffer.toString().trim();
    }

    /**
     * If debug mode is enabled, log the <code>msg</code> as is, otherwise add unique msg in <code>warnMessages</code>.
     *
     * @param key not null
     * @param msg not null
     * @see #parse(Reader, Sink)
     * @since 1.1.1
     */
    private void logMessage( String key, String msg )
    {
        msg = "[APT Parser] " + msg;
        if ( getLog().isDebugEnabled() )
        {
            getLog().debug( msg );

            return;
        }

        if ( warnMessages == null )
        {
            warnMessages = new HashMap<>();
        }

        Set<String> set = warnMessages.get( key );
        if ( set == null )
        {
            set = new TreeSet<>();
        }
        set.add( msg );
        warnMessages.put( key, set );
    }

    /**
     * @since 1.1.2
     */
    private void logWarnings()
    {
        if ( getLog().isWarnEnabled() && this.warnMessages != null && !isSecondParsing() )
        {
            for ( Map.Entry<String, Set<String>> entry : this.warnMessages.entrySet() )
            {
                for ( String msg : entry.getValue() )
                {
                    getLog().warn( msg );
                }
            }

            this.warnMessages = null;
        }
    }

    // -----------------------------------------------------------------------

    /** A block of an apt source document. */
    private abstract class Block
    {
        /** type. */
        protected int type;

        /** indent. */
        protected int indent;

        /** text. */
        protected String text;

        /** textLength. */
        protected int textLength;

        /**
         * Constructor.
         *
         * @param type the block type.
         * @param indent indent.
         * @throws AptParseException AptParseException
         */
        Block( int type, int indent )
            throws AptParseException
        {
            this( type, indent, null );
        }

        /**
         * Constructor.
         *
         * @param type type.
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Block( int type, int indent, String firstLine )
            throws AptParseException
        {
            this.type = type;
            this.indent = indent;

            // Skip first line ---
            AptParser.this.nextLine();

            if ( firstLine == null )
            {
                text = null;
                textLength = 0;
            }
            else
            {
                // Read block ---
                StringBuilder buffer = new StringBuilder( firstLine );

                while ( AptParser.this.line != null )
                {
                    String l = AptParser.this.line;
                    int length = l.length();
                    int i = 0;

                    i = skipSpace( l, length, i );
                    if ( i == length )
                    {
                        // Stop after open line and skip it.
                        AptParser.this.nextLine();
                        break;
                    }
                    else if ( ( AptParser.charAt( l, length, i ) == COMMENT
                            && AptParser.charAt( l, length, i + 1 ) == COMMENT )
                            || type == COMMENT_BLOCK )
                    {
                        // parse comments as separate blocks line by line
                        break;
                    }

                    buffer.append( EOL );
                    buffer.append( l );

                    AptParser.this.nextLine();
                }

                text = buffer.toString();
                textLength = text.length();
            }
        }

        /**
         * Return the block type.
         *
         * @return int
         */
        public final int getType()
        {
            return type;
        }

        /**
         * Return the block indent.
         *
         * @return int
         */
        public final int getIndent()
        {
            return indent;
        }

        /**
         * Parse the block.
         *
         * @throws AptParseException if something goes wrong.
         */
        public abstract void traverse()
            throws AptParseException;

        /**
         * Traverse the text.
         *
         * @param begin offset.
         * @throws AptParseException if something goes wrong.
         */
        protected void traverseText( int begin )
            throws AptParseException
        {
            traverseText( begin, text.length() );
        }

        /**
         * Traverse the text.
         *
         * @param begin offset.
         * @param end offset.
         * @throws AptParseException if something goes wrong.
         */
        protected void traverseText( int begin, int end )
            throws AptParseException
        {
            AptParser.this.doTraverseText( text, begin, end, AptParser.this.sink );
        }

        /**
         * Skip spaces.
         *
         * @return int.
         */
        protected int skipLeadingBullets()
        {
            int i = skipSpaceFrom( 0 );
            for ( ; i < textLength; ++i )
            {
                if ( text.charAt( i ) != STAR )
                {
                    break;
                }
            }
            return skipSpaceFrom( i );
        }

        /**
         * Skip brackets.
         *
         * @param i offset.
         * @return int.
         * @throws AptParseException if something goes wrong.
         */
        protected int skipFromLeftToRightBracket( int i )
            throws AptParseException
        {
            char previous = LEFT_SQUARE_BRACKET;
            for ( ++i; i < textLength; ++i )
            {
                char c = text.charAt( i );
                if ( c == RIGHT_SQUARE_BRACKET && previous != BACKSLASH )
                {
                    break;
                }
                previous = c;
            }
            if ( i == textLength )
            {
                throw new AptParseException( "missing '" + RIGHT_SQUARE_BRACKET + "'" );
            }

            return i;
        }

        /**
         * Skip spaces.
         *
         * @param i offset.
         * @return int.
         */
        protected final int skipSpaceFrom( int i )
        {
            return AptParser.skipSpace( text, textLength, i );
        }
    }

    /** A ListBreak Block. */
    private class ListBreak
        extends AptParser.Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        ListBreak( int indent, String firstLine )
            throws AptParseException
        {
            super( AptParser.LIST_BREAK, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            throw new AptParseException( "internal error: traversing list break" );
        }
    }

    /** A Title Block. */
    private class Title
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Title( int indent, String firstLine )
            throws AptParseException
        {
            super( TITLE, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            StringTokenizer lines = new StringTokenizer( text, EOL );
            int separator = -1;
            boolean firstLine = true;
            boolean title = false;
            boolean author = false;
            boolean date = false;

            loop: while ( lines.hasMoreTokens() )
            {
                String line = lines.nextToken().trim();
                int lineLength = line.length();

                if ( AptParser.charAt( line, lineLength, 0 ) == MINUS
                    && AptParser.charAt( line, lineLength, 1 ) == MINUS
                    && AptParser.charAt( line, lineLength, 2 ) == MINUS )
                {
                    switch ( separator )
                    {
                        case 0:
                            if ( title )
                            {
                                AptParser.this.sink.title_();
                            }
                            else
                            {
                                throw new AptParseException( "missing title" );
                            }
                            break;
                        case 1:
                            if ( author )
                            {
                                AptParser.this.sink.author_();
                            }
                            break;
                        case 2:
                            // Note that an extra decorative line is allowed
                            // at the end of the author.
                            break loop;
                        default:
                            break;
                    }

                    ++separator;
                    firstLine = true;
                }
                else
                {
                    if ( firstLine )
                    {
                        firstLine = false;
                        switch ( separator )
                        {
                            case 0:
                                title = true;
                                AptParser.this.sink.title();
                                break;
                            case 1:
                                author = true;
                                AptParser.this.sink.author();
                                break;
                            case 2:
                                date = true;
                                AptParser.this.sink.date();
                                break;
                            default:
                                break;
                        }
                    }
                    else
                    {
                        // An implicit lineBreak separates title lines.
                        AptParser.this.sink.lineBreak();
                    }

                    AptParser.this.doTraverseText( line, 0, lineLength, AptParser.this.sink );
                }
            }

            switch ( separator )
            {
                case 0:
                    if ( title )
                    {
                        AptParser.this.sink.title_();
                    }
                    else
                    {
                        throw new AptParseException( "missing title" );
                    }
                    break;
                case 1:
                    if ( author )
                    {
                        AptParser.this.sink.author_();
                    }
                    break;
                case 2:
                    if ( date )
                    {
                        AptParser.this.sink.date_();
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /** A Section Block. */
    private abstract class Section
        extends Block
    {
        /**
         * Constructor.
         *
         * @param type type.
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Section( int type, int indent, String firstLine )
            throws AptParseException
        {
            super( type, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            Title();
            traverseText( skipLeadingBullets() );
            Title_();
        }

        /** Start a title. */
        public abstract void Title();

        /** End a title. */
        public abstract void Title_();
    }

    /** A Section1 Block. */
    private class Section1
        extends Section
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Section1( int indent, String firstLine )
            throws AptParseException
        {
            super( SECTION1, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void Title()
        {
            AptParser.this.sink.sectionTitle1();
        }

        /** {@inheritDoc} */
        public void Title_()
        {
            AptParser.this.sink.sectionTitle1_();
        }
    }

    /** A Section2 Block. */
    private class Section2
        extends Section
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Section2( int indent, String firstLine )
            throws AptParseException
        {
            super( SECTION2, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void Title()
        {
            AptParser.this.sink.sectionTitle2();
        }

        /** {@inheritDoc} */
        public void Title_()
        {
            AptParser.this.sink.sectionTitle2_();
        }
    }

    /** A Section3 Block. */
    public class Section3
        extends Section
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Section3( int indent, String firstLine )
            throws AptParseException
        {
            super( SECTION3, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void Title()
        {
            AptParser.this.sink.sectionTitle3();
        }

        /** {@inheritDoc} */
        public void Title_()
        {
            AptParser.this.sink.sectionTitle3_();
        }
    }

    /** A Section4 Block. */
    private class Section4
        extends Section
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Section4( int indent, String firstLine )
            throws AptParseException
        {
            super( SECTION4, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void Title()
        {
            AptParser.this.sink.sectionTitle4();
        }

        /** {@inheritDoc} */
        public void Title_()
        {
            AptParser.this.sink.sectionTitle4_();
        }
    }

    /** A Section5 Block. */
    private class Section5
        extends Section
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Section5( int indent, String firstLine )
            throws AptParseException
        {
            super( SECTION5, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void Title()
        {
            AptParser.this.sink.sectionTitle5();
        }

        /** {@inheritDoc} */
        public void Title_()
        {
            AptParser.this.sink.sectionTitle5_();
        }
    }

    /** A Paragraph Block. */
    private class Paragraph
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Paragraph( int indent, String firstLine )
            throws AptParseException
        {
            super( PARAGRAPH, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            AptParser.this.sink.paragraph();
            traverseText( skipSpaceFrom( 0 ) );
            AptParser.this.sink.paragraph_();
        }
    }

    /** A Comment Block. */
    private class Comment
        extends Block
    {
        /**
         * Constructor.
         *
         * @param line the comment line.
         * @throws AptParseException AptParseException
         */
        Comment( String line )
            throws AptParseException
        {
            super( COMMENT_BLOCK, 0, line );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            if ( isEmitComments() )
            {
                AptParser.this.sink.comment( text );
            }
        }
    }

    /** A Verbatim Block. */
    private class Verbatim
        extends Block
    {
        /** boxed. */
        private boolean boxed;

        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Verbatim( int indent, String firstLine )
            throws AptParseException
        {
            super( VERBATIM, indent, null );

            // Read block (first line already skipped) ---

            StringBuilder buffer = new StringBuilder();
            char firstChar = firstLine.charAt( 0 );
            boxed = ( firstChar == PLUS );

            while ( AptParser.this.line != null )
            {
                String l = AptParser.this.line;
                int length = l.length();

                if ( AptParser.charAt( l, length, 0 ) == firstChar && AptParser.charAt( l, length, 1 ) == MINUS
                    && AptParser.charAt( l, length, 2 ) == MINUS )
                {
                    AptParser.this.nextLine();

                    break;
                }

                // Expand tabs ---

                int prevColumn, column;

                column = 0;

                for ( int i = 0; i < length; ++i )
                {
                    char c = l.charAt( i );

                    if ( c == TAB )
                    {
                        prevColumn = column;

                        column = ( ( column + 1 + TAB_WIDTH - 1 ) / TAB_WIDTH ) * TAB_WIDTH;

                        buffer.append( SPACES, 0, column - prevColumn );
                    }
                    else
                    {
                        ++column;
                        buffer.append( c );
                    }
                }
                buffer.append( EOL );

                AptParser.this.nextLine();
            }

            // The last '\n' is mandatory before the "---" delimeter but is
            // not part of the verbatim text.
            textLength = buffer.length();

            if ( textLength > 0 )
            {
                --textLength;

                buffer.setLength( textLength );
            }

            text = buffer.toString();
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            AptParser.this.sink.verbatim( boxed ? SinkEventAttributeSet.BOXED : null );
            AptParser.this.sink.text( text );
            AptParser.this.sink.verbatim_();
        }
    }

    /** A Figure Block. */
    private class Figure
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Figure( int indent, String firstLine )
            throws AptParseException
        {
            super( FIGURE, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            AptParser.this.sink.figure();

            int i = skipFromLeftToRightBracket( 0 );
            AptParser.this.sink.figureGraphics( text.substring( 1, i ) );

            i = skipSpaceFrom( i + 1 );
            if ( i < textLength )
            {
                AptParser.this.sink.figureCaption();
                traverseText( i );
                AptParser.this.sink.figureCaption_();
            }

            AptParser.this.sink.figure_();
        }
    }

    /** A Table Block. */
    private class Table
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        Table( int indent, String firstLine )
            throws AptParseException
        {
            super( TABLE, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            int captionIndex = -1;
            int nextLineIndex = 0;
            int init = 2;
            int[] justification = null;
            int rows = 0;
            int columns = 0;
            StringBuilder[] cells = null;
            boolean[] headers = null;
            boolean grid;

            AptParser.this.sink.table();

            while ( nextLineIndex < textLength )
            {
                int i = text.indexOf( "*--", nextLineIndex );
                if ( i < 0 )
                {
                    captionIndex = nextLineIndex;
                    break;
                }

                String line;
                i = text.indexOf( '\n', nextLineIndex );
                if ( i < 0 )
                {
                    line = text.substring( nextLineIndex );
                    nextLineIndex = textLength;
                }
                else
                {
                    line = text.substring( nextLineIndex, i );
                    nextLineIndex = i + 1;
                }
                int lineLength = line.length();

                if ( line.indexOf( "*--" ) == 0 )
                {
                    if ( init == 2 )
                    {
                        init = 1;
                        justification = parseJustification( line, lineLength );
                        columns = justification.length;
                        cells = new StringBuilder[columns];
                        headers = new boolean[columns];
                        for ( i = 0; i < columns; ++i )
                        {
                            cells[i] = new StringBuilder();
                            headers[i] = false;
                        }
                    }
                    else
                    {
                        if ( traverseRow( cells, headers, justification ) )
                        {
                            ++rows;
                        }
                        justification = parseJustification( line, lineLength );
                    }
                }
                else
                {
                    if ( init == 1 )
                    {
                        init = 0;
                        grid = ( AptParser.charAt( line, lineLength, 0 ) == PIPE );
                        AptParser.this.sink.tableRows( justification, grid );
                    }

                    line = replaceAll( line, "\\|", "\\u007C" );

                    StringTokenizer cellLines = new StringTokenizer( line, "|", true );

                    i = 0;
                    boolean processedGrid = false;
                    while ( cellLines.hasMoreTokens() )
                    {
                        String cellLine = cellLines.nextToken();
                        if ( "|".equals( cellLine ) )
                        {
                            if ( processedGrid )
                            {
                                headers[i] = true;
                            }
                            else
                            {
                                processedGrid = true;
                                headers[i] = false;
                            }
                            continue;
                        }
                        processedGrid = false;
                        cellLine = replaceAll( cellLine, "\\", "\\u00A0" ); // linebreak
                        // Escaped special characters: \~, \=, \-, \+, \*, \[, \], \<, \>, \{, \}, \\.
                        cellLine = replaceAll( cellLine, "\\u00A0~", "\\~" );
                        cellLine = replaceAll( cellLine, "\\u00A0=", "\\=" );
                        cellLine = replaceAll( cellLine, "\\u00A0-", "\\-" );
                        cellLine = replaceAll( cellLine, "\\u00A0+", "\\+" );
                        cellLine = replaceAll( cellLine, "\\u00A0*", "\\*" );
                        cellLine = replaceAll( cellLine, "\\u00A0[", "\\[" );
                        cellLine = replaceAll( cellLine, "\\u00A0]", "\\]" );
                        cellLine = replaceAll( cellLine, "\\u00A0<", "\\<" );
                        cellLine = replaceAll( cellLine, "\\u00A0>", "\\>" );
                        cellLine = replaceAll( cellLine, "\\u00A0{", "\\{" );
                        cellLine = replaceAll( cellLine, "\\u00A0}", "\\}" );
                        cellLine = replaceAll( cellLine, "\\u00A0u", "\\u" );
                        cellLine = replaceAll( cellLine, "\\u00A0\\u00A0", "\\\\" );
                        cellLine = cellLine.trim();

                        StringBuilder cell = cells[i];
                        if ( cellLine.length() > 0 )
                        {
                            // line break in table cells
                            if ( cell.toString().trim().endsWith( "\\u00A0" ) )
                            {
                                cell.append( "\\\n" );
                            }
                            else
                            {
                                if ( cell.length() != 0 )
                                {
                                    // Always add a space for multi line tables cells
                                    cell.append( " " );
                                }
                            }

                            cell.append( cellLine );
                        }

                        ++i;
                        if ( i == columns )
                        {
                            break;
                        }
                    }
                }
            }
            if ( rows == 0 )
            {
                throw new AptParseException( "no table rows" );
            }
            AptParser.this.sink.tableRows_();

            if ( captionIndex >= 0 )
            {
                AptParser.this.sink.tableCaption();
                AptParser.this.doTraverseText( text, captionIndex, textLength, AptParser.this.sink );
                AptParser.this.sink.tableCaption_();
            }

            AptParser.this.sink.table_();
        }

        /**
         * Parse a table justification line.
         *
         * @param jline the justification line.
         * @param lineLength the length of the line. Must be > 2.
         * @return int[]
         * @throws AptParseException if something goes wrong.
         */
        private int[] parseJustification( String jline, int lineLength )
            throws AptParseException
        {
            int columns = 0;

            for ( int i = 2 /*Skip '*--'*/; i < lineLength; ++i )
            {
                switch ( jline.charAt( i ) )
                {
                    case STAR:
                    case PLUS:
                    case COLON:
                        ++columns;
                        break;
                    default:
                        break;
                }
            }

            if ( columns == 0 )
            {
                throw new AptParseException( "no columns specified" );
            }

            int[] justification = new int[columns];
            columns = 0;
            for ( int i = 2; i < lineLength; ++i )
            {
                switch ( jline.charAt( i ) )
                {
                    case STAR:
                        justification[columns++] = Sink.JUSTIFY_CENTER;
                        break;
                    case PLUS:
                        justification[columns++] = Sink.JUSTIFY_LEFT;
                        break;
                    case COLON:
                        justification[columns++] = Sink.JUSTIFY_RIGHT;
                        break;
                    default:
                        break;
                }
            }

            return justification;
        }

        /**
         * Traverse a table row.
         *
         * @param cells The table cells.
         * @param headers true for header cells.
         * @param justification the justification for each cell.
         * @return boolean
         * @throws AptParseException if something goes wrong.
         */
        private boolean traverseRow( StringBuilder[] cells, boolean[] headers, int[] justification )
            throws AptParseException
        {
            // Skip empty row (a decorative line).
            boolean traversed = false;
            for ( StringBuilder cell1 : cells )
            {
                if ( cell1.length() > 0 )
                {
                    traversed = true;
                    break;
                }
            }

            if ( traversed )
            {
                AptParser.this.sink.tableRow();
                for ( int i = 0; i < cells.length; ++i )
                {
                    StringBuilder cell = cells[i];

                    SinkEventAttributes justif;
                    switch ( justification[i] )
                    {
                        case Sink.JUSTIFY_CENTER:
                            justif = SinkEventAttributeSet.CENTER;
                            break;
                        case Sink.JUSTIFY_LEFT:
                            justif = SinkEventAttributeSet.LEFT;
                            break;
                        case Sink.JUSTIFY_RIGHT:
                            justif = SinkEventAttributeSet.RIGHT;
                            break;
                        default:
                            justif = SinkEventAttributeSet.LEFT;
                            break;
                    }
                    SinkEventAttributeSet event = new SinkEventAttributeSet();
                    event.addAttributes( justif );

                    if ( headers[i] )
                    {
                        AptParser.this.sink.tableHeaderCell( event );
                    }
                    else
                    {
                        AptParser.this.sink.tableCell( event );
                    }
                    if ( cell.length() > 0 )
                    {
                        AptParser.this.doTraverseText( cell.toString(), 0, cell.length(), AptParser.this.sink );
                        cell.setLength( 0 );
                    }
                    if ( headers[i] )
                    {
                        AptParser.this.sink.tableHeaderCell_();
                        // DOXIA-404: reset header for next row
                        headers[i] = false;
                    }
                    else
                    {
                        AptParser.this.sink.tableCell_();
                    }
                }
                AptParser.this.sink.tableRow_();
            }

            return traversed;
        }
    }

    /** A ListItem Block. */
    private class ListItem
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        ListItem( int indent, String firstLine )
            throws AptParseException
        {
            super( LIST_ITEM, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            traverseText( skipLeadingBullets() );
        }
    }

    /** A NumberedListItem Block. */
    private class NumberedListItem
        extends Block
    {
        /** numbering. */
        private int numbering;

        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @param number numbering.
         * @throws AptParseException AptParseException
         */
        NumberedListItem( int indent, String firstLine, int number )
            throws AptParseException
        {
            super( NUMBERED_LIST_ITEM, indent, firstLine );
            this.numbering = number;
        }

        /**
         * getNumbering.
         *
         * @return int
         */
        public int getNumbering()
        {
            return numbering;
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            traverseText( skipItemNumber() );
        }

        /**
         * skipItemNumber.
         *
         * @return int
         * @throws AptParseException AptParseException
         */
        private int skipItemNumber()
            throws AptParseException
        {
            int i = skipSpaceFrom( 0 );

            char prevChar = SPACE;
            for ( ; i < textLength; ++i )
            {
                char c = text.charAt( i );
                if ( c == RIGHT_SQUARE_BRACKET && prevChar == RIGHT_SQUARE_BRACKET )
                {
                    break;
                }
                prevChar = c;
            }

            if ( i == textLength )
            {
                throw new AptParseException( "missing '" + RIGHT_SQUARE_BRACKET + RIGHT_SQUARE_BRACKET + "'" );
            }

            return skipSpaceFrom( i + 1 );
        }
    }

    /** A DefinitionListItem Block. */
    private class DefinitionListItem
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        DefinitionListItem( int indent, String firstLine )
            throws AptParseException
        {
            super( DEFINITION_LIST_ITEM, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            int i = skipSpaceFrom( 0 );
            int j = skipFromLeftToRightBracket( i );

            AptParser.this.sink.definedTerm();
            traverseText( i + 1, j );
            AptParser.this.sink.definedTerm_();

            j = skipSpaceFrom( j + 1 );
            if ( j == textLength )
            {
                // TODO: this doesn't handle the case of a dd in a paragraph
                //throw new AptParseException( "no definition" );
            }

            AptParser.this.sink.definition();
            traverseText( j );
        }
    }

    /** A HorizontalRule Block. */
    private class HorizontalRule
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        HorizontalRule( int indent, String firstLine )
            throws AptParseException
        {
            super( HORIZONTAL_RULE, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            AptParser.this.sink.horizontalRule();
        }
    }

    /** A PageBreak Block. */
    private class PageBreak
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        PageBreak( int indent, String firstLine )
            throws AptParseException
        {
            super( PG_BREAK, indent, firstLine );
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            AptParser.this.sink.pageBreak();
        }
    }

    /** A MacroBlock Block. */
    private class MacroBlock
        extends Block
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        MacroBlock( int indent, String firstLine )
            throws AptParseException
        {
            super( MACRO, indent );

            text = firstLine;
        }

        /** {@inheritDoc} */
        public void traverse()
            throws AptParseException
        {
            if ( isSecondParsing() )
            {
                return;
            }

            final int start = text.indexOf( '{' );
            final int end = text.indexOf( '}' );

            String s = text.substring( start + 1, end );

            s = escapeForMacro( s );

            String[] params = StringUtils.split( s, "|" );

            String macroId = params[0];

            Map<String, Object> parameters = new HashMap<>();

            for ( int i = 1; i < params.length; i++ )
            {
                String[] param = StringUtils.split( params[i], "=" );

                if ( param.length == 1 )
                {
                    throw new AptParseException( "Missing 'key=value' pair for macro parameter: " + params[i] );
                }

                String key = unescapeForMacro( param[0] );
                String value = unescapeForMacro( param[1] );

                parameters.put( key, value );
            }

            // getBasedir() does not work in multi-module builds, see DOXIA-373
            // the basedir should be injected from here, see DOXIA-224
            MacroRequest request = new MacroRequest( sourceContent, new AptParser(), parameters, getBasedir() );
            try
            {
                AptParser.this.executeMacro( macroId, request, sink );
            }
            catch ( MacroExecutionException e )
            {
                throw new AptParseException( "Unable to execute macro in the APT document", e );
            }
            catch ( MacroNotFoundException e )
            {
                throw new AptParseException( "Unable to find macro used in the APT document", e );
            }
        }

        /**
         * escapeForMacro
         *
         * @param s String
         * @return String
         */
        private String escapeForMacro( String s )
        {
            if ( s == null || s.length() < 1 )
            {
                return s;
            }

            String result = s;

            // use some outrageously out-of-place chars for text
            // (these are device control one/two in unicode)
            result = StringUtils.replace( result, "\\=", "\u0011" );
            result = StringUtils.replace( result, "\\|", "\u0012" );

            return result;
        }

        /**
         * unescapeForMacro
         *
         * @param s String
         * @return String
         */
        private String unescapeForMacro( String s )
        {
            if ( s == null || s.length() < 1 )
            {
                return s;
            }

            String result = s;

            result = StringUtils.replace( result, "\u0011", "=" );
            result = StringUtils.replace( result, "\u0012", "|" );

            return result;
        }
    }
}
