/* XMLWriter.java --
   Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.xml.util;

import gnu.java.lang.CPStringBuilder;

import java.io.BufferedWriter;
import java.io.CharConversionException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Stack;

import org.xml.sax.*;
import org.xml.sax.ext.*;
import org.xml.sax.helpers.*;


/**
 * This class is a SAX handler which writes all its input as a well formed
 * XML or XHTML document.  If driven using SAX2 events, this output may
 * include a recreated document type declaration, subject to limitations
 * of SAX (no internal subset exposed) or DOM (the important declarations,
 * with their documentation, are discarded).
 *
 * <p> By default, text is generated "as-is", but some optional modes
 * are supported.  Pretty-printing is supported, to make life easier
 * for people reading the output.  XHTML (1.0) output has can be made
 * particularly pretty; all the built-in character entities are known.
 * Canonical XML can also be generated, assuming the input is properly
 * formed.
 *
 * <hr>
 *
 * <p> Some of the methods on this class are intended for applications to
 * use directly, rather than as pure SAX2 event callbacks.  Some of those
 * methods access the JavaBeans properties (used to tweak output formats,
 * for example canonicalization and pretty printing).  Subclasses
 * are expected to add new behaviors, not to modify current behavior, so
 * many such methods are final.</p>
 *
 * <p> The <em>write*()</em> methods may be slightly simpler for some
 * applications to use than direct callbacks.  For example, they support
 * a simple policy for encoding data items as the content of a single element.
 *
 * <p> To reuse an XMLWriter you must provide it with a new Writer, since
 * this handler closes the writer it was given as part of its endDocument()
 * handling.  (XML documents have an end of input, and the way to encode
 * that on a stream is to close it.) </p>
 *
 * <hr>
 *
 * <p> Note that any relative URIs in the source document, as found in
 * entity and notation declarations, ought to have been fully resolved by
 * the parser providing events to this handler.  This means that the
 * output text should only have fully resolved URIs, which may not be
 * the desired behavior in cases where later binding is desired. </p>
 *
 * <p> <em>Note that due to SAX2 defaults, you may need to manually
 * ensure that the input events are XML-conformant with respect to namespace
 * prefixes and declarations.  {@link gnu.xml.pipeline.NSFilter} is
 * one solution to this problem, in the context of processing pipelines.</em>
 * Something as simple as connecting this handler to a parser might not
 * generate the correct output.  Another workaround is to ensure that the
 * <em>namespace-prefixes</em> feature is always set to true, if you're
 * hooking this directly up to some XMLReader implementation.
 *
 * @see gnu.xml.pipeline.TextConsumer
 *
 * @author David Brownell
 *
 * @deprecated Please use the javax.xml.stream APIs instead
 */
public class XMLWriter
    implements ContentHandler, LexicalHandler, DTDHandler, DeclHandler
{
    // text prints/escapes differently depending on context
    //  CTX_ENTITY ... entity literal value
    //  CTX_ATTRIBUTE ... attribute literal value
    //  CTX_CONTENT ... content of an element
    //  CTX_UNPARSED ... CDATA, comment, PI, names, etc
    //  CTX_NAME ... name or nmtoken, no escapes possible
    private static final int    CTX_ENTITY = 1;
    private static final int    CTX_ATTRIBUTE = 2;
    private static final int    CTX_CONTENT = 3;
    private static final int    CTX_UNPARSED = 4;
    private static final int    CTX_NAME = 5;

// FIXME: names (element, attribute, PI, notation, etc) are not
// currently written out with range checks (escapeChars).
// In non-XHTML, some names can't be directly written; panic!

    private static String       sysEOL;

    static {
        try {
            sysEOL = System.getProperty ("line.separator", "\n");

            // don't use the system's EOL if it's illegal XML.
            if (!isLineEnd (sysEOL))
                sysEOL = "\n";

        } catch (SecurityException e) {
            sysEOL = "\n";
        }
    }

    private static boolean isLineEnd (String eol)
    {
        return "\n".equals (eol)
                    || "\r".equals (eol)
                    || "\r\n".equals (eol);
    }

    private Writer              out;
    private boolean             inCDATA;
    private int                 elementNestLevel;
    private String              eol = sysEOL;

    private short               dangerMask;
    private CPStringBuilder     stringBuf;
    private Locator             locator;
    private ErrorHandler        errHandler;

    private boolean             expandingEntities = false;
    private int                 entityNestLevel;
    private boolean             xhtml;
    private boolean             startedDoctype;
    private String              encoding;

    private boolean             canonical;
    private boolean             inDoctype;
    private boolean             inEpilogue;

    // pretty printing controls
    private boolean             prettyPrinting;
    private int                 column;
    private boolean             noWrap;
    private Stack               space = new Stack ();

    // this is not a hard'n'fast rule -- longer lines are OK,
    // but are to be avoided.  Here, prettyprinting is more to
    // show structure "cleanly" than to be precise about it.
    // better to have ragged layout than one line 24Kb long.
    private static final int    lineLength = 75;


    /**
     * Constructs this handler with System.out used to write SAX events
     * using the UTF-8 encoding.  Avoid using this except when you know
     * it's safe to close System.out at the end of the document.
     */
    public XMLWriter () throws IOException
        { this (System.out); }

    /**
     * Constructs a handler which writes all input to the output stream
     * in the UTF-8 encoding, and closes it when endDocument is called.
     * (Yes it's annoying that this throws an exception -- but there's
     * really no way around it, since it's barely possible a JDK may
     * exist somewhere that doesn't know how to emit UTF-8.)
     */
    public XMLWriter (OutputStream out) throws IOException
    {
        this (new OutputStreamWriter (out, "UTF8"));
    }

    /**
     * Constructs a handler which writes all input to the writer, and then
     * closes the writer when the document ends.  If an XML declaration is
     * written onto the output, and this class can determine the name of
     * the character encoding for this writer, that encoding name will be
     * included in the XML declaration.
     *
     * <P> See the description of the constructor which takes an encoding
     * name for imporant information about selection of encodings.
     *
     * @param writer XML text is written to this writer.
     */
    public XMLWriter (Writer writer)
    {
        this (writer, null);
    }

    /**
     * Constructs a handler which writes all input to the writer, and then
     * closes the writer when the document ends.  If an XML declaration is
     * written onto the output, this class will use the specified encoding
     * name in that declaration.  If no encoding name is specified, no
     * encoding name will be declared unless this class can otherwise
     * determine the name of the character encoding for this writer.
     *
     * <P> At this time, only the UTF-8 ("UTF8") and UTF-16 ("Unicode")
     * output encodings are fully lossless with respect to XML data.  If you
     * use any other encoding you risk having your data be silently mangled
     * on output, as the standard Java character encoding subsystem silently
     * maps non-encodable characters to a question mark ("?") and will not
     * report such errors to applications.
     *
     * <p> For a few other encodings the risk can be reduced. If the writer is
     * a java.io.OutputStreamWriter, and uses either the ISO-8859-1 ("8859_1",
     * "ISO8859_1", etc) or US-ASCII ("ASCII") encodings, content which
     * can't be encoded in those encodings will be written safely.  Where
     * relevant, the XHTML entity names will be used; otherwise, numeric
     * character references will be emitted.
     *
     * <P> However, there remain a number of cases where substituting such
     * entity or character references is not an option.  Such references are
     * not usable within a DTD, comment, PI, or CDATA section.  Neither may
     * they be used when element, attribute, entity, or notation names have
     * the problematic characters.
     *
     * @param writer XML text is written to this writer.
     * @param encoding if non-null, and an XML declaration is written,
     *  this is the name that will be used for the character encoding.
     */
    public XMLWriter (Writer writer, String encoding)
    {
        setWriter (writer, encoding);
    }

    private void setEncoding (String encoding)
    {
        if (encoding == null && out instanceof OutputStreamWriter)
            encoding = ((OutputStreamWriter)out).getEncoding ();

        if (encoding != null) {
            encoding = encoding.toUpperCase ();

            // Use official encoding names where we know them,
            // avoiding the Java-only names.  When using common
            // encodings where we can easily tell if characters
            // are out of range, we'll escape out-of-range
            // characters using character refs for safety.

            // I _think_ these are all the main synonyms for these!
            if ("UTF8".equals (encoding)) {
                encoding = "UTF-8";
            } else if ("US-ASCII".equals (encoding)
                    || "ASCII".equals (encoding)) {
                dangerMask = (short) 0xff80;
                encoding = "US-ASCII";
            } else if ("ISO-8859-1".equals (encoding)
                    || "8859_1".equals (encoding)
                    || "ISO8859_1".equals (encoding)) {
                dangerMask = (short) 0xff00;
                encoding = "ISO-8859-1";
            } else if ("UNICODE".equals (encoding)
                    || "UNICODE-BIG".equals (encoding)
                    || "UNICODE-LITTLE".equals (encoding)) {
                encoding = "UTF-16";

                // TODO: UTF-16BE, UTF-16LE ... no BOM; what
                // release of JDK supports those Unicode names?
            }

            if (dangerMask != 0)
                stringBuf = new CPStringBuilder ();
        }

        this.encoding = encoding;
    }


    /**
     * Resets the handler to write a new text document.
     *
     * @param writer XML text is written to this writer.
     * @param encoding if non-null, and an XML declaration is written,
     *  this is the name that will be used for the character encoding.
     *
     * @exception IllegalStateException if the current
     *  document hasn't yet ended (with {@link #endDocument})
     */
    final public void setWriter (Writer writer, String encoding)
    {
        if (out != null)
            throw new IllegalStateException (
                "can't change stream in mid course");
        out = writer;
        if (out != null)
            setEncoding (encoding);
        if (!(out instanceof BufferedWriter))
            out = new BufferedWriter (out);
        space.push ("default");
    }

    /**
     * Assigns the line ending style to be used on output.
     * @param eolString null to use the system default; else
     *  "\n", "\r", or "\r\n".
     */
    final public void setEOL (String eolString)
    {
        if (eolString == null)
            eol = sysEOL;
        else if (!isLineEnd (eolString))
            eol = eolString;
        else
            throw new IllegalArgumentException (eolString);
    }

    /**
     * Assigns the error handler to be used to present most fatal
     * errors.
     */
    public void setErrorHandler (ErrorHandler handler)
    {
        errHandler = handler;
    }

    /**
     * Used internally and by subclasses, this encapsulates the logic
     * involved in reporting fatal errors.  It uses locator information
     * for good diagnostics, if available, and gives the application's
     * ErrorHandler the opportunity to handle the error before throwing
     * an exception.
     */
    protected void fatal (String message, Exception e)
    throws SAXException
    {
        SAXParseException       x;

        if (locator == null)
            x = new SAXParseException (message, null, null, -1, -1, e);
        else
            x = new SAXParseException (message, locator, e);
        if (errHandler != null)
            errHandler.fatalError (x);
        throw x;
    }


    // JavaBeans properties

    /**
     * Controls whether the output should attempt to follow the "transitional"
     * XHTML rules so that it meets the "HTML Compatibility Guidelines"
     * appendix in the XHTML specification.  A "transitional" Document Type
     * Declaration (DTD) is placed near the beginning of the output document,
     * instead of whatever DTD would otherwise have been placed there, and
     * XHTML empty elements are printed specially.  When writing text in
     * US-ASCII or ISO-8859-1 encodings, the predefined XHTML internal
     * entity names are used (in preference to character references) when
     * writing content characters which can't be expressed in those encodings.
     *
     * <p> When this option is enabled, it is the caller's responsibility
     * to ensure that the input is otherwise valid as XHTML.  Things to
     * be careful of in all cases, as described in the appendix referenced
     * above, include:  <ul>
     *
     *  <li> Element and attribute names must be in lower case, both
     *          in the document and in any CSS style sheet.
     *  <li> All XML constructs must be valid as defined by the XHTML
     *          "transitional" DTD (including all familiar constructs,
     *          even deprecated ones).
     *  <li> The root element must be "html".
     *  <li> Elements that must be empty (such as <em>&lt;br&gt;</em>
     *          must have no content.
     *  <li> Use both <em>lang</em> and <em>xml:lang</em> attributes
     *          when specifying language.
     *  <li> Similarly, use both <em>id</em> and <em>name</em> attributes
     *          when defining elements that may be referred to through
     *          URI fragment identifiers ... and make sure that the
     *          value is a legal NMTOKEN, since not all such HTML 4.0
     *          identifiers are valid in XML.
     *  <li> Be careful with character encodings; make sure you provide
     *          a <em>&lt;meta http-equiv="Content-type"
     *          content="text/xml;charset=..." /&gt;</em> element in
     *          the HTML "head" element, naming the same encoding
     *          used to create this handler.  Also, if that encoding
     *          is anything other than US-ASCII, make sure that if
     *          the document is given a MIME content type, it has
     *          a <em>charset=...</em> attribute with that encoding.
     *  </ul>
     *
     * <p> Additionally, some of the oldest browsers have additional
     * quirks, to address with guidelines such as: <ul>
     *
     *  <li> Processing instructions may be rendered, so avoid them.
     *          (Similarly for an XML declaration.)
     *  <li> Embedded style sheets and scripts should not contain XML
     *          markup delimiters:  &amp;, &lt;, and ]]&gt; are trouble.
     *  <li> Attribute values should not have line breaks or multiple
     *          consecutive white space characters.
     *  <li> Use no more than one of the deprecated (transitional)
     *          <em>&lt;isindex&gt;</em> elements.
     *  <li> Some boolean attributes (such as <em>compact, checked,
     *          disabled, readonly, selected,</em> and more) confuse
     *          some browsers, since they only understand minimized
     *          versions which are illegal in XML.
     *  </ul>
     *
     * <p> Also, some characteristics of the resulting output may be
     * a function of whether the document is later given a MIME
     * content type of <em>text/html</em> rather than one indicating
     * XML (<em>application/xml</em> or <em>text/xml</em>).  Worse,
     * some browsers ignore MIME content types and prefer to rely URI
     * name suffixes -- so an "index.xml" could always be XML, never
     * XHTML, no matter its MIME type.
     */
    final public void setXhtml (boolean value)
    {
        if (locator != null)
            throw new IllegalStateException ("started parsing");
        xhtml = value;
        if (xhtml)
            canonical = false;
    }

    /**
     * Returns true if the output attempts to echo the input following
     * "transitional" XHTML rules and matching the "HTML Compatibility
     * Guidelines" so that an HTML version 3 browser can read the output
     * as HTML; returns false (the default) othewise.
     */
    final public boolean isXhtml ()
    {
        return xhtml;
    }

    /**
     * Controls whether the output text contains references to
     * entities (the default), or instead contains the expanded
     * values of those entities.
     */
    final public void setExpandingEntities (boolean value)
    {
        if (locator != null)
            throw new IllegalStateException ("started parsing");
        expandingEntities = value;
        if (!expandingEntities)
            canonical = false;
    }

    /**
     * Returns true if the output will have no entity references;
     * returns false (the default) otherwise.
     */
    final public boolean isExpandingEntities ()
    {
        return expandingEntities;
    }

    /**
     * Controls pretty-printing, which by default is not enabled
     * (and currently is most useful for XHTML output).
     * Pretty printing enables structural indentation, sorting of attributes
     * by name, line wrapping, and potentially other mechanisms for making
     * output more or less readable.
     *
     * <p> At this writing, structural indentation and line wrapping are
     * enabled when pretty printing is enabled and the <em>xml:space</em>
     * attribute has the value <em>default</em> (its other legal value is
     * <em>preserve</em>, as defined in the XML specification).  The three
     * XHTML element types which use another value are recognized by their
     * names (namespaces are ignored).
     *
     * <p> Also, for the record, the "pretty" aspect of printing here
     * is more to provide basic structure on outputs that would otherwise
     * risk being a single long line of text.  For now, expect the
     * structure to be ragged ... unless you'd like to submit a patch
     * to make this be more strictly formatted!
     *
     * @exception IllegalStateException thrown if this method is invoked
     *  after output has begun.
     */
    final public void setPrettyPrinting (boolean value)
    {
        if (locator != null)
            throw new IllegalStateException ("started parsing");
        prettyPrinting = value;
        if (prettyPrinting)
            canonical = false;
    }

    /**
     * Returns value of flag controlling pretty printing.
     */
    final public boolean isPrettyPrinting ()
    {
        return prettyPrinting;
    }


    /**
     * Sets the output style to be canonicalized.  Input events must
     * meet requirements that are slightly more stringent than the
     * basic well-formedness ones, and include:  <ul>
     *
     *  <li> Namespace prefixes must not have been changed from those
     *  in the original document.  (This may only be ensured by setting
     *  the SAX2 XMLReader <em>namespace-prefixes</em> feature flag;
     *  by default, it is cleared.)
     *
     *  <li> Redundant namespace declaration attributes have been
     *  removed.  (If an ancestor element defines a namespace prefix
     *  and that declaration hasn't been overriden, an element must
     *  not redeclare it.)
     *
     *  <li> If comments are not to be included in the canonical output,
     *  they must first be removed from the input event stream; this
     *  <em>Canonical XML with comments</em> by default.
     *
     *  <li> If the input character encoding was not UCS-based, the
     *  character data must have been normalized using Unicode
     *  Normalization Form C.  (UTF-8 and UTF-16 are UCS-based.)
     *
     *  <li> Attribute values must have been normalized, as is done
     *  by any conformant XML processor which processes all external
     *  parameter entities.
     *
     *  <li> Similarly, attribute value defaulting has been performed.
     *
     *  </ul>
     *
     * <p> Note that fragments of XML documents, as specified by an XPath
     * node set, may be canonicalized.  In such cases, elements may need
     * some fixup (for <em>xml:*</em> attributes and application-specific
     * context).
     *
     * @exception IllegalArgumentException if the output encoding
     *  is anything other than UTF-8.
     */
    final public void setCanonical (boolean value)
    {
        if (value && !"UTF-8".equals (encoding))
            throw new IllegalArgumentException ("encoding != UTF-8");
        canonical = value;
        if (canonical) {
            prettyPrinting = xhtml = false;
            expandingEntities = true;
            eol = "\n";
        }
    }


    /**
     * Returns value of flag controlling canonical output.
     */
    final public boolean isCanonical ()
    {
        return canonical;
    }


    /**
     * Flushes the output stream.  When this handler is used in long lived
     * pipelines, it can be important to flush buffered state, for example
     * so that it can reach the disk as part of a state checkpoint.
     */
    final public void flush ()
    throws IOException
    {
        if (out != null)
            out.flush ();
    }


    // convenience routines

// FIXME:  probably want a subclass that holds a lot of these...
// and maybe more!

    /**
     * Writes the string as if characters() had been called on the contents
     * of the string.  This is particularly useful when applications act as
     * producers and write data directly to event consumers.
     */
    final public void write (String data)
    throws SAXException
    {
        char    buf [] = data.toCharArray ();
        characters (buf, 0, buf.length);
    }


    /**
     * Writes an element that has content consisting of a single string.
     * @see #writeEmptyElement
     * @see #startElement
     */
    public void writeElement (
        String uri,
        String localName,
        String qName,
        Attributes atts,
        String content
    ) throws SAXException
    {
        if (content == null || content.length () == 0) {
            writeEmptyElement (uri, localName, qName, atts);
            return;
        }
        startElement (uri, localName, qName, atts);
        char chars [] = content.toCharArray ();
        characters (chars, 0, chars.length);
        endElement (uri, localName, qName);
    }


    /**
     * Writes an element that has content consisting of a single integer,
     * encoded as a decimal string.
     * @see #writeEmptyElement
     * @see #startElement
     */
    public void writeElement (
        String uri,
        String localName,
        String qName,
        Attributes atts,
        int content
    ) throws SAXException
    {
        writeElement (uri, localName, qName, atts, Integer.toString (content));
    }


    // SAX1 ContentHandler
    /** <b>SAX1</b>:  provides parser status information */
    final public void setDocumentLocator (Locator l)
    {
        locator = l;
    }


    // URL for dtd that validates against all normal HTML constructs
    private static final String xhtmlFullDTD =
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";


    /**
     * <b>SAX1</b>:  indicates the beginning of a document parse.
     * If you're writing (well formed) fragments of XML, neither
     * this nor endDocument should be called.
     */
    // NOT final
    public void startDocument ()
    throws SAXException
    {
        try {
            if (out == null)
                throw new IllegalStateException (
                    "null Writer given to XMLWriter");

            // Not all parsers provide the locator we want; this also
            // flags whether events are being sent to this object yet.
            // We could only have this one call if we only printed whole
            // documents ... but we also print fragments, so most of the
            // callbacks here replicate this test.

            if (locator == null)
                locator = new LocatorImpl ();

            // Unless the data is in US-ASCII or we're canonicalizing, write
            // the XML declaration if we know the encoding.  US-ASCII won't
            // normally get mangled by web server confusion about the
            // character encodings used.  Plus, it's an easy way to
            // ensure we can write ASCII that's unlikely to confuse
            // elderly HTML parsers.

            if (!canonical
                    && dangerMask != (short) 0xff80
                    && encoding != null) {
                rawWrite ("<?xml version='1.0'");
                rawWrite (" encoding='" + encoding + "'");
                rawWrite ("?>");
                newline ();
            }

            if (xhtml) {

                rawWrite ("<!DOCTYPE html PUBLIC");
                newline ();
                rawWrite ("  '-//W3C//DTD XHTML 1.0 Transitional//EN'");
                newline ();
                rawWrite ("  '");
                    // NOTE:  URL (above) matches the REC
                rawWrite (xhtmlFullDTD);
                rawWrite ("'>");
                newline ();
                newline ();

                // fake the rest of the handler into ignoring
                // everything until the root element, so any
                // XHTML DTD comments, PIs, etc are ignored
                startedDoctype = true;
            }

            entityNestLevel = 0;

        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /**
     * <b>SAX1</b>:  indicates the completion of a parse.
     * Note that all complete SAX event streams make this call, even
     * if an error is reported during a parse.
     */
    // NOT final
    public void endDocument ()
    throws SAXException
    {
        try {
            if (!canonical) {
                newline ();
                newline ();
            }
            out.close ();
            out = null;
            locator = null;
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    // XHTML elements declared as EMPTY print differently
    final private static boolean isEmptyElementTag (String tag)
    {
        switch (tag.charAt (0)) {
          case 'a':     return "area".equals (tag);
          case 'b':     return "base".equals (tag)
                            || "basefont".equals (tag)
                            || "br".equals (tag);
          case 'c':     return "col".equals (tag);
          case 'f':     return "frame".equals (tag);
          case 'h':     return "hr".equals (tag);
          case 'i':     return "img".equals (tag)
                            || "input".equals (tag)
                            || "isindex".equals (tag);
          case 'l':     return "link".equals (tag);
          case 'm':     return "meta".equals (tag);
          case 'p':     return "param".equals (tag);
        }
        return false;
    }

    private static boolean indentBefore (String tag)
    {
        // basically indent before block content
        // and within structure like tables, lists
        switch (tag.charAt (0)) {
          case 'a':     return "applet".equals (tag);
          case 'b':     return "body".equals (tag)
                            || "blockquote".equals (tag);
          case 'c':     return "center".equals (tag);
          case 'f':     return "frame".equals (tag)
                            || "frameset".equals (tag);
          case 'h':     return "head".equals (tag);
          case 'm':     return "meta".equals (tag);
          case 'o':     return "object".equals (tag);
          case 'p':     return "param".equals (tag)
                            || "pre".equals (tag);
          case 's':     return "style".equals (tag);
          case 't':     return "title".equals (tag)
                            || "td".equals (tag)
                            || "th".equals (tag);
        }
        // ... but not inline elements like "em", "b", "font"
        return false;
    }

    private static boolean spaceBefore (String tag)
    {
        // blank line AND INDENT before certain structural content
        switch (tag.charAt (0)) {
          case 'h':     return "h1".equals (tag)
                            || "h2".equals (tag)
                            || "h3".equals (tag)
                            || "h4".equals (tag)
                            || "h5".equals (tag)
                            || "h6".equals (tag)
                            || "hr".equals (tag);
          case 'l':     return "li".equals (tag);
          case 'o':     return "ol".equals (tag);
          case 'p':     return "p".equals (tag);
          case 't':     return "table".equals (tag)
                            || "tr".equals (tag);
          case 'u':     return "ul".equals (tag);
        }
        return false;
    }

    // XHTML DTDs say these three have xml:space="preserve"
    private static boolean spacePreserve (String tag)
    {
        return "pre".equals (tag)
                || "style".equals (tag)
                || "script".equals (tag);
    }

    /**
     * <b>SAX2</b>:  ignored.
     */
    final public void startPrefixMapping (String prefix, String uri)
        {}

    /**
     * <b>SAX2</b>:  ignored.
     */
    final public void endPrefixMapping (String prefix)
        {}

    private void writeStartTag (
        String name,
        Attributes atts,
        boolean isEmpty
    ) throws SAXException, IOException
    {
        rawWrite ('<');
        rawWrite (name);

        // write out attributes ... sorting is particularly useful
        // with output that's been heavily defaulted.
        if (atts != null && atts.getLength () != 0) {

            // Set up to write, with optional sorting
            int         indices [] = new int [atts.getLength ()];

            for (int i= 0; i < indices.length; i++)
                indices [i] = i;

            // optionally sort

// FIXME:  canon xml demands xmlns nodes go first,
// and sorting by URI first (empty first) then localname
// it should maybe use a different sort

            if (canonical || prettyPrinting) {

                // insertion sort by attribute name
                for (int i = 1; i < indices.length; i++) {
                    int n = indices [i], j;
                    String      s = atts.getQName (n);

                    for (j = i - 1; j >= 0; j--) {
                        if (s.compareTo (atts.getQName (indices [j]))
                                >= 0)
                            break;
                        indices [j + 1] = indices [j];
                    }
                    indices [j + 1] = n;
                }
            }

            // write, sorted or no
            for (int i= 0; i < indices.length; i++) {
                String  s = atts.getQName (indices [i]);

                    if (s == null || "".equals (s))
                        throw new IllegalArgumentException ("no XML name");
                rawWrite (" ");
                rawWrite (s);
                rawWrite ("=");
                writeQuotedValue (atts.getValue (indices [i]),
                    CTX_ATTRIBUTE);
            }
        }
        if (isEmpty)
            rawWrite (" /");
        rawWrite ('>');
    }

    /**
     * <b>SAX2</b>:  indicates the start of an element.
     * When XHTML is in use, avoid attribute values with
     * line breaks or multiple whitespace characters, since
     * not all user agents handle them correctly.
     */
    final public void startElement (
        String uri,
        String localName,
        String qName,
        Attributes atts
    ) throws SAXException
    {
        startedDoctype = false;

        if (locator == null)
            locator = new LocatorImpl ();

        if (qName == null || "".equals (qName))
            throw new IllegalArgumentException ("no XML name");

        try {
            if (entityNestLevel != 0)
                return;
            if (prettyPrinting) {
                String whitespace = null;

                if (xhtml && spacePreserve (qName))
                    whitespace = "preserve";
                else if (atts != null)
                    whitespace = atts.getValue ("xml:space");
                if (whitespace == null)
                    whitespace = (String) space.peek ();
                space.push (whitespace);

                if ("default".equals (whitespace)) {
                    if (xhtml) {
                        if (spaceBefore (qName)) {
                            newline ();
                            doIndent ();
                        } else if (indentBefore (qName))
                            doIndent ();
                        // else it's inlined, modulo line length
                        // FIXME: incrementing element nest level
                        // for inlined elements causes ugliness
                    } else
                        doIndent ();
                }
            }
            elementNestLevel++;
            writeStartTag (qName, atts, xhtml && isEmptyElementTag (qName));

            if (xhtml) {
// FIXME: if this is an XHTML "pre" element, turn
// off automatic wrapping.
            }

        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /**
     * Writes an empty element.
     * @see #startElement
     */
    public void writeEmptyElement (
        String uri,
        String localName,
        String qName,
        Attributes atts
    ) throws SAXException
    {
        if (canonical) {
            startElement (uri, localName, qName, atts);
            endElement (uri, localName, qName);
        } else {
            try {
                writeStartTag (qName, atts, true);
            } catch (IOException e) {
                fatal ("can't write", e);
            }
        }
    }


    /** <b>SAX2</b>:  indicates the end of an element */
    final public void endElement (String uri, String localName, String qName)
    throws SAXException
    {
        if (qName == null || "".equals (qName))
            throw new IllegalArgumentException ("no XML name");

        try {
            elementNestLevel--;
            if (entityNestLevel != 0)
                return;
            if (xhtml && isEmptyElementTag (qName))
                return;
            rawWrite ("</");
            rawWrite (qName);
            rawWrite ('>');

            if (prettyPrinting) {
                if (!space.empty ())
                    space.pop ();
                else
                    fatal ("stack discipline", null);
            }
            if (elementNestLevel == 0)
                inEpilogue = true;

        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX1</b>:  reports content characters */
    final public void characters (char ch [], int start, int length)
    throws SAXException
    {
        if (locator == null)
            locator = new LocatorImpl ();

        try {
            if (entityNestLevel != 0)
                return;
            if (inCDATA) {
                escapeChars (ch, start, length, CTX_UNPARSED);
            } else {
                escapeChars (ch, start, length, CTX_CONTENT);
            }
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX1</b>:  reports ignorable whitespace */
    final public void ignorableWhitespace (char ch [], int start, int length)
    throws SAXException
    {
        if (locator == null)
            locator = new LocatorImpl ();

        try {
            if (entityNestLevel != 0)
                return;
            // don't forget to map NL to CRLF, CR, etc
            escapeChars (ch, start, length, CTX_CONTENT);
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /**
     * <b>SAX1</b>:  reports a PI.
     * This doesn't check for illegal target names, such as "xml" or "XML",
     * or namespace-incompatible ones like "big:dog"; the caller is
     * responsible for ensuring those names are legal.
     */
    final public void processingInstruction (String target, String data)
    throws SAXException
    {
        if (locator == null)
            locator = new LocatorImpl ();

        // don't print internal subset for XHTML
        if (xhtml && startedDoctype)
            return;

        // ancient HTML browsers might render these ... their loss.
        // to prevent:  "if (xhtml) return;".

        try {
            if (entityNestLevel != 0)
                return;
            if (canonical && inEpilogue)
                newline ();
            rawWrite ("<?");
            rawWrite (target);
            rawWrite (' ');
            escapeChars (data.toCharArray (), -1, -1, CTX_UNPARSED);
            rawWrite ("?>");
            if (elementNestLevel == 0 && !(canonical && inEpilogue))
                newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX1</b>: indicates a non-expanded entity reference */
    public void skippedEntity (String name)
    throws SAXException
    {
        try {
            rawWrite ("&");
            rawWrite (name);
            rawWrite (";");
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    // SAX2 LexicalHandler

    /** <b>SAX2</b>:  called before parsing CDATA characters */
    final public void startCDATA ()
    throws SAXException
    {
        if (locator == null)
            locator = new LocatorImpl ();

        if (canonical)
            return;

        try {
            inCDATA = true;
            if (entityNestLevel == 0)
                rawWrite ("<![CDATA[");
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX2</b>:  called after parsing CDATA characters */
    final public void endCDATA ()
    throws SAXException
    {
        if (canonical)
            return;

        try {
            inCDATA = false;
            if (entityNestLevel == 0)
                rawWrite ("]]>");
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /**
     * <b>SAX2</b>:  called when the doctype is partially parsed
     * Note that this, like other doctype related calls, is ignored
     * when XHTML is in use.
     */
    final public void startDTD (String name, String publicId, String systemId)
    throws SAXException
    {
        if (locator == null)
            locator = new LocatorImpl ();
        if (xhtml)
            return;
        try {
            inDoctype = startedDoctype = true;
            if (canonical)
                return;
            rawWrite ("<!DOCTYPE ");
            rawWrite (name);
            rawWrite (' ');

            if (!expandingEntities) {
                if (publicId != null)
                    rawWrite ("PUBLIC '" + publicId + "' '" + systemId + "' ");
                else if (systemId != null)
                    rawWrite ("SYSTEM '" + systemId + "' ");
            }

            rawWrite ('[');
            newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX2</b>:  called after the doctype is parsed */
    final public void endDTD ()
    throws SAXException
    {
        inDoctype = false;
        if (canonical || xhtml)
            return;
        try {
            rawWrite ("]>");
            newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /**
     * <b>SAX2</b>:  called before parsing a general entity in content
     */
    final public void startEntity (String name)
    throws SAXException
    {
        try {
            boolean     writeEOL = true;

            // Predefined XHTML entities (for characters) will get
            // mapped back later.
            if (xhtml || expandingEntities)
                return;

            entityNestLevel++;
            if (name.equals ("[dtd]"))
                return;
            if (entityNestLevel != 1)
                return;
            if (!name.startsWith ("%")) {
                writeEOL = false;
                rawWrite ('&');
            }
            rawWrite (name);
            rawWrite (';');
            if (writeEOL)
                newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /**
     * <b>SAX2</b>:  called after parsing a general entity in content
     */
    final public void endEntity (String name)
    throws SAXException
    {
        if (xhtml || expandingEntities)
            return;
        entityNestLevel--;
    }

    /**
     * <b>SAX2</b>:  called when comments are parsed.
     * When XHTML is used, the old HTML tradition of using comments
     * to for inline CSS, or for JavaScript code is  discouraged.
     * This is because XML processors are encouraged to discard, on
     * the grounds that comments are for users (and perhaps text
     * editors) not programs.  Instead, use external scripts
     */
    final public void comment (char ch [], int start, int length)
    throws SAXException
    {
        if (locator == null)
            locator = new LocatorImpl ();

        // don't print internal subset for XHTML
        if (xhtml && startedDoctype)
            return;
        // don't print comment in doctype for canon xml
        if (canonical && inDoctype)
            return;

        try {
            boolean indent;

            if (prettyPrinting && space.empty ())
                fatal ("stack discipline", null);
            indent = prettyPrinting && "default".equals (space.peek ());
            if (entityNestLevel != 0)
                return;
            if (indent)
                doIndent ();
            if (canonical && inEpilogue)
                newline ();
            rawWrite ("<!--");
            escapeChars (ch, start, length, CTX_UNPARSED);
            rawWrite ("-->");
            if (indent)
                doIndent ();
            if (elementNestLevel == 0 && !(canonical && inEpilogue))
                newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    // SAX1 DTDHandler

    /** <b>SAX1</b>:  called on notation declarations */
    final public void notationDecl (String name,
        String publicId, String systemId)
    throws SAXException
    {
        if (xhtml)
            return;
        try {
            // At this time, only SAX2 callbacks start these.
            if (!startedDoctype)
                return;

            if (entityNestLevel != 0)
                return;
            rawWrite ("<!NOTATION " + name + " ");
            if (publicId != null)
                rawWrite ("PUBLIC \"" + publicId + '"');
            else
                rawWrite ("SYSTEM ");
            if (systemId != null)
                rawWrite ('"' + systemId + '"');
            rawWrite (">");
            newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX1</b>:  called on unparsed entity declarations */
    final public void unparsedEntityDecl (String name,
        String publicId, String systemId,
        String notationName)
    throws SAXException
    {
        if (xhtml)
            return;
        try {
            // At this time, only SAX2 callbacks start these.
            if (!startedDoctype)  {
                // FIXME: write to temporary buffer, and make the start
                // of the root element write these declarations.
                return;
            }

            if (entityNestLevel != 0)
                return;
            rawWrite ("<!ENTITY " + name + " ");
            if (publicId != null)
                rawWrite ("PUBLIC \"" + publicId + '"');
            else
                rawWrite ("SYSTEM ");
            rawWrite ('"' + systemId + '"');
            rawWrite (" NDATA " + notationName + ">");
            newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    // SAX2 DeclHandler

    /** <b>SAX2</b>:  called on attribute declarations */
    final public void attributeDecl (String eName, String aName,
            String type, String mode, String value)
    throws SAXException
    {
        if (xhtml)
            return;
        try {
            // At this time, only SAX2 callbacks start these.
            if (!startedDoctype)
                return;
            if (entityNestLevel != 0)
                return;
            rawWrite ("<!ATTLIST " + eName + ' ' + aName + ' ');
            rawWrite (type);
            rawWrite (' ');
            if (mode != null)
                rawWrite (mode + ' ');
            if (value != null)
                writeQuotedValue (value, CTX_ATTRIBUTE);
            rawWrite ('>');
            newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX2</b>:  called on element declarations */
    final public void elementDecl (String name, String model)
    throws SAXException
    {
        if (xhtml)
            return;
        try {
            // At this time, only SAX2 callbacks start these.
            if (!startedDoctype)
                return;
            if (entityNestLevel != 0)
                return;
            rawWrite ("<!ELEMENT " + name + ' ' + model + '>');
            newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX2</b>:  called on external entity declarations */
    final public void externalEntityDecl (
        String name,
        String publicId,
        String systemId)
    throws SAXException
    {
        if (xhtml)
            return;
        try {
            // At this time, only SAX2 callbacks start these.
            if (!startedDoctype)
                return;
            if (entityNestLevel != 0)
                return;
            rawWrite ("<!ENTITY ");
            if (name.startsWith ("%")) {
                rawWrite ("% ");
                rawWrite (name.substring (1));
            } else
                rawWrite (name);
            if (publicId != null)
                rawWrite (" PUBLIC \"" + publicId + '"');
            else
                rawWrite (" SYSTEM ");
            rawWrite ('"' + systemId + "\">");
            newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    /** <b>SAX2</b>:  called on internal entity declarations */
    final public void internalEntityDecl (String name, String value)
    throws SAXException
    {
        if (xhtml)
            return;
        try {
            // At this time, only SAX2 callbacks start these.
            if (!startedDoctype)
                return;
            if (entityNestLevel != 0)
                return;
            rawWrite ("<!ENTITY ");
            if (name.startsWith ("%")) {
                rawWrite ("% ");
                rawWrite (name.substring (1));
            } else
                rawWrite (name);
            rawWrite (' ');
            writeQuotedValue (value, CTX_ENTITY);
            rawWrite ('>');
            newline ();
        } catch (IOException e) {
            fatal ("can't write", e);
        }
    }

    private void writeQuotedValue (String value, int code)
    throws SAXException, IOException
    {
        char    buf [] = value.toCharArray ();
        int     off = 0, len = buf.length;

        // we can't add line breaks to attribute/entity/... values
        noWrap = true;
        rawWrite ('"');
        escapeChars (buf, off, len, code);
        rawWrite ('"');
        noWrap = false;
    }

    // From "HTMLlat1x.ent" ... names of entities for ISO-8859-1
    // (Latin/1) characters, all codes:  160-255 (0xA0-0xFF).
    // Codes 128-159 have no assigned values.
    private static final String HTMLlat1x [] = {
        // 160
        "nbsp", "iexcl", "cent", "pound", "curren",
        "yen", "brvbar", "sect", "uml", "copy",

        // 170
        "ordf", "laquo", "not", "shy", "reg",
        "macr", "deg", "plusmn", "sup2", "sup3",

        // 180
        "acute", "micro", "para", "middot", "cedil",
        "sup1", "ordm", "raquo", "frac14", "frac12",

        // 190
        "frac34", "iquest", "Agrave", "Aacute", "Acirc",
        "Atilde", "Auml", "Aring", "AElig", "Ccedil",

        // 200
        "Egrave", "Eacute", "Ecirc", "Euml", "Igrave",
        "Iacute", "Icirc", "Iuml", "ETH", "Ntilde",

        // 210
        "Ograve", "Oacute", "Ocirc", "Otilde", "Ouml",
        "times", "Oslash", "Ugrave", "Uacute", "Ucirc",

        // 220
        "Uuml", "Yacute", "THORN", "szlig", "agrave",
        "aacute", "acirc", "atilde", "auml", "aring",

        // 230
        "aelig", "ccedil", "egrave", "eacute", "ecirc",
        "euml", "igrave", "iacute", "icirc", "iuml",

        // 240
        "eth", "ntilde", "ograve", "oacute", "ocirc",
        "otilde", "ouml", "divide", "oslash", "ugrave",

        // 250
        "uacute", "ucirc", "uuml", "yacute", "thorn",
        "yuml"
    };

    // From "HTMLsymbolx.ent" ... some of the symbols that
    // we can conveniently handle.  Entities for the Greek.
    // alphabet (upper and lower cases) are compact.
    private static final String HTMLsymbolx_GR [] = {
        // 913
        "Alpha", "Beta", "Gamma", "Delta", "Epsilon",
        "Zeta", "Eta", "Theta", "Iota", "Kappa",

        // 923
        "Lambda", "Mu", "Nu", "Xi", "Omicron",
        "Pi", "Rho", null, "Sigma", "Tau",

        // 933
        "Upsilon", "Phi", "Chi", "Psi", "Omega"
    };

    private static final String HTMLsymbolx_gr [] = {
        // 945
        "alpha", "beta", "gamma", "delta", "epsilon",
        "zeta", "eta", "theta", "iota", "kappa",

        // 955
        "lambda", "mu", "nu", "xi", "omicron",
        "pi", "rho", "sigmaf", "sigma", "tau",

        // 965
        "upsilon", "phi", "chi", "psi", "omega"
    };


    // General routine to write text and substitute predefined
    // entities (XML, and a special case for XHTML) as needed.
    private void escapeChars (char buf [], int off, int len, int code)
    throws SAXException, IOException
    {
        int     first = 0;

        if (off < 0) {
            off = 0;
            len = buf.length;
        }
        for (int i = 0; i < len; i++) {
            String      esc;
            char        c = buf [off + i];

            switch (c) {
              // Note that CTX_ATTRIBUTE isn't explicitly tested here;
              // all syntax delimiters are escaped in CTX_ATTRIBUTE,
              // otherwise it's similar to CTX_CONTENT

              // ampersand flags entity references; entity replacement
              // text has unexpanded references, other text doesn't.
              case '&':
                if (code == CTX_ENTITY || code == CTX_UNPARSED)
                    continue;
                esc = "amp";
                break;

              // attributes and text may NOT have literal '<', but
              // entities may have markup constructs
              case '<':
                if (code == CTX_ENTITY || code == CTX_UNPARSED)
                    continue;
                esc = "lt";
                break;

              // as above re markup constructs; but otherwise
              // except when canonicalizing, this is for consistency
              case '>':
                if (code == CTX_ENTITY || code == CTX_UNPARSED)
                    continue;
                esc = "gt";
                break;
              case '\'':
                if (code == CTX_CONTENT || code == CTX_UNPARSED)
                    continue;
                if (canonical)
                    continue;
                esc = "apos";
                break;

              // needed when printing quoted attribute/entity values
              case '"':
                if (code == CTX_CONTENT || code == CTX_UNPARSED)
                    continue;
                esc = "quot";
                break;

              // make line ends work per host OS convention
              case '\n':
                esc = eol;
                break;

              //
              // No other characters NEED special treatment ... except
              // for encoding-specific issues, like whether the character
              // can really be represented in that encoding.
              //
              default:
                //
                // There are characters we can never write safely; getting
                // them is an error.
                //
                //   (a) They're never legal in XML ... detected by range
                //      checks, and (eventually) by remerging surrogate
                //      pairs on output.  (Easy error for apps to prevent.)
                //
                //   (b) This encoding can't represent them, and we
                //      can't make reference substitution (e.g. inside
                //      CDATA sections, names, PI data, etc).  (Hard for
                //      apps to prevent, except by using UTF-8 or UTF-16
                //      as their output encoding.)
                //
                // We know a very little bit about what characters
                // the US-ASCII and ISO-8859-1 encodings support.  For
                // other encodings we can't detect the second type of
                // error at all.  (Never an issue for UTF-8 or UTF-16.)
                //

// FIXME:  CR in CDATA is an error; in text, turn to a char ref

// FIXME:  CR/LF/TAB in attributes should become char refs

                if ((c > 0xfffd)
                        || ((c < 0x0020) && !((c == 0x0009)
                                || (c == 0x000A) || (c == 0x000D)))
                        || (((c & dangerMask) != 0)
                            && (code == CTX_UNPARSED))) {

                    // if case (b) in CDATA, we might end the section,
                    // write a reference, then restart ... possible
                    // in one DOM L3 draft.

                    throw new CharConversionException (
                            "Illegal or non-writable character: U+"
                            + Integer.toHexString (c));
                }

                //
                // If the output encoding represents the character
                // directly, let it do so!  Else we'll escape it.
                //
                if ((c & dangerMask) == 0)
                    continue;
                esc = null;

                // Avoid numeric refs where symbolic ones exist, as
                // symbolic ones make more sense to humans reading!
                if (xhtml) {
                    // all the HTMLlat1x.ent entities
                    // (all the "ISO-8859-1" characters)
                    if (c >= 160 && c <= 255)
                        esc = HTMLlat1x [c - 160];

                    // not quite half the HTMLsymbolx.ent entities
                    else if (c >= 913 && c <= 937)
                        esc = HTMLsymbolx_GR [c - 913];
                    else if (c >= 945 && c <= 969)
                        esc = HTMLsymbolx_gr [c - 945];

                    else switch (c) {
                        // all of the HTMLspecialx.ent entities
                        case  338: esc = "OElig";       break;
                        case  339: esc = "oelig";       break;
                        case  352: esc = "Scaron";      break;
                        case  353: esc = "scaron";      break;
                        case  376: esc = "Yuml";        break;
                        case  710: esc = "circ";        break;
                        case  732: esc = "tilde";       break;
                        case 8194: esc = "ensp";        break;
                        case 8195: esc = "emsp";        break;
                        case 8201: esc = "thinsp";      break;
                        case 8204: esc = "zwnj";        break;
                        case 8205: esc = "zwj";         break;
                        case 8206: esc = "lrm";         break;
                        case 8207: esc = "rlm";         break;
                        case 8211: esc = "ndash";       break;
                        case 8212: esc = "mdash";       break;
                        case 8216: esc = "lsquo";       break;
                        case 8217: esc = "rsquo";       break;
                        case 8218: esc = "sbquo";       break;
                        case 8220: esc = "ldquo";       break;
                        case 8221: esc = "rdquo";       break;
                        case 8222: esc = "bdquo";       break;
                        case 8224: esc = "dagger";      break;
                        case 8225: esc = "Dagger";      break;
                        case 8240: esc = "permil";      break;
                        case 8249: esc = "lsaquo";      break;
                        case 8250: esc = "rsaquo";      break;
                        case 8364: esc = "euro";        break;

                        // the other HTMLsymbox.ent entities
                        case  402: esc = "fnof";        break;
                        case  977: esc = "thetasym";    break;
                        case  978: esc = "upsih";       break;
                        case  982: esc = "piv";         break;
                        case 8226: esc = "bull";        break;
                        case 8230: esc = "hellip";      break;
                        case 8242: esc = "prime";       break;
                        case 8243: esc = "Prime";       break;
                        case 8254: esc = "oline";       break;
                        case 8260: esc = "frasl";       break;
                        case 8472: esc = "weierp";      break;
                        case 8465: esc = "image";       break;
                        case 8476: esc = "real";        break;
                        case 8482: esc = "trade";       break;
                        case 8501: esc = "alefsym";     break;
                        case 8592: esc = "larr";        break;
                        case 8593: esc = "uarr";        break;
                        case 8594: esc = "rarr";        break;
                        case 8595: esc = "darr";        break;
                        case 8596: esc = "harr";        break;
                        case 8629: esc = "crarr";       break;
                        case 8656: esc = "lArr";        break;
                        case 8657: esc = "uArr";        break;
                        case 8658: esc = "rArr";        break;
                        case 8659: esc = "dArr";        break;
                        case 8660: esc = "hArr";        break;
                        case 8704: esc = "forall";      break;
                        case 8706: esc = "part";        break;
                        case 8707: esc = "exist";       break;
                        case 8709: esc = "empty";       break;
                        case 8711: esc = "nabla";       break;
                        case 8712: esc = "isin";        break;
                        case 8713: esc = "notin";       break;
                        case 8715: esc = "ni";          break;
                        case 8719: esc = "prod";        break;
                        case 8721: esc = "sum";         break;
                        case 8722: esc = "minus";       break;
                        case 8727: esc = "lowast";      break;
                        case 8730: esc = "radic";       break;
                        case 8733: esc = "prop";        break;
                        case 8734: esc = "infin";       break;
                        case 8736: esc = "ang";         break;
                        case 8743: esc = "and";         break;
                        case 8744: esc = "or";          break;
                        case 8745: esc = "cap";         break;
                        case 8746: esc = "cup";         break;
                        case 8747: esc = "int";         break;
                        case 8756: esc = "there4";      break;
                        case 8764: esc = "sim";         break;
                        case 8773: esc = "cong";        break;
                        case 8776: esc = "asymp";       break;
                        case 8800: esc = "ne";          break;
                        case 8801: esc = "equiv";       break;
                        case 8804: esc = "le";          break;
                        case 8805: esc = "ge";          break;
                        case 8834: esc = "sub";         break;
                        case 8835: esc = "sup";         break;
                        case 8836: esc = "nsub";        break;
                        case 8838: esc = "sube";        break;
                        case 8839: esc = "supe";        break;
                        case 8853: esc = "oplus";       break;
                        case 8855: esc = "otimes";      break;
                        case 8869: esc = "perp";        break;
                        case 8901: esc = "sdot";        break;
                        case 8968: esc = "lceil";       break;
                        case 8969: esc = "rceil";       break;
                        case 8970: esc = "lfloor";      break;
                        case 8971: esc = "rfloor";      break;
                        case 9001: esc = "lang";        break;
                        case 9002: esc = "rang";        break;
                        case 9674: esc = "loz";         break;
                        case 9824: esc = "spades";      break;
                        case 9827: esc = "clubs";       break;
                        case 9829: esc = "hearts";      break;
                        case 9830: esc = "diams";       break;
                    }
                }

                // else escape with numeric char refs
                if (esc == null) {
                    stringBuf.setLength (0);
                    stringBuf.append ("#x");
                    stringBuf.append (Integer.toHexString (c).toUpperCase ());
                    esc = stringBuf.toString ();

                    // FIXME:  We don't write surrogate pairs correctly.
                    // They should work as one ref per character, since
                    // each pair is one character.  For reading back into
                    // Unicode, it matters beginning in Unicode 3.1 ...
                }
                break;
            }
            if (i != first)
                rawWrite (buf, off + first, i - first);
            first = i + 1;
            if (esc == eol)
                newline ();
            else {
                rawWrite ('&');
                rawWrite (esc);
                rawWrite (';');
            }
        }
        if (first < len)
            rawWrite (buf, off + first, len - first);
    }



    private void newline ()
    throws SAXException, IOException
    {
        out.write (eol);
        column = 0;
    }

    private void doIndent ()
    throws SAXException, IOException
    {
        int     space = elementNestLevel * 2;

        newline ();
        column = space;
        // track tabs only at line starts
        while (space > 8) {
            out.write ("\t");
            space -= 8;
        }
        while (space > 0) {
            out.write ("  ");
            space -= 2;
        }
    }

    private void rawWrite (char c)
    throws IOException
    {
        out.write (c);
        column++;
    }

    private void rawWrite (String s)
    throws SAXException, IOException
    {
        if (prettyPrinting && "default".equals (space.peek ())) {
            char data [] = s.toCharArray ();
            rawWrite (data, 0, data.length);
        } else {
            out.write (s);
            column += s.length ();
        }
    }

    // NOTE:  if xhtml, the REC gives some rules about whitespace
    // which we could follow ... notably, many places where conformant
    // agents "must" consolidate/normalize whitespace.  Line ends can
    // be removed there, etc.  This may not be the right place to do
    // such mappings though.

    // Line buffering may help clarify algorithms and improve results.

    // It's likely xml:space needs more attention.

    private void rawWrite (char buf [], int offset, int length)
    throws SAXException, IOException
    {
        boolean         wrap;

        if (prettyPrinting && space.empty ())
            fatal ("stack discipline", null);

        wrap = prettyPrinting && "default".equals (space.peek ());
        if (!wrap) {
            out.write (buf, offset, length);
            column += length;
            return;
        }

        // we're pretty printing and want to fill lines out only
        // to the desired line length.
        while (length > 0) {
            int         target = lineLength - column;
            boolean     wrote = false;

            // Do we even have a problem?
            if (target > length || noWrap) {
                out.write (buf, offset, length);
                column += length;
                return;
            }

            // break the line at a space character, trying to fill
            // as much of the line as possible.
            char        c;

            for (int i = target - 1; i >= 0; i--) {
                if ((c = buf [offset + i]) == ' ' || c == '\t') {
                    i++;
                    out.write (buf, offset, i);
                    doIndent ();
                    offset += i;
                    length -= i;
                    wrote = true;
                    break;
                }
            }
            if (wrote)
                continue;

            // no space character permitting break before target
            // line length is filled.  So, take the next one.
            if (target < 0)
                target = 0;
            for (int i = target; i < length; i++)
                if ((c = buf [offset + i]) == ' ' || c == '\t') {
                    i++;
                    out.write (buf, offset, i);
                    doIndent ();
                    offset += i;
                    length -= i;
                    wrote = true;
                    break;
                }
            if (wrote)
                continue;

            // no such luck.
            out.write (buf, offset, length);
            column += length;
            break;
        }
    }
}
