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

/*
 * 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 java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;

import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.AbstractXmlSink;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.doxia.util.DoxiaUtils;
import org.apache.maven.doxia.util.HtmlTools;
import org.codehaus.plexus.util.FileUtils;

/**
 * <a href="http://www.oasis-open.org/docbook">Docbook</a> Sink implementation.
 * <br>
 * It uses the Docbook v4.4 DTD <a href="http://www.oasis-open.org/docbook/sgml/4.4/docbookx.dtd">
 * http://www.oasis-open.org/docbook/sgml/4.4/docbookx.dtd</a>.
 *
 * @version $Id$
 * @since 1.0
 */
public class DocBookSink
    extends AbstractXmlSink
    implements DocbookMarkup, SimplifiedDocbookMarkup
{
    /** DocBook V4.4 SGML public id: "-//OASIS//DTD DocBook V4.4//EN"
     * @deprecated since 1.1, use {@link DocbookMarkup#DEFAULT_SGML_PUBLIC_ID} instead of. */
    public static final String DEFAULT_SGML_PUBLIC_ID = DocbookMarkup.DEFAULT_SGML_PUBLIC_ID;

    /** DocBook XML V4.4 XML public id: "-//OASIS//DTD DocBook XML V4.4//EN"
     * @deprecated since 1.1, use {@link DocbookMarkup#DEFAULT_XML_PUBLIC_ID} instead of. */
    public static final String DEFAULT_XML_PUBLIC_ID = DocbookMarkup.DEFAULT_XML_PUBLIC_ID;

    /** DocBook XML V4.4 XML system id: "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
     * @deprecated since 1.1, use {@link DocbookMarkup#DEFAULT_XML_SYSTEM_ID} instead of. */
    public static final String DEFAULT_XML_SYSTEM_ID = DocbookMarkup.DEFAULT_XML_SYSTEM_ID;

    /** DocBook XML V4.4 SGML system id: "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
     * @deprecated since 1.1, use {@link DocbookMarkup#DEFAULT_SGML_SYSTEM_ID} instead of. */
    public static final String DEFAULT_SGML_SYSTEM_ID = DocbookMarkup.DEFAULT_SGML_SYSTEM_ID;

    /** The output writer. */
    private PrintWriter out;

    /** xmlMode. */
    private boolean xmlMode = false;

    /** styleSheet. */
    private String styleSheet = null;

    /** language. */
    private String lang = null;

    /** publicId. */
    private String publicId = null;

    /** systemId. */
    private String systemId = null;

    /** italicBegin. */
    private String italicBeginTag;

    /** italicEnd. */
    private String italicEndTag;

    /** boldBegin. */
    private String boldBeginTag;

    /** boldEnd. */
    private String boldEndTag;

    /** monospacedBegin. */
    private String monospacedBeginTag;

    /** monospacedEnd. */
    private String monospacedEndTag;

    /** horizontalRule. */
    private String horizontalRuleElement;

    /** pageBreak. */
    private String pageBreakElement;

    /** lineBreak. */
    private String lineBreakElement;

    /** An image source file. */
    private String graphicsFileName;

    /** hasTitle. */
    private boolean hasTitle;

    /** authorDate. */
    private boolean authorDateFlag;

    /** verbatim. */
    private boolean verbatimFlag;

    /** externalLink. */
    private boolean externalLinkFlag;

    /** tableHasCaption. */
    private boolean tableHasCaption;

    /** Used for table rows. */
    private PrintWriter savedOut;

    /** tableRows. */
    private String tableRows;

    /** tableRows writer. */
    private StringWriter tableRowsWriter;

    /** tableHasGrid. */
    private boolean tableHasGrid;

    private boolean skip;

    private boolean paragraph;

    private String encoding;

    /** Keep track of the closing tags for inline events. */
    protected Stack<List<String>> inlineStack = new Stack<List<String>>();

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

    /**
     * Constructor, initialize the Writer.
     *
     * @param writer not null writer to write the result. <b>Should</b> be an UTF-8 Writer.
     * You could use <code>newXmlWriter</code> methods from {@link org.codehaus.plexus.util.WriterFactory}.
     */
    protected DocBookSink( Writer writer )
    {
        this( writer, null );
    }

    /**
     * Constructor, initialize the Writer and tells which encoding is used.
     *
     * @param writer not null writer to write the result.
     * @param encoding the encoding used, that should be written to the generated HTML content
     * if not <code>null</code>.
     */
    protected DocBookSink( Writer writer, String encoding )
    {
        this.out = new PrintWriter( writer );
        this.encoding = encoding;

        setItalicElement( "<emphasis>" );
        setBoldElement( "<emphasis role=\"bold\">" );
        setMonospacedElement( "<literal>" );
        setHorizontalRuleElement( "<!-- HR -->" );
        setPageBreakElement( "<!-- PB -->" );
        setLineBreakElement( "<!-- LB -->" );
    }

    /**
     * Constructor, initialize the Writer and tells which encoding and languageId are used.
     *
     * @param writer not null writer to write the result.
     * @param encoding the encoding used, that should be written to the generated HTML content
     * if not <code>null</code>.
     * @param languageId language identifier for the root element as defined by
     * <a href="ftp://ftp.isi.edu/in-notes/bcp/bcp47.txt">IETF BCP 47</a>, Tags for the Identification of Languages;
     * in addition, the empty string may be specified.
     * @since 1.1
     */
    protected DocBookSink( Writer writer, String encoding, String languageId )
    {
        this( writer, encoding );

        this.lang = languageId;
    }

    /**
     * <p>escapeSGML</p>
     *
     * @param text The text to escape.
     * @param xmlMode xmlMode.
     * @return The escaped text.
     * @deprecated Use HtmlTools#escapeHTML(String,boolean).
     */
    public static final String escapeSGML( String text, boolean xmlMode )
    {
        return HtmlTools.escapeHTML( text, xmlMode );
    }

    /**
     * Sets the xml mode.
     *
     * @param mode the mode to set.
     * @deprecated xml mode is not used.
     */
    public void setXMLMode( boolean mode )
    {
        this.xmlMode = mode;
    }

    /**
     * Returns the current xmlMode.
     *
     * @return the current xmlMode.
     * @deprecated xml mode is not used.
     */
    public boolean isXMLMode()
    {
        return xmlMode;
    }

    /**
     * Sets the encoding. The encoding specified here must be consistent with then encoding
     * used in the Writer used by this DocBookSink instance.
     *
     * @param enc the encoding to set.
     */
    public void setEncoding( String enc )
    {
        encoding = enc;
    }

    /**
     * Returns the encoding.
     *
     * @return the encoding set (can be <code>null</code>).
     */
    public String getEncoding()
    {
        return encoding;
    }

    /**
     * Sets the styleSheet.
     *
     * @param sheet the styleSheet to set.
     */
    public void setStyleSheet( String sheet )
    {
        this.styleSheet = sheet;
    }

    /**
     * Returns the current styleSheet.
     *
     * @return the current styleSheet.
     */
    public String getStyleSheet()
    {
        return styleSheet;
    }

    /**
     * Sets the publicId.
     *
     * @param id the publicId to set.
     */
    public void setPublicId( String id )
    {
        this.publicId = id;
    }

    /**
     * Returns the current publicId.
     *
     * @return the current publicId.
     */
    public String getPublicId()
    {
        return publicId;
    }

    /**
     * Sets the systemId.
     *
     * @param id the systemId to set.
     */
    public void setSystemId( String id )
    {
        this.systemId = id;
    }

    /**
     * Returns the current systemId.
     *
     * @return the current systemId.
     */
    public String getSystemId()
    {
        return systemId;
    }

    /**
     * Sets the language.
     *
     * @param language the language to set.
     */
    public void setLanguage( String language )
    {
        this.lang = language;
    }

    /**
     * Returns the current language.
     *
     * @return the current language.
     */
    public String getLanguage()
    {
        return lang;
    }

    /**
     * Sets the current italicBeginTag and constructs the corresponding end tag from it.
     *
     * @param tag the tag to set. If tag is null, the empty string is used.
     */
    public void setItalicElement( String tag )
    {
        if ( tag == null )
        {
            tag = "";
        }
        this.italicBeginTag = tag;
        italicEndTag = makeEndTag( italicBeginTag );
    }

    /**
     * Constructs the corresponding end tag from the given begin tag.
     *
     * @param beginTag the begin tag to set. If null, the empty string is returned.
     * @return the corresponding end tag.
     */
    private String makeEndTag( String beginTag )
    {
        int length = beginTag.length();
        if ( length == 0 )
        {
            return "";
        }

        if ( beginTag.charAt( 0 ) != '<' || beginTag.charAt( length - 1 ) != '>' )
        {
            throw new IllegalArgumentException( "'" + beginTag + "', not a tag" );
        }

        StringTokenizer tokens = new StringTokenizer( beginTag, "<> \t\n\r\f" );
        if ( !tokens.hasMoreTokens() )
        {
            throw new IllegalArgumentException( "'" + beginTag + "', invalid tag" );
        }

        return "</" + tokens.nextToken() + ">";
    }

    /**
     * Returns the current italicBeginTag.
     *
     * @return the current italicBeginTag. Defaults to {@code <emphasis>}.
     */
    public String getItalicElement()
    {
        return italicBeginTag;
    }

    /**
     * Sets the current boldBeginTag and constructs the corresponding end tag from it.
     *
     * @param tag the tag to set. If tag is null, the empty string is used.
     */
    public void setBoldElement( String tag )
    {
        if ( tag == null )
        {
            tag = "";
        }
        this.boldBeginTag = tag;
        boldEndTag = makeEndTag( boldBeginTag );
    }

    /**
     * Returns the current boldBeginTag.
     *
     * @return the current boldBeginTag. Defaults to {@code <emphasis role=\"bold\">}.
     */
    public String getBoldElement()
    {
        return boldBeginTag;
    }

    /**
     * Sets the current monospacedBeginTag and constructs the corresponding end tag from it.
     *
     * @param tag the tag to set. If tag is null, the empty string is used.
     */
    public void setMonospacedElement( String tag )
    {
        if ( tag == null )
        {
            tag = "";
        }
        this.monospacedBeginTag = tag;
        monospacedEndTag = makeEndTag( monospacedBeginTag );
    }

    /**
     * Returns the current monospacedBeginTag.
     *
     * @return the current monospacedBeginTag. Defaults to {@code <literal>}.
     */
    public String getMonospacedElement()
    {
        return monospacedBeginTag;
    }

    /**
     * Sets the current horizontalRuleElement.
     *
     * @param element the element to set.
     */
    public void setHorizontalRuleElement( String element )
    {
        this.horizontalRuleElement = element;
    }

    /**
     * Returns the current horizontalRuleElement.
     *
     * @return the current horizontalRuleElement. Defaults to "<!-- HR -->".
     */
    public String getHorizontalRuleElement()
    {
        return horizontalRuleElement;
    }

    /**
     * Sets the current pageBreakElement.
     *
     * @param element the element to set.
     */
    public void setPageBreakElement( String element )
    {
        this.pageBreakElement = element;
    }

    /**
     * Returns the current pageBreakElement.
     *
     * @return the current pageBreakElement. Defaults to "<!-- PB -->".
     */
    public String getPageBreakElement()
    {
        return pageBreakElement;
    }

    /**
     * Sets the current lineBreakElement.
     *
     * @param element the element to set.
     */
    public void setLineBreakElement( String element )
    {
        this.lineBreakElement = element;
    }

    /**
     * Returns the current lineBreakElement.
     *
     * @return the current lineBreakElement. Defaults to "<!-- LB -->".
     */
    public String getLineBreakElement()
    {
        return lineBreakElement;
    }

    /**
     * Reset all variables.
     *
     * @deprecated since 1.1.2, use {@link #init()} instead of.
     */
    protected void resetState()
    {
       init();
    }

    /** {@inheritDoc} */
    protected void init()
    {
        hasTitle = false;
        authorDateFlag = false;
        verbatimFlag = false;
        externalLinkFlag = false;
        graphicsFileName = null;
        tableHasCaption = false;
        savedOut = null;
        tableRows = null;
        tableHasGrid = false;
    }

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

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#DEFAULT_XML_PUBLIC_ID
     * @see SimplifiedDocbookMarkup#DEFAULT_XML_SYSTEM_ID
     * @see SimplifiedDocbookMarkup#ARTICLE_TAG
     */
    public void head()
    {
        init();

        MutableAttributeSet att = writeXmlHeader( "article" );

        writeStartTag( SimplifiedDocbookMarkup.ARTICLE_TAG, att );
    }

    /**
     * writeXmlHeader.
     *
     * @param root not null.
     * @return an attribute set.
     * @see SimplifiedDocbookMarkup#DEFAULT_XML_PUBLIC_ID
     * @see SimplifiedDocbookMarkup#DEFAULT_XML_SYSTEM_ID
     * @see SimplifiedDocbookMarkup#ARTICLE_TAG
     * @since 1.1
     */
    protected MutableAttributeSet writeXmlHeader( String root )
    {
        markup( "<?xml version=\"1.0\"" );
        if ( encoding != null )
        {
            markup( " encoding=\"" + encoding + "\"" );
        }
        markup( "?>" );

        if ( styleSheet != null )
        {
            markup( "<?xml-stylesheet type=\"text/css\" href=\"" + styleSheet + "\" ?>" );
        }

        String pubId;
        markup( "<!DOCTYPE " + root + " PUBLIC" );

        if ( publicId == null )
        {
            pubId = SimplifiedDocbookMarkup.DEFAULT_XML_PUBLIC_ID;
        }
        else
        {
            pubId = publicId;
        }
        markup( " \"" + pubId + "\"" );
        String sysId = systemId;
        if ( sysId == null )
        {
                sysId = SimplifiedDocbookMarkup.DEFAULT_XML_SYSTEM_ID;
        }
        markup( " \"" + sysId + "\">" );

        MutableAttributeSet att = new SimpleAttributeSet();
        if ( lang != null )
        {
            att.addAttribute( LANG_ATTRIBUTE, lang );
        }
        return att;
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ARTICLEINFO_TAG
     */
    public void head_()
    {
        if ( hasTitle )
        {
            writeEndTag( SimplifiedDocbookMarkup.ARTICLEINFO_TAG );
            hasTitle = false;
        }
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ARTICLEINFO_TAG
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void title()
    {
        writeStartTag( SimplifiedDocbookMarkup.ARTICLEINFO_TAG );
        writeStartTag( SimplifiedDocbookMarkup.TITLE_TAG );
        hasTitle = true;
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void title_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#CORPAUTHOR_TAG
     */
    public void author()
    {
        authorDateFlag = true;
        writeStartTag( SimplifiedDocbookMarkup.CORPAUTHOR_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#CORPAUTHOR_TAG
     */
    public void author_()
    {
        writeEndTag( SimplifiedDocbookMarkup.CORPAUTHOR_TAG );
        authorDateFlag = false;
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#DATE_TAG
     */
    public void date()
    {
        authorDateFlag = true;
        writeStartTag( SimplifiedDocbookMarkup.DATE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#DATE_TAG
     */
    public void date_()
    {
        writeEndTag( SimplifiedDocbookMarkup.DATE_TAG );
        authorDateFlag = false;
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ARTICLE_TAG
     */
    public void body_()
    {
        writeEndTag( SimplifiedDocbookMarkup.ARTICLE_TAG );
        out.flush();
        init();
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SIDEBAR_TAG
     */
    public void sidebar()
    {
        writeStartTag( SimplifiedDocbookMarkup.SIDEBAR_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SIDEBAR_TAG
     */
    public void sidebar_()
    {
        writeEndTag( SimplifiedDocbookMarkup.SIDEBAR_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section1()
    {
        writeStartTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section1_()
    {
        writeEndTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section2()
    {
        writeStartTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section2_()
    {
        writeEndTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section3()
    {
        writeStartTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section3_()
    {
        writeEndTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section4()
    {
        writeStartTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section4_()
    {
        writeEndTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section5()
    {
        writeStartTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTION_TAG
     */
    public void section5_()
    {
        writeEndTag( SimplifiedDocbookMarkup.SECTION_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle()
    {
        writeStartTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle1()
    {
        writeStartTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle1_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle2()
    {
        writeStartTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle2_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle3()
    {
        writeStartTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle3_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle4()
    {
        writeStartTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle4_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle5()
    {
        writeStartTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void sectionTitle5_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTIONINFO_TAG
     */
    public void header()
    {
        writeStartTag( SimplifiedDocbookMarkup.SECTIONINFO_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#SECTIONINFO_TAG
     */
    public void header_()
    {
        writeEndTag( SimplifiedDocbookMarkup.SECTIONINFO_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ITEMIZEDLIST_TAG
     */
    public void list()
    {
        paragraph_();
        writeStartTag( SimplifiedDocbookMarkup.ITEMIZEDLIST_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ITEMIZEDLIST_TAG
     */
    public void list_()
    {
        writeEndTag( SimplifiedDocbookMarkup.ITEMIZEDLIST_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#LISTITEM_TAG
     */
    public void listItem()
    {
        writeStartTag( SimplifiedDocbookMarkup.LISTITEM_TAG );
        paragraph();
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#LISTITEM_TAG
     */
    public void listItem_()
    {
        paragraph_();
        writeEndTag( SimplifiedDocbookMarkup.LISTITEM_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ORDEREDLIST_TAG
     * @see SimplifiedDocbookMarkup#NUMERATION_ATTRIBUTE
     */
    public void numberedList( int numbering )
    {
        String numeration = DocbookUtils.docbookListNumbering( numbering );

        paragraph_();

        MutableAttributeSet att = new SimpleAttributeSet();
        att.addAttribute( SimplifiedDocbookMarkup.NUMERATION_ATTRIBUTE, numeration );

        writeStartTag( SimplifiedDocbookMarkup.ORDEREDLIST_TAG, att );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ORDEREDLIST_TAG
     */
    public void numberedList_()
    {
        writeEndTag( SimplifiedDocbookMarkup.ORDEREDLIST_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#LISTITEM_TAG
     */
    public void numberedListItem()
    {
        writeStartTag( SimplifiedDocbookMarkup.LISTITEM_TAG );
        paragraph();
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#LISTITEM_TAG
     */
    public void numberedListItem_()
    {
        paragraph_();
        writeEndTag( SimplifiedDocbookMarkup.LISTITEM_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#VARIABLELIST_TAG
     */
    public void definitionList()
    {
        paragraph_();
        writeStartTag( SimplifiedDocbookMarkup.VARIABLELIST_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#VARIABLELIST_TAG
     */
    public void definitionList_()
    {
        writeEndTag( SimplifiedDocbookMarkup.VARIABLELIST_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#VARLISTENTRY_TAG
     */
    public void definitionListItem()
    {
        writeStartTag( SimplifiedDocbookMarkup.VARLISTENTRY_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#VARLISTENTRY_TAG
     */
    public void definitionListItem_()
    {
        writeEndTag( SimplifiedDocbookMarkup.VARLISTENTRY_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TERM_TAG
     */
    public void definedTerm()
    {
        writeStartTag( SimplifiedDocbookMarkup.TERM_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TERM_TAG
     */
    public void definedTerm_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TERM_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#LISTITEM_TAG
     */
    public void definition()
    {
        writeStartTag( SimplifiedDocbookMarkup.LISTITEM_TAG );
        paragraph();
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#LISTITEM_TAG
     */
    public void definition_()
    {
        paragraph_();
        writeEndTag( SimplifiedDocbookMarkup.LISTITEM_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#PARA_TAG
     */
    public void paragraph()
    {
        if ( !paragraph )
        {
            writeStartTag( SimplifiedDocbookMarkup.PARA_TAG );
            paragraph = true;
        }
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#PARA_TAG
     */
    public void paragraph_()
    {
        if ( paragraph )
        {
            writeEndTag( SimplifiedDocbookMarkup.PARA_TAG );
            paragraph = false;
        }
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#PROGRAMLISTING_TAG
     */
    public void verbatim( boolean boxed )
    {
        verbatimFlag = true;
        paragraph_();
        writeStartTag( SimplifiedDocbookMarkup.PROGRAMLISTING_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#PROGRAMLISTING_TAG
     */
    public void verbatim_()
    {
        writeEndTag( SimplifiedDocbookMarkup.PROGRAMLISTING_TAG );
        verbatimFlag = false;
    }

    /** {@inheritDoc} */
    public void horizontalRule()
    {
        markup( horizontalRuleElement );
    }

    /** {@inheritDoc} */
    public void pageBreak()
    {
        markup( pageBreakElement );
    }

    /** {@inheritDoc} */
    public void figure()
    {
        writeStartTag( SimplifiedDocbookMarkup.MEDIAOBJECT_TAG );
    }

    /** {@inheritDoc} */
    public void figure_()
    {
        writeEndTag( SimplifiedDocbookMarkup.MEDIAOBJECT_TAG );
    }

    /**
     * <p>graphicElement</p>
     *
     * @see SimplifiedDocbookMarkup#MEDIAOBJECT_TAG
     * @see SimplifiedDocbookMarkup#IMAGEOBJECT_TAG
     * @see SimplifiedDocbookMarkup#IMAGEDATA_TAG
     * @see SimplifiedDocbookMarkup#FORMAT_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#FILEREF_ATTRIBUTE
     * @deprecated do not use!
     */
    protected void graphicElement()
    {
        if ( graphicsFileName != null )
        {
            String format = FileUtils.extension( graphicsFileName ).toUpperCase( Locale.ENGLISH );
            if ( format.length() == 0 )
            {
                format = "JPEG";
            }

            writeStartTag( SimplifiedDocbookMarkup.MEDIAOBJECT_TAG );
            writeStartTag( SimplifiedDocbookMarkup.IMAGEOBJECT_TAG );

            MutableAttributeSet att = new SimpleAttributeSet();
            att.addAttribute( SimplifiedDocbookMarkup.FORMAT_ATTRIBUTE, format );
            att.addAttribute( SimplifiedDocbookMarkup.FILEREF_ATTRIBUTE,
                    HtmlTools.escapeHTML( graphicsFileName, true ) );

            writeSimpleTag( SimplifiedDocbookMarkup.IMAGEDATA_TAG, att );

            writeEndTag( SimplifiedDocbookMarkup.IMAGEOBJECT_TAG );
            writeEndTag( SimplifiedDocbookMarkup.MEDIAOBJECT_TAG );
            graphicsFileName = null;
        }
    }

    /** {@inheritDoc} */
    public void figureGraphics( String name )
    {
        String format = FileUtils.extension( name ).toUpperCase( Locale.ENGLISH );

        writeStartTag( SimplifiedDocbookMarkup.IMAGEOBJECT_TAG );

        MutableAttributeSet att = new SimpleAttributeSet();
        att.addAttribute( SimplifiedDocbookMarkup.FORMAT_ATTRIBUTE, format );
        att.addAttribute( SimplifiedDocbookMarkup.FILEREF_ATTRIBUTE, HtmlTools.escapeHTML( name, true ) );

        writeSimpleTag( SimplifiedDocbookMarkup.IMAGEDATA_TAG, att );

        writeEndTag( SimplifiedDocbookMarkup.IMAGEOBJECT_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#FIGURE_TAG
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void figureCaption()
    {
        writeStartTag( SimplifiedDocbookMarkup.CAPTION_TAG );
        writeStartTag( SimplifiedDocbookMarkup.PARA_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#FIGURE_TAG
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void figureCaption_()
    {
        writeEndTag( SimplifiedDocbookMarkup.PARA_TAG );
        writeEndTag( SimplifiedDocbookMarkup.CAPTION_TAG );
    }

    /** {@inheritDoc} */
    public void table()
    {
        tableHasCaption = false;
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#INFORMALTABLE_TAG
     * @see SimplifiedDocbookMarkup#FRAME_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#ROWSEP_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#COLSEP_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#TABLE_TAG
     */
    public void table_()
    {
        if ( tableHasCaption )
        {
            tableHasCaption = false;
            // Formal table+title already written to original destination ---

            out.write( tableRows  );
            writeEndTag( TABLE_TAG );
        }
        else
        {
            String frame = "none";
            String sep = "0";
            if ( tableHasGrid )
            {
                frame = "all";
                sep = "1";
            }

            MutableAttributeSet att = new SimpleAttributeSet();
            att.addAttribute( SimplifiedDocbookMarkup.FRAME_ATTRIBUTE, frame );
            att.addAttribute( SimplifiedDocbookMarkup.ROWSEP_ATTRIBUTE, sep );
            att.addAttribute( SimplifiedDocbookMarkup.COLSEP_ATTRIBUTE, sep );

            writeStartTag( SimplifiedDocbookMarkup.INFORMALTABLE_TAG, att );

            out.write( tableRows  );

            writeEndTag( SimplifiedDocbookMarkup.INFORMALTABLE_TAG );
        }

        tableRows = null;
        tableHasGrid = false;
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TGROUP_TAG
     * @see SimplifiedDocbookMarkup#COLS_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#COLSPEC_TAG
     */
    public void tableRows( int[] justification, boolean grid )
    {
        tableHasGrid = grid;

        // Divert output to a string ---
        out.flush();
        savedOut = out;
        tableRowsWriter = new StringWriter();
        out = new PrintWriter( tableRowsWriter );

        MutableAttributeSet att = new SimpleAttributeSet();
        att.addAttribute( SimplifiedDocbookMarkup.COLS_ATTRIBUTE, String.valueOf( justification.length ) );

        writeStartTag( SimplifiedDocbookMarkup.TGROUP_TAG, att );

        for ( int i = 0; i < justification.length; ++i )
        {
            String justif;
            switch ( justification[i] )
            {
                case Sink.JUSTIFY_LEFT:
                    justif = "left";
                    break;
                case Sink.JUSTIFY_RIGHT:
                    justif = "right";
                    break;
                case Sink.JUSTIFY_CENTER:
                default:
                    justif = "center";
                    break;
            }

            att = new SimpleAttributeSet();
            att.addAttribute( "align", justif );

            writeSimpleTag( SimplifiedDocbookMarkup.COLSPEC_TAG, att );
        }

        writeStartTag( SimplifiedDocbookMarkup.TBODY_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TGROUP_TAG
     * @see SimplifiedDocbookMarkup#TBODY_TAG
     */
    public void tableRows_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TBODY_TAG );
        writeEndTag( SimplifiedDocbookMarkup.TGROUP_TAG );

        // Remember diverted output and restore original destination ---
        out.flush();
        if ( tableRowsWriter == null )
        {
            throw new IllegalArgumentException( "tableRows( int[] justification, boolean grid )"
                                                + " was not called before." );
        }

        tableRows = tableRowsWriter.toString();
        tableRowsWriter = null;
        out = savedOut;
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ROW_TAG
     */
    public void tableRow()
    {
        writeStartTag( SimplifiedDocbookMarkup.ROW_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ROW_TAG
     */
    public void tableRow_()
    {
        writeEndTag( SimplifiedDocbookMarkup.ROW_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ENTRY_TAG
     */
    public void tableCell()
    {
        writeStartTag( SimplifiedDocbookMarkup.ENTRY_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ENTRY_TAG
     */
    public void tableCell_()
    {
        writeEndTag( SimplifiedDocbookMarkup.ENTRY_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ENTRY_TAG
     */
    public void tableHeaderCell()
    {
        writeStartTag( SimplifiedDocbookMarkup.ENTRY_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ENTRY_TAG
     */
    public void tableHeaderCell_()
    {
        writeEndTag( SimplifiedDocbookMarkup.ENTRY_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TABLE_TAG
     * @see SimplifiedDocbookMarkup#FRAME_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#ROWSEP_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#COLSEP_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void tableCaption()
    {
        tableHasCaption = true;

        String frame;
        int sep;
        if ( tableHasGrid )
        {
            frame = "all";
            sep = 1;
        }
        else
        {
            frame = "none";
            sep = 0;
        }

        MutableAttributeSet att = new SimpleAttributeSet();
        att.addAttribute( SimplifiedDocbookMarkup.FRAME_ATTRIBUTE, frame );
        att.addAttribute( SimplifiedDocbookMarkup.ROWSEP_ATTRIBUTE, String.valueOf( sep ) );
        att.addAttribute( SimplifiedDocbookMarkup.COLSEP_ATTRIBUTE, String.valueOf( sep ) );

        writeStartTag( TABLE_TAG, att );

        writeStartTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#TITLE_TAG
     */
    public void tableCaption_()
    {
        writeEndTag( SimplifiedDocbookMarkup.TITLE_TAG );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ANCHOR_TAG
     */
    public void anchor( String name )
    {
        if ( name == null )
        {
            throw new NullPointerException( "Anchor name cannot be null!" );
        }

        if ( authorDateFlag )
        {
            return;
        }

        String id = name;

        if ( !DoxiaUtils.isValidId( id ) )
        {
            id = DoxiaUtils.encodeId( name, true );

            String msg = "Modified invalid anchor name: '" + name + "' to '" + id + "'";
            logMessage( "modifiedLink", msg );
        }

        MutableAttributeSet att = new SimpleAttributeSet();
        att.addAttribute( ID_ATTRIBUTE, id );

        writeSimpleTag( SimplifiedDocbookMarkup.ANCHOR_TAG, att );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ANCHOR_TAG
     */
    public void anchor_()
    {
        comment( " anchor_end " );
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ULINK_TAG
     * @see SimplifiedDocbookMarkup#URL_ATTRIBUTE
     * @see SimplifiedDocbookMarkup#LINK_TAG
     * @see SimplifiedDocbookMarkup#LINKEND_ATTRIBUTE
     */
    public void link( String name )
    {
        if ( name == null )
        {
            throw new NullPointerException( "Link name cannot be null!" );
        }

        if ( DoxiaUtils.isInternalLink( name ) )
        {
            String linkend = name.substring( 1 );
            MutableAttributeSet att = new SimpleAttributeSet();
            att.addAttribute( SimplifiedDocbookMarkup.LINKEND_ATTRIBUTE, HtmlTools.escapeHTML( linkend ) );

            writeStartTag( SimplifiedDocbookMarkup.LINK_TAG, att );
        }
        else
        {
            externalLinkFlag = true;
            MutableAttributeSet att = new SimpleAttributeSet();
            att.addAttribute( SimplifiedDocbookMarkup.URL_ATTRIBUTE, HtmlTools.escapeHTML( name, true ) );

            writeStartTag( SimplifiedDocbookMarkup.ULINK_TAG, att );
        }
    }

    /**
     * {@inheritDoc}
     * @see SimplifiedDocbookMarkup#ULINK_TAG
     * @see SimplifiedDocbookMarkup#LINK_TAG
     */
    public void link_()
    {
        if ( externalLinkFlag )
        {
            writeEndTag( SimplifiedDocbookMarkup.ULINK_TAG );
            externalLinkFlag = false;
        }
        else
        {
            writeEndTag( SimplifiedDocbookMarkup.LINK_TAG );
        }
    }

    /** {@inheritDoc} */
    public void inline()
    {
        inline( null );
    }

    /** {@inheritDoc} */
    public void inline( SinkEventAttributes attributes )
    {
        List<String> tags = new ArrayList<String>();

        if ( attributes != null )
        {

            if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "italic" ) )
            {
                markup( italicBeginTag );
                tags.add( 0, italicEndTag );
            }

            if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "bold" ) )
            {
                write( boldBeginTag );
                tags.add( 0, boldEndTag );
            }

            if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "code" ) )
            {
                if ( !authorDateFlag )
                {
                    write( monospacedBeginTag );
                    tags.add( 0, monospacedEndTag );
                }
            }

        }

        inlineStack.push( tags );
    }

    /** {@inheritDoc} */
    public void inline_()
    {
        for ( String tag: inlineStack.pop() )
        {
            markup( tag );
        }
    }

    /** {@inheritDoc} */
    public void italic()
    {
        inline( SinkEventAttributeSet.Semantics.ITALIC );
    }

    /** {@inheritDoc} */
    public void italic_()
    {
        inline_();
    }

    /** {@inheritDoc} */
    public void bold()
    {
        inline( SinkEventAttributeSet.Semantics.BOLD );
    }

    /** {@inheritDoc} */
    public void bold_()
    {
        inline_();
    }

    /** {@inheritDoc} */
    public void monospaced()
    {
        inline( SinkEventAttributeSet.Semantics.CODE );
    }

    /** {@inheritDoc} */
    public void monospaced_()
    {
        inline_();
    }

    /** {@inheritDoc} */
    public void lineBreak()
    {
        markup( lineBreakElement );
    }

    /** {@inheritDoc} */
    public void nonBreakingSpace()
    {
        markup( "&#x00A0;" );
        //markup( "&nbsp;" );
    }

    /** {@inheritDoc} */
    public void text( String text )
    {
        if ( verbatimFlag )
        {
            verbatimContent( text );
        }
        else
        {
            content( text );
        }
    }

    /** {@inheritDoc} */
    public void comment( String comment )
    {
        if ( comment != null )
        {
            String originalComment = comment;

            // http://www.w3.org/TR/2000/REC-xml-20001006#sec-comments
            while ( comment.contains( "--" ) )
            {
                comment = comment.replace( "--", "- -" );
            }

            if ( comment.endsWith( "-" ) )
            {
                comment += " ";
            }

            if ( !originalComment.equals( comment ) )
            {
                String msg = "Modified invalid comment: '" + originalComment + "' to '" + comment + "'";
                logMessage( "modifiedComment", msg );
            }

            StringBuilder buffer = new StringBuilder( comment.length() + 7 );

            buffer.append( LESS_THAN ).append( BANG ).append( MINUS ).append( MINUS );
            buffer.append( comment );
            buffer.append( MINUS ).append( MINUS ).append( GREATER_THAN );

            markup( buffer.toString() );
        }
    }

    /**
     * {@inheritDoc}
     *
     * Unknown events just log a warning message but are ignored otherwise.
     * @see org.apache.maven.doxia.sink.Sink#unknown(String,Object[],SinkEventAttributes)
     */
    public void unknown( String name, Object[] requiredParams, SinkEventAttributes attributes )
    {
        String msg = "Unknown Sink event: '" + name + "', ignoring!";
        logMessage( "unknownEvent", msg );
    }

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

    /**
     * Write text to output, preserving white space.
     *
     * @param text The text to write.
     */
    protected void markup( String text )
    {
        if ( !skip )
        {
            out.write( text );
        }
    }

    /**
     * Write SGML escaped text to output, not preserving white space.
     *
     * @param text The text to write.
     */
    protected void content( String text )
    {
        if ( !skip )
        {
            out.write( HtmlTools.escapeHTML( text, true ) );
        }
    }

    /**
     * Write SGML escaped text to output, preserving white space.
     *
     * @param text The text to write.
     */
    protected void verbatimContent( String text )
    {
        if ( !skip )
        {
            out.write( HtmlTools.escapeHTML( text, true ) );
        }
    }

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

    /** {@inheritDoc} */
    public void flush()
    {
        out.flush();
    }

    /** {@inheritDoc} */
    public void close()
    {
        out.close();

        if ( getLog().isWarnEnabled() && this.warnMessages != null )
        {
            for ( Map.Entry<String, Set<String>> entry : this.warnMessages.entrySet() )
            {
                for ( String msg : entry.getValue() )
                {
                    getLog().warn( msg );
                }
            }

            this.warnMessages = null;
        }
    }

    /** {@inheritDoc} */
    protected void write( String text )
    {
        markup( unifyEOLs( text ) );
    }

    /**
     * <p>Setter for the field <code>skip</code>.</p>
     *
     * @param skip the skip to set.
     * @since 1.1
     */
    public void setSkip( boolean skip )
    {
        this.skip = skip;
    }

    /**
     * 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 #close()
     * @since 1.1.1
     */
    private void logMessage( String key, String msg )
    {
        msg = "[Docbook Sink] " + 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 );
    }
}
