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 > 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.substring( 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<String, Set<String>>();
        }

        Set<String> set = warnMessages.get( key );
        if ( set == null )
        {
            set = new TreeSet<String>();
        }
        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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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. */
    private class Section3
        extends Section
    {
        /**
         * Constructor.
         *
         * @param indent indent.
         * @param firstLine the first line.
         * @throws AptParseException AptParseException
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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 ( int i = 0; i < cells.length; ++i )
            {
                if ( cells[i].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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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
         */
        public 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<String, Object>();

            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;
        }
    }
}
