/* XmlParser.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.

Partly derived from code which carried the following notice:

  Copyright (c) 1997, 1998 by Microstar Software Ltd.

  AElfred is free for both commercial and non-commercial use and
  redistribution, provided that Microstar's copyright and disclaimer are
  retained intact.  You are free to modify AElfred for your own use and
  to redistribute AElfred with your modifications, provided that the
  modifications are clearly documented.

  This program 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.  Please use it AT
  YOUR OWN RISK.
*/

package gnu.xml.aelfred2;

import gnu.java.security.action.GetPropertyAction;

import java.io.BufferedInputStream;
import java.io.CharConversionException;
import java.io.EOFException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessController;

import java.util.Iterator;
import java.util.HashMap;
import java.util.LinkedList;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


/**
 * Parse XML documents and return parse events through call-backs.
 * Use the <code>SAXDriver</code> class as your entry point, as all
 * internal parser interfaces are subject to change.
 *
 * @author Written by David Megginson &lt;dmeggins@microstar.com&gt;
 *      (version 1.2a with bugfixes)
 * @author Updated by David Brownell &lt;dbrownell@users.sourceforge.net&gt;
 * @see SAXDriver
 */
final class XmlParser
{

  // avoid slow per-character readCh()
  private final static boolean USE_CHEATS = true;

  ////////////////////////////////////////////////////////////////////////
  // Constants.
  ////////////////////////////////////////////////////////////////////////

  //
  // Constants for element content type.
  //

  /**
   * Constant: an element has not been declared.
   * @see #getElementContentType
   */
  public final static int CONTENT_UNDECLARED = 0;

  /**
   * Constant: the element has a content model of ANY.
   * @see #getElementContentType
   */
  public final static int CONTENT_ANY = 1;

  /**
   * Constant: the element has declared content of EMPTY.
   * @see #getElementContentType
   */
  public final static int CONTENT_EMPTY = 2;

  /**
   * Constant: the element has mixed content.
   * @see #getElementContentType
   */
  public final static int CONTENT_MIXED = 3;

  /**
   * Constant: the element has element content.
   * @see #getElementContentType
   */
  public final static int CONTENT_ELEMENTS = 4;


  //
  // Constants for the entity type.
  //

  /**
   * Constant: the entity has not been declared.
   * @see #getEntityType
   */
  public final static int ENTITY_UNDECLARED = 0;

  /**
   * Constant: the entity is internal.
   * @see #getEntityType
   */
  public final static int ENTITY_INTERNAL = 1;

  /**
   * Constant: the entity is external, non-parsable data.
   * @see #getEntityType
   */
  public final static int ENTITY_NDATA = 2;

  /**
   * Constant: the entity is external XML data.
   * @see #getEntityType
   */
  public final static int ENTITY_TEXT = 3;

  //
  // Attribute type constants are interned literal strings.
  //

  //
  // Constants for supported encodings.  "external" is just a flag.
  //
  private final static int ENCODING_EXTERNAL = 0;
  private final static int ENCODING_UTF_8 = 1;
  private final static int ENCODING_ISO_8859_1 = 2;
  private final static int ENCODING_UCS_2_12 = 3;
  private final static int ENCODING_UCS_2_21 = 4;
  private final static int ENCODING_UCS_4_1234 = 5;
  private final static int ENCODING_UCS_4_4321 = 6;
  private final static int ENCODING_UCS_4_2143 = 7;
  private final static int ENCODING_UCS_4_3412 = 8;
  private final static int ENCODING_ASCII = 9;

  //
  // Constants for attribute default value.
  //

  /**
   * Constant: the attribute is not declared.
   * @see #getAttributeDefaultValueType
   */
  public final static int ATTRIBUTE_DEFAULT_UNDECLARED = 30;

  /**
   * Constant: the attribute has a literal default value specified.
   * @see #getAttributeDefaultValueType
   * @see #getAttributeDefaultValue
   */
  public final static int ATTRIBUTE_DEFAULT_SPECIFIED = 31;

  /**
   * Constant: the attribute was declared #IMPLIED.
   * @see #getAttributeDefaultValueType
   */
  public final static int ATTRIBUTE_DEFAULT_IMPLIED = 32;

  /**
   * Constant: the attribute was declared #REQUIRED.
   * @see #getAttributeDefaultValueType
   */
  public final static int ATTRIBUTE_DEFAULT_REQUIRED = 33;

  /**
   * Constant: the attribute was declared #FIXED.
   * @see #getAttributeDefaultValueType
   * @see #getAttributeDefaultValue
   */
  public final static int ATTRIBUTE_DEFAULT_FIXED = 34;

  //
  // Constants for input.
  //
  private final static int INPUT_NONE = 0;
  private final static int INPUT_INTERNAL = 1;
  private final static int INPUT_STREAM = 3;
  private final static int INPUT_READER = 5;

  //
  // Flags for reading literals.
  //
  // expand general entity refs (attribute values in dtd and content)
  private final static int LIT_ENTITY_REF = 2;
  // normalize this value (space chars) (attributes, public ids)
  private final static int LIT_NORMALIZE = 4;
  // literal is an attribute value
  private final static int LIT_ATTRIBUTE = 8;
  // don't expand parameter entities
  private final static int LIT_DISABLE_PE = 16;
  // don't expand [or parse] character refs
  private final static int LIT_DISABLE_CREF = 32;
  // don't parse general entity refs
  private final static int LIT_DISABLE_EREF = 64;
  // literal is a public ID value
  private final static int LIT_PUBID = 256;

  //
  // Flags affecting PE handling in DTDs (if expandPE is true).
  // PEs expand with space padding, except inside literals.
  //
  private final static int CONTEXT_NORMAL = 0;
  private final static int CONTEXT_LITERAL = 1;

  // Emit warnings for relative URIs with no base URI.
  static boolean uriWarnings;
  static
  {
    String key = "gnu.xml.aelfred2.XmlParser.uriWarnings";
    GetPropertyAction a = new GetPropertyAction(key);
    uriWarnings = "true".equals(AccessController.doPrivileged(a));
  }

  //
  // The current XML handler interface.
  //
  private SAXDriver handler;

  //
  // I/O information.
  //
  private Reader reader;   // current reader
  private InputStream is;     // current input stream
  private int line;     // current line number
  private int column;   // current column number
  private int sourceType;   // type of input source
  private LinkedList inputStack;   // stack of input soruces
  private URLConnection externalEntity; // current external entity
  private int encoding;   // current character encoding
  private int currentByteCount; // bytes read from current source
  private InputSource scratch;  // temporary

  //
  // Buffers for decoded but unparsed character input.
  //
  private char[] readBuffer;
  private int readBufferPos;
  private int readBufferLength;
  private int readBufferOverflow;  // overflow from last data chunk.

  //
  // Buffer for undecoded raw byte input.
  //
  private final static int READ_BUFFER_MAX = 16384;
  private byte[] rawReadBuffer;


  //
  // Buffer for attribute values, char refs, DTD stuff.
  //
  private static int DATA_BUFFER_INITIAL = 4096;
  private char[] dataBuffer;
  private int dataBufferPos;

  //
  // Buffer for parsed names.
  //
  private static int NAME_BUFFER_INITIAL = 1024;
  private char[] nameBuffer;
  private int nameBufferPos;

  //
  // Save any standalone flag
  //
  private boolean docIsStandalone;

  //
  // Hashtables for DTD information on elements, entities, and notations.
  // Populated until we start ignoring decls (because of skipping a PE)
  //
  private HashMap elementInfo;
  private HashMap entityInfo;
  private HashMap notationInfo;
  private boolean skippedPE;

  //
  // Element type currently in force.
  //
  private String currentElement;
  private int currentElementContent;

  //
  // Stack of entity names, to detect recursion.
  //
  private LinkedList entityStack;

  //
  // PE expansion is enabled in most chunks of the DTD, not all.
  // When it's enabled, literals are treated differently.
  //
  private boolean inLiteral;
  private boolean expandPE;
  private boolean peIsError;

  //
  // can't report entity expansion inside two constructs:
  // - attribute expansions (internal entities only)
  // - markup declarations (parameter entities only)
  //
  private boolean doReport;

  //
  // Symbol table, for caching interned names.
  //
  // These show up wherever XML names or nmtokens are used:  naming elements,
  // attributes, PIs, notations, entities, and enumerated attribute values.
  //
  // NOTE:  This hashtable doesn't grow.  The default size is intended to be
  // rather large for most documents.  Example:  one snapshot of the DocBook
  // XML 4.1 DTD used only about 350 such names.  As a rule, only pathological
  // documents (ones that don't reuse names) should ever see much collision.
  //
  // Be sure that SYMBOL_TABLE_LENGTH always stays prime, for best hashing.
  // "2039" keeps the hash table size at about two memory pages on typical
  // 32 bit hardware.
  //
  private final static int SYMBOL_TABLE_LENGTH = 2039;

  private Object[][] symbolTable;

  //
  // Hash table of attributes found in current start tag.
  //
  private String[] tagAttributes;
  private int tagAttributePos;

  //
  // Utility flag: have we noticed a CR while reading the last
  // data chunk?  If so, we will have to go back and normalise
  // CR or CR/LF line ends.
  //
  private boolean sawCR;

  //
  // Utility flag: are we in CDATA?  If so, whitespace isn't ignorable.
  //
  private boolean inCDATA;

  //
  // Xml version.
  //
  private static final int XML_10 = 0;
  private static final int XML_11 = 1;
  private int xmlVersion = XML_10;

  //////////////////////////////////////////////////////////////////////
  // Constructors.
  ////////////////////////////////////////////////////////////////////////

  /**
   * Construct a new parser with no associated handler.
   * @see #setHandler
   * @see #parse
   */
  // package private
  XmlParser()
  {
  }

  /**
   * Set the handler that will receive parsing events.
   * @param handler The handler to receive callback events.
   * @see #parse
   */
  // package private
  void setHandler(SAXDriver handler)
  {
    this.handler = handler;
  }

  /**
   * Parse an XML document from the character stream, byte stream, or URI
   * that you provide (in that order of preference).  Any URI that you
   * supply will become the base URI for resolving relative URI, and may
   * be used to acquire a reader or byte stream.
   *
   * <p> Only one thread at a time may use this parser; since it is
   * private to this package, post-parse cleanup is done by the caller,
   * which MUST NOT REUSE the parser (just null it).
   *
   * @param systemId Absolute URI of the document; should never be null,
   *    but may be so iff a reader <em>or</em> a stream is provided.
   * @param publicId The public identifier of the document, or null.
   * @param reader A character stream; must be null if stream isn't.
   * @param stream A byte input stream; must be null if reader isn't.
   * @param encoding The suggested encoding, or null if unknown.
   * @exception java.lang.Exception Basically SAXException or IOException
   */
  // package private
  void doParse(String systemId, String publicId, Reader reader,
               InputStream stream, String encoding)
    throws Exception
  {
    if (handler == null)
      {
        throw new IllegalStateException("no callback handler");
      }

    initializeVariables();

    // predeclare the built-in entities here (replacement texts)
    // we don't need to intern(), since we're guaranteed literals
    // are always (globally) interned.
    setInternalEntity("amp", "&#38;");
    setInternalEntity("lt", "&#60;");
    setInternalEntity("gt", "&#62;");
    setInternalEntity("apos", "&#39;");
    setInternalEntity("quot", "&#34;");

    try
      {
        // pushURL first to ensure locator is correct in startDocument
        // ... it might report an IO or encoding exception.
        handler.startDocument();
        pushURL(false, "[document]",
                // default baseURI: null
                new ExternalIdentifiers(publicId, systemId, null),
                reader, stream, encoding, false);

        parseDocument();
      }
    catch (EOFException e)
      {
        //empty input
        error("empty document, with no root element.");
      }
    finally
      {
        if (reader != null)
          {
            try
              {
                reader.close();
              }
            catch (IOException e)
              {
                /* ignore */
              }
          }
        if (stream != null)
          {
            try
              {
                stream.close();
              }
            catch (IOException e)
              {
                /* ignore */
              }
          }
        if (is != null)
          {
            try
              {
                is.close();
              }
            catch (IOException e)
              {
                /* ignore */
              }
          }
        scratch = null;
      }
  }

  //////////////////////////////////////////////////////////////////////
  // Error reporting.
  //////////////////////////////////////////////////////////////////////

  /**
   * Report an error.
   * @param message The error message.
   * @param textFound The text that caused the error (or null).
   * @see SAXDriver#error
   * @see #line
   */
  private void error(String message, String textFound, String textExpected)
    throws SAXException
  {
    if (textFound != null)
      {
        message = message + " (found \"" + textFound + "\")";
      }
    if (textExpected != null)
      {
        message = message + " (expected \"" + textExpected + "\")";
      }
    handler.fatal(message);

    // "can't happen"
    throw new SAXException(message);
  }

  /**
   * Report a serious error.
   * @param message The error message.
   * @param textFound The text that caused the error (or null).
   */
  private void error(String message, char textFound, String textExpected)
    throws SAXException
  {
    error(message, Character.toString(textFound), textExpected);
  }

  /**
   * Report typical case fatal errors.
   */
  private void error(String message)
    throws SAXException
  {
    handler.fatal(message);
  }

  //////////////////////////////////////////////////////////////////////
  // Major syntactic productions.
  //////////////////////////////////////////////////////////////////////

  /**
   * Parse an XML document.
   * <pre>
   * [1] document ::= prolog element Misc*
   * </pre>
   * <p>This is the top-level parsing function for a single XML
   * document.  As a minimum, a well-formed document must have
   * a document element, and a valid document must have a prolog
   * (one with doctype) as well.
   */
  private void parseDocument()
    throws Exception
  {
    try
      {                                       // added by MHK
        boolean sawDTD = parseProlog();
        require('<');
        parseElement(!sawDTD);
      }
    catch (EOFException ee)
      {                 // added by MHK
        error("premature end of file", "[EOF]", null);
      }

    try
      {
        parseMisc();   //skip all white, PIs, and comments
        char c = readCh();    //if this doesn't throw an exception...
        error("unexpected characters after document end", c, null);
      }
    catch (EOFException e)
      {
        return;
      }
  }

  static final char[] startDelimComment = { '<', '!', '-', '-' };
  static final char[] endDelimComment = { '-', '-' };

  /**
   * Skip a comment.
   * <pre>
   * [15] Comment ::= '&lt;!--' ((Char - '-') | ('-' (Char - '-')))* "-->"
   * </pre>
   * <p> (The <code>&lt;!--</code> has already been read.)
   */
  private void parseComment()
    throws Exception
  {
    char c;
    boolean saved = expandPE;

    expandPE = false;
    parseUntil(endDelimComment);
    require('>');
    expandPE = saved;
    handler.comment(dataBuffer, 0, dataBufferPos);
    dataBufferPos = 0;
  }

  static final char[] startDelimPI = { '<', '?' };
  static final char[] endDelimPI = { '?', '>' };

  /**
   * Parse a processing instruction and do a call-back.
   * <pre>
   * [16] PI ::= '&lt;?' PITarget
   *    (S (Char* - (Char* '?&gt;' Char*)))?
   *    '?&gt;'
   * [17] PITarget ::= Name - ( ('X'|'x') ('M'|m') ('L'|l') )
   * </pre>
   * <p> (The <code>&lt;?</code> has already been read.)
   */
  private void parsePI()
    throws SAXException, IOException
  {
    String name;
    boolean saved = expandPE;

    expandPE = false;
    name = readNmtoken(true);
    //NE08
    if (name.indexOf(':') >= 0)
      {
        error("Illegal character(':') in processing instruction name ",
              name, null);
      }
    if ("xml".equalsIgnoreCase(name))
      {
        error("Illegal processing instruction target", name, null);
      }
    if (!tryRead(endDelimPI))
      {
        requireWhitespace();
        parseUntil(endDelimPI);
      }
    expandPE = saved;
    handler.processingInstruction(name, dataBufferToString());
  }

  static final char[] endDelimCDATA = { ']', ']', '>' };

  private boolean isDirtyCurrentElement;

  /**
   * Parse a CDATA section.
   * <pre>
   * [18] CDSect ::= CDStart CData CDEnd
   * [19] CDStart ::= '&lt;![CDATA['
   * [20] CData ::= (Char* - (Char* ']]&gt;' Char*))
   * [21] CDEnd ::= ']]&gt;'
   * </pre>
   * <p> (The '&lt;![CDATA[' has already been read.)
   */
  private void parseCDSect()
    throws Exception
  {
    parseUntil(endDelimCDATA);
    dataBufferFlush();
  }

  /**
   * Parse the prolog of an XML document.
   * <pre>
   * [22] prolog ::= XMLDecl? Misc* (Doctypedecl Misc*)?
   * </pre>
   * <p>We do not look for the XML declaration here, because it was
   * handled by pushURL ().
   * @see pushURL
   * @return true if a DTD was read.
   */
  private boolean parseProlog()
    throws Exception
  {
    parseMisc();

    if (tryRead("<!DOCTYPE"))
      {
        parseDoctypedecl();
        parseMisc();
        return true;
      }
    return false;
  }

  private void checkLegalVersion(String version)
    throws SAXException
  {
    int len = version.length();
    for (int i = 0; i < len; i++)
      {
        char c = version.charAt(i);
        if ('0' <= c && c <= '9')
          {
            continue;
          }
        if (c == '_' || c == '.' || c == ':' || c == '-')
          {
            continue;
          }
        if ('a' <= c && c <= 'z')
          {
            continue;
          }
        if ('A' <= c && c <= 'Z')
          {
            continue;
          }
        error ("illegal character in version", version, "1.0");
      }
  }

  /**
   * Parse the XML declaration.
   * <pre>
   * [23] XMLDecl ::= '&lt;?xml' VersionInfo EncodingDecl? SDDecl? S? '?&gt;'
   * [24] VersionInfo ::= S 'version' Eq
   *    ("'" VersionNum "'" | '"' VersionNum '"' )
   * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')*
   * [32] SDDecl ::= S 'standalone' Eq
   *    ( "'"" ('yes' | 'no') "'"" | '"' ("yes" | "no") '"' )
   * [80] EncodingDecl ::= S 'encoding' Eq
   *    ( "'" EncName "'" | "'" EncName "'" )
   * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
   * </pre>
   * <p> (The <code>&lt;?xml</code> and whitespace have already been read.)
   * @return the encoding in the declaration, uppercased; or null
   * @see #parseTextDecl
   * @see #setupDecoding
   */
  private String parseXMLDecl(boolean ignoreEncoding)
    throws SAXException, IOException
  {
    String version;
    String encodingName = null;
    String standalone = null;
    int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;
    String inputEncoding = null;

    switch (this.encoding)
      {
      case ENCODING_EXTERNAL:
      case ENCODING_UTF_8:
        inputEncoding = "UTF-8";
        break;
      case ENCODING_ISO_8859_1:
        inputEncoding = "ISO-8859-1";
        break;
      case ENCODING_UCS_2_12:
        inputEncoding = "UTF-16BE";
        break;
      case ENCODING_UCS_2_21:
        inputEncoding = "UTF-16LE";
        break;
      }

    // Read the version.
    require("version");
    parseEq();
    checkLegalVersion(version = readLiteral(flags));
    if (!version.equals("1.0"))
      {
        if (version.equals("1.1"))
          {
            handler.warn("expected XML version 1.0, not: " + version);
            xmlVersion = XML_11;
          }
        else
          {
            error("illegal XML version", version, "1.0 or 1.1");
          }
      }
    else
      {
        xmlVersion = XML_10;
      }
    // Try reading an encoding declaration.
    boolean white = tryWhitespace();

    if (tryRead("encoding"))
      {
        if (!white)
          {
            error("whitespace required before 'encoding='");
          }
        parseEq();
        encodingName = readLiteral(flags);
        if (!ignoreEncoding)
          {
            setupDecoding(encodingName);
          }
      }

    // Try reading a standalone declaration
    if (encodingName != null)
      {
        white = tryWhitespace();
      }
    if (tryRead("standalone"))
      {
        if (!white)
          {
            error("whitespace required before 'standalone='");
          }
        parseEq();
        standalone = readLiteral(flags);
        if ("yes".equals(standalone))
          {
            docIsStandalone = true;
          }
        else if (!"no".equals(standalone))
          {
            error("standalone flag must be 'yes' or 'no'");
          }
      }

    skipWhitespace();
    require("?>");

    if (inputEncoding == null)
      {
        inputEncoding = encodingName;
      }
    return encodingName;
  }

  /**
   * Parse a text declaration.
   * <pre>
   * [79] TextDecl ::= '&lt;?xml' VersionInfo? EncodingDecl S? '?&gt;'
   * [80] EncodingDecl ::= S 'encoding' Eq
   *    ( '"' EncName '"' | "'" EncName "'" )
   * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
   * </pre>
   * <p> (The <code>&lt;?xml</code>' and whitespace have already been read.)
   * @return the encoding in the declaration, uppercased; or null
   * @see #parseXMLDecl
   * @see #setupDecoding
   */
  private String parseTextDecl(boolean ignoreEncoding)
    throws SAXException, IOException
  {
    String encodingName = null;
    int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;

    // Read an optional version.
    if (tryRead ("version"))
      {
        String version;
        parseEq();
        checkLegalVersion(version = readLiteral(flags));

        if (version.equals("1.1"))
          {
            if (xmlVersion == XML_10)
              {
                error("external subset has later version number.", "1.0",
                      version);
              }
            handler.warn("expected XML version 1.0, not: " + version);
            xmlVersion = XML_11;
          }
        else if (!version.equals("1.0"))
          {
            error("illegal XML version", version, "1.0 or 1.1");
          }
        requireWhitespace();
      }

    // Read the encoding.
    require("encoding");
    parseEq();
    encodingName = readLiteral(flags);
    if (!ignoreEncoding)
      {
        setupDecoding(encodingName);
      }
    skipWhitespace();
    require("?>");

    return encodingName;
  }

  /**
   * Sets up internal state so that we can decode an entity using the
   * specified encoding.  This is used when we start to read an entity
   * and we have been given knowledge of its encoding before we start to
   * read any data (e.g. from a SAX input source or from a MIME type).
   *
   * <p> It is also used after autodetection, at which point only very
   * limited adjustments to the encoding may be used (switching between
   * related builtin decoders).
   *
   * @param encodingName The name of the encoding specified by the user.
   * @exception IOException if the encoding isn't supported either
   *  internally to this parser, or by the hosting JVM.
   * @see #parseXMLDecl
   * @see #parseTextDecl
     */
  private void setupDecoding(String encodingName)
    throws SAXException, IOException
  {
    encodingName = encodingName.toUpperCase();

    // ENCODING_EXTERNAL indicates an encoding that wasn't
    // autodetected ... we can use builtin decoders, or
    // ones from the JVM (InputStreamReader).

    // Otherwise we can only tweak what was autodetected, and
    // only for single byte (ASCII derived) builtin encodings.

    // ASCII-derived encodings
    if (encoding == ENCODING_UTF_8 || encoding == ENCODING_EXTERNAL)
      {
        if (encodingName.equals("ISO-8859-1")
            || encodingName.equals("8859_1")
            || encodingName.equals("ISO8859_1"))
          {
            encoding = ENCODING_ISO_8859_1;
            return;
          }
        else if (encodingName.equals("US-ASCII")
                 || encodingName.equals("ASCII"))
          {
            encoding = ENCODING_ASCII;
            return;
          }
        else if (encodingName.equals("UTF-8")
                 || encodingName.equals("UTF8"))
          {
            encoding = ENCODING_UTF_8;
            return;
          }
        else if (encoding != ENCODING_EXTERNAL)
          {
            // used to start with a new reader ...
            throw new UnsupportedEncodingException(encodingName);
          }
        // else fallthrough ...
        // it's ASCII-ish and something other than a builtin
      }

    // Unicode and such
    if (encoding == ENCODING_UCS_2_12 || encoding == ENCODING_UCS_2_21)
      {
        if (!(encodingName.equals("ISO-10646-UCS-2")
              || encodingName.equals("UTF-16")
              || encodingName.equals("UTF-16BE")
              || encodingName.equals("UTF-16LE")))
          {
            error("unsupported Unicode encoding", encodingName, "UTF-16");
          }
        return;
      }

    // four byte encodings
    if (encoding == ENCODING_UCS_4_1234
        || encoding == ENCODING_UCS_4_4321
        || encoding == ENCODING_UCS_4_2143
        || encoding == ENCODING_UCS_4_3412)
      {
        // Strictly:  "UCS-4" == "UTF-32BE"; also, "UTF-32LE" exists
        if (!encodingName.equals("ISO-10646-UCS-4"))
          {
            error("unsupported 32-bit encoding", encodingName,
                  "ISO-10646-UCS-4");
          }
        return;
      }

    // assert encoding == ENCODING_EXTERNAL
    // if (encoding != ENCODING_EXTERNAL)
    //     throw new RuntimeException ("encoding = " + encoding);

    if (encodingName.equals("UTF-16BE"))
      {
        encoding = ENCODING_UCS_2_12;
        return;
      }
    if (encodingName.equals("UTF-16LE"))
      {
        encoding = ENCODING_UCS_2_21;
        return;
      }

    // We couldn't use the builtin decoders at all.  But we can try to
    // create a reader, since we haven't messed up buffering.  Tweak
    // the encoding name if necessary.

    if (encodingName.equals("UTF-16")
        || encodingName.equals("ISO-10646-UCS-2"))
      {
        encodingName = "Unicode";
      }
    // Ignoring all the EBCDIC aliases here

    reader = new InputStreamReader(is, encodingName);
    sourceType = INPUT_READER;
  }

  /**
   * Parse miscellaneous markup outside the document element and DOCTYPE
   * declaration.
   * <pre>
   * [27] Misc ::= Comment | PI | S
   * </pre>
   */
  private void parseMisc()
    throws Exception
  {
    while (true)
      {
        skipWhitespace();
        if (tryRead(startDelimPI))
          {
            parsePI();
          }
        else if (tryRead(startDelimComment))
          {
            parseComment();
          }
        else
          {
            return;
          }
      }
  }

  /**
   * Parse a document type declaration.
   * <pre>
   * [28] doctypedecl ::= '&lt;!DOCTYPE' S Name (S ExternalID)? S?
   *    ('[' (markupdecl | PEReference | S)* ']' S?)? '&gt;'
   * </pre>
   * <p> (The <code>&lt;!DOCTYPE</code> has already been read.)
   */
  private void parseDoctypedecl()
    throws Exception
  {
    String rootName;
    ExternalIdentifiers ids;

    // Read the document type name.
    requireWhitespace();
    rootName = readNmtoken(true);

    // Read the External subset's IDs
    skipWhitespace();
    ids = readExternalIds(false, true);

    // report (a) declaration of name, (b) lexical info (ids)
    handler.doctypeDecl(rootName, ids.publicId, ids.systemId);

    // Internal subset is parsed first, if present
    skipWhitespace();
    if (tryRead('['))
      {

        // loop until the subset ends
        while (true)
          {
            doReport = expandPE = true;
            skipWhitespace();
            doReport = expandPE = false;
            if (tryRead(']'))
              {
                break;     // end of subset
              }
            else
              {
                // WFC, PEs in internal subset (only between decls)
                peIsError = expandPE = true;
                parseMarkupdecl();
                peIsError = expandPE = false;
              }
          }
      }
    skipWhitespace();
    require('>');

    // Read the external subset, if any
    InputSource subset;

    if (ids.systemId == null)
      {
        subset = handler.getExternalSubset(rootName,
                                           handler.getSystemId());
      }
    else
      {
        subset = null;
      }
    if (ids.systemId != null || subset != null)
      {
        pushString(null, ">");

        // NOTE:  [dtd] is so we say what SAX2 expects,
        // though it's misleading (subset, not entire dtd)
        if (ids.systemId != null)
          {
            pushURL(true, "[dtd]", ids, null, null, null, true);
          }
        else
          {
            handler.warn("modifying document by adding external subset");
            pushURL(true, "[dtd]",
                    new ExternalIdentifiers(subset.getPublicId(),
                                            subset.getSystemId(),
                                            null),
                    subset.getCharacterStream(),
                    subset.getByteStream(),
                    subset.getEncoding(),
                    false);
          }

        // Loop until we end up back at '>'
        while (true)
          {
            doReport = expandPE = true;
            skipWhitespace();
            doReport = expandPE = false;
            if (tryRead('>'))
              {
                break;
              }
            else
              {
                expandPE = true;
                parseMarkupdecl();
                expandPE = false;
              }
          }

        // the ">" string isn't popped yet
        if (inputStack.size() != 1)
          {
            error("external subset has unmatched '>'");
          }
      }

    // done dtd
    handler.endDoctype();
    expandPE = false;
    doReport = true;
  }

  /**
   * Parse a markup declaration in the internal or external DTD subset.
   * <pre>
   * [29] markupdecl ::= elementdecl | Attlistdecl | EntityDecl
   *    | NotationDecl | PI | Comment
   * [30] extSubsetDecl ::= (markupdecl | conditionalSect
   *    | PEReference | S) *
   * </pre>
   * <p> Reading toplevel PE references is handled as a lexical issue
   * by the caller, as is whitespace.
   */
  private void parseMarkupdecl()
    throws Exception
  {
    char[] saved = null;
    boolean savedPE = expandPE;

    // prevent "<%foo;" and ensures saved entity is right
    require('<');
    unread('<');
    expandPE = false;

    if (tryRead("<!ELEMENT"))
      {
        saved = readBuffer;
        expandPE = savedPE;
        parseElementDecl();
      }
    else if (tryRead("<!ATTLIST"))
      {
        saved = readBuffer;
        expandPE = savedPE;
        parseAttlistDecl();
      }
    else if (tryRead("<!ENTITY"))
      {
        saved = readBuffer;
        expandPE = savedPE;
        parseEntityDecl();
      }
    else if (tryRead("<!NOTATION"))
      {
        saved = readBuffer;
        expandPE = savedPE;
        parseNotationDecl();
      }
    else if (tryRead(startDelimPI))
      {
        saved = readBuffer;
        expandPE = savedPE;
        parsePI();
      }
    else if (tryRead(startDelimComment))
      {
        saved = readBuffer;
        expandPE = savedPE;
        parseComment();
      }
    else if (tryRead("<!["))
      {
        saved = readBuffer;
        expandPE = savedPE;
        if (inputStack.size() > 0)
          {
            parseConditionalSect(saved);
          }
        else
          {
            error("conditional sections illegal in internal subset");
          }
      }
    else
      {
        error("expected markup declaration");
      }

    // VC: Proper Decl/PE Nesting
    if (readBuffer != saved)
      {
        handler.verror("Illegal Declaration/PE nesting");
      }
  }

  /**
   * Parse an element, with its tags.
   * <pre>
   * [39] element ::= EmptyElementTag | STag content ETag
   * [40] STag ::= '&lt;' Name (S Attribute)* S? '&gt;'
   * [44] EmptyElementTag ::= '&lt;' Name (S Attribute)* S? '/&gt;'
   * </pre>
   * <p> (The '&lt;' has already been read.)
   * <p>NOTE: this method actually chains onto parseContent (), if necessary,
   * and parseContent () will take care of calling parseETag ().
   */
  private void parseElement(boolean maybeGetSubset)
    throws Exception
  {
    String gi;
    char c;
    int oldElementContent = currentElementContent;
    String oldElement = currentElement;
    ElementDecl element;

    // This is the (global) counter for the
    // array of specified attributes.
    tagAttributePos = 0;

    // Read the element type name.
    gi = readNmtoken(true);

    // If we saw no DTD, and this is the document root element,
    // let the application modify the input stream by providing one.
    if (maybeGetSubset)
      {
        InputSource subset = handler.getExternalSubset(gi,
                                                       handler.getSystemId());
        if (subset != null)
          {
            String publicId = subset.getPublicId();
            String systemId = subset.getSystemId();

            handler.warn("modifying document by adding DTD");
            handler.doctypeDecl(gi, publicId, systemId);
            pushString(null, ">");

            // NOTE:  [dtd] is so we say what SAX2 expects,
            // though it's misleading (subset, not entire dtd)
            pushURL(true, "[dtd]",
                    new ExternalIdentifiers(publicId, systemId, null),
                    subset.getCharacterStream(),
                    subset.getByteStream(),
                    subset.getEncoding(),
                    false);

            // Loop until we end up back at '>'
            while (true)
              {
                doReport = expandPE = true;
                skipWhitespace();
                doReport = expandPE = false;
                if (tryRead('>'))
                  {
                    break;
                  }
                else
                  {
                    expandPE = true;
                    parseMarkupdecl();
                    expandPE = false;
                  }
              }

            // the ">" string isn't popped yet
            if (inputStack.size() != 1)
              {
                error("external subset has unmatched '>'");
              }

            handler.endDoctype();
          }
      }

    // Determine the current content type.
    currentElement = gi;
    element = (ElementDecl) elementInfo.get(gi);
    currentElementContent = getContentType(element, CONTENT_ANY);

    // Read the attributes, if any.
    // After this loop, "c" is the closing delimiter.
    boolean white = tryWhitespace();
    c = readCh();
    while (c != '/' && c != '>')
      {
        unread(c);
        if (!white)
          {
            error("need whitespace between attributes");
          }
        parseAttribute(gi);
        white = tryWhitespace();
        c = readCh();
      }

    // Supply any defaulted attributes.
    Iterator atts = declaredAttributes(element);
    if (atts != null)
      {
        String aname;
loop:
        while (atts.hasNext())
          {
            aname = (String) atts.next();
            // See if it was specified.
            for (int i = 0; i < tagAttributePos; i++)
              {
                if (tagAttributes[i] == aname)
                  {
                    continue loop;
                  }
              }
            // ... or has a default
            String value = getAttributeDefaultValue(gi, aname);

            if (value == null)
              {
                continue;
              }
            handler.attribute(aname, value, false);
          }
      }

    // Figure out if this is a start tag
    // or an empty element, and dispatch an
    // event accordingly.
    switch (c)
      {
      case '>':
        handler.startElement(gi);
        parseContent();
        break;
      case '/':
        require('>');
        handler.startElement(gi);
        handler.endElement(gi);
        break;
      }

    // Restore the previous state.
    currentElement = oldElement;
    currentElementContent = oldElementContent;
  }

  /**
   * Parse an attribute assignment.
   * <pre>
   * [41] Attribute ::= Name Eq AttValue
   * </pre>
   * @param name The name of the attribute's element.
   * @see SAXDriver#attribute
   */
  private void parseAttribute(String name)
    throws Exception
  {
    String aname;
    String type;
    String value;
    int flags = LIT_ATTRIBUTE |  LIT_ENTITY_REF;

    // Read the attribute name.
    aname = readNmtoken(true);
    type = getAttributeType(name, aname);

    // Parse '='
    parseEq();

    // Read the value, normalizing whitespace
    // unless it is CDATA.
    if (handler.stringInterning)
      {
        if (type == "CDATA" || type == null)
          {
            value = readLiteral(flags);
          }
        else
          {
            value = readLiteral(flags | LIT_NORMALIZE);
          }
      }
    else
      {
        if (type == null || type.equals("CDATA"))
          {
            value = readLiteral(flags);
          }
        else
          {
            value = readLiteral(flags | LIT_NORMALIZE);
          }
      }

    // WFC: no duplicate attributes
    for (int i = 0; i < tagAttributePos; i++)
      {
        if (aname.equals(tagAttributes [i]))
          {
            error("duplicate attribute", aname, null);
          }
      }

    // Inform the handler about the
    // attribute.
    handler.attribute(aname, value, true);
    dataBufferPos = 0;

    // Note that the attribute has been
    // specified.
    if (tagAttributePos == tagAttributes.length)
      {
        String newAttrib[] = new String[tagAttributes.length * 2];
        System.arraycopy(tagAttributes, 0, newAttrib, 0, tagAttributePos);
        tagAttributes = newAttrib;
      }
    tagAttributes[tagAttributePos++] = aname;
  }

  /**
   * Parse an equals sign surrounded by optional whitespace.
   * <pre>
   * [25] Eq ::= S? '=' S?
   * </pre>
   */
  private void parseEq()
    throws SAXException, IOException
  {
    skipWhitespace();
    require('=');
    skipWhitespace();
  }

  /**
   * Parse an end tag.
   * <pre>
   * [42] ETag ::= '</' Name S? '>'
   * </pre>
   * <p>NOTE: parseContent () chains to here, we already read the
   * "&lt;/".
   */
  private void parseETag()
    throws Exception
  {
    require(currentElement);
    skipWhitespace();
    require('>');
    handler.endElement(currentElement);
    // not re-reporting any SAXException re bogus end tags,
    // even though that diagnostic might be clearer ...
  }

  /**
   * Parse the content of an element.
   * <pre>
   * [43] content ::= (element | CharData | Reference
   *    | CDSect | PI | Comment)*
   * [67] Reference ::= EntityRef | CharRef
   * </pre>
   * <p> NOTE: consumes ETtag.
   */
  private void parseContent()
    throws Exception
  {
    char c;

    while (true)
      {
        // consume characters (or ignorable whitspace) until delimiter
        parseCharData();

        // Handle delimiters
        c = readCh();
        switch (c)
          {
          case '&':       // Found "&"
            c = readCh();
            if (c == '#')
              {
                parseCharRef();
              }
            else
              {
                unread(c);
                parseEntityRef(true);
              }
            isDirtyCurrentElement = true;
            break;

          case '<':       // Found "<"
            dataBufferFlush();
            c = readCh();
            switch (c)
              {
              case '!':       // Found "<!"
                c = readCh();
                switch (c)
                  {
                  case '-':     // Found "<!-"
                    require('-');
                    isDirtyCurrentElement = false;
                    parseComment();
                    break;
                  case '[':     // Found "<!["
                    isDirtyCurrentElement = false;
                    require("CDATA[");
                    handler.startCDATA();
                    inCDATA = true;
                    parseCDSect();
                    inCDATA = false;
                    handler.endCDATA();
                    break;
                  default:
                    error("expected comment or CDATA section", c, null);
                    break;
                  }
                break;

              case '?':     // Found "<?"
                isDirtyCurrentElement = false;
                parsePI();
                break;

              case '/':     // Found "</"
                isDirtyCurrentElement = false;
                parseETag();
                return;

              default:     // Found "<" followed by something else
                isDirtyCurrentElement = false;
                unread(c);
                parseElement(false);
                break;
              }
          }
      }
  }

  /**
   * Parse an element type declaration.
   * <pre>
   * [45] elementdecl ::= '&lt;!ELEMENT' S Name S contentspec S? '&gt;'
   * </pre>
   * <p> NOTE: the '&lt;!ELEMENT' has already been read.
   */
  private void parseElementDecl()
    throws Exception
  {
    String name;

    requireWhitespace();
    // Read the element type name.
    name = readNmtoken(true);

    requireWhitespace();
    // Read the content model.
    parseContentspec(name);

    skipWhitespace();
    require('>');
  }

  /**
   * Content specification.
   * <pre>
   * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | elements
   * </pre>
   */
  private void parseContentspec(String name)
    throws Exception
  {
    // FIXME: move elementDecl() into setElement(), pass EMTPY/ANY ...
    if (tryRead("EMPTY"))
      {
        setElement(name, CONTENT_EMPTY, null, null);
        if (!skippedPE)
          {
            handler.getDeclHandler().elementDecl(name, "EMPTY");
          }
        return;
      }
    else if (tryRead("ANY"))
      {
        setElement(name, CONTENT_ANY, null, null);
        if (!skippedPE)
          {
            handler.getDeclHandler().elementDecl(name, "ANY");
          }
        return;
      }
    else
      {
        String model;
        char[] saved;

        require('(');
        saved = readBuffer;
        dataBufferAppend('(');
        skipWhitespace();
        if (tryRead("#PCDATA"))
          {
            dataBufferAppend("#PCDATA");
            parseMixed(saved);
            model = dataBufferToString();
            setElement(name, CONTENT_MIXED, model, null);
          }
        else
          {
            parseElements(saved);
            model = dataBufferToString();
            setElement(name, CONTENT_ELEMENTS, model, null);
          }
        if (!skippedPE)
          {
            handler.getDeclHandler().elementDecl(name, model);
          }
      }
  }

  /**
   * Parse an element-content model.
   * <pre>
   * [47] elements ::= (choice | seq) ('?' | '*' | '+')?
   * [49] choice ::= '(' S? cp (S? '|' S? cp)+ S? ')'
   * [50] seq ::= '(' S? cp (S? ',' S? cp)* S? ')'
   * </pre>
   *
   * <p> NOTE: the opening '(' and S have already been read.
   *
   * @param saved Buffer for entity that should have the terminal ')'
   */
  private void parseElements(char[] saved)
    throws Exception
  {
    char c;
    char sep;

    // Parse the first content particle
    skipWhitespace();
    parseCp();

    // Check for end or for a separator.
    skipWhitespace();
    c = readCh();
    switch (c)
      {
      case ')':
        // VC: Proper Group/PE Nesting
        if (readBuffer != saved)
          {
            handler.verror("Illegal Group/PE nesting");
          }

        dataBufferAppend(')');
        c = readCh();
        switch (c)
          {
          case '*':
          case '+':
          case '?':
            dataBufferAppend(c);
            break;
          default:
            unread(c);
          }
        return;
      case ',':       // Register the separator.
      case '|':
        sep = c;
        dataBufferAppend(c);
        break;
      default:
        error("bad separator in content model", c, null);
        return;
      }

    // Parse the rest of the content model.
    while (true)
      {
        skipWhitespace();
        parseCp();
        skipWhitespace();
        c = readCh();
        if (c == ')')
          {
            // VC: Proper Group/PE Nesting
            if (readBuffer != saved)
              {
                handler.verror("Illegal Group/PE nesting");
              }

            dataBufferAppend(')');
            break;
          }
        else if (c != sep)
          {
            error("bad separator in content model", c, null);
            return;
          }
        else
          {
            dataBufferAppend(c);
          }
      }

    // Check for the occurrence indicator.
    c = readCh();
    switch (c)
      {
      case '?':
      case '*':
      case '+':
        dataBufferAppend(c);
        return;
      default:
        unread(c);
        return;
      }
  }

  /**
   * Parse a content particle.
   * <pre>
   * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
   * </pre>
   */
  private void parseCp()
    throws Exception
  {
    if (tryRead('('))
      {
        dataBufferAppend('(');
        parseElements(readBuffer);
      }
    else
      {
        dataBufferAppend(readNmtoken(true));
        char c = readCh();
        switch (c)
          {
          case '?':
          case '*':
          case '+':
            dataBufferAppend(c);
            break;
          default:
            unread(c);
            break;
          }
      }
  }

  /**
   * Parse mixed content.
   * <pre>
   * [51] Mixed ::= '(' S? ( '#PCDATA' (S? '|' S? Name)*) S? ')*'
   *        | '(' S? ('#PCDATA') S? ')'
   * </pre>
   *
   * @param saved Buffer for entity that should have the terminal ')'
   */
  private void parseMixed(char[] saved)
    throws Exception
  {
    // Check for PCDATA alone.
    skipWhitespace();
    if (tryRead(')'))
      {
        // VC: Proper Group/PE Nesting
        if (readBuffer != saved)
          {
            handler.verror("Illegal Group/PE nesting");
          }

        dataBufferAppend(")*");
        tryRead('*');
        return;
      }

    // Parse mixed content.
    skipWhitespace();
    while (!tryRead(")"))
      {
        require('|');
        dataBufferAppend('|');
        skipWhitespace();
        dataBufferAppend(readNmtoken(true));
        skipWhitespace();
      }

    // VC: Proper Group/PE Nesting
    if (readBuffer != saved)
      {
        handler.verror("Illegal Group/PE nesting");
      }

    require('*');
    dataBufferAppend(")*");
  }

  /**
   * Parse an attribute list declaration.
   * <pre>
   * [52] AttlistDecl ::= '&lt;!ATTLIST' S Name AttDef* S? '&gt;'
   * </pre>
   * <p>NOTE: the '&lt;!ATTLIST' has already been read.
   */
  private void parseAttlistDecl()
    throws Exception
  {
    String elementName;

    requireWhitespace();
    elementName = readNmtoken(true);
    boolean white = tryWhitespace();
    while (!tryRead('>'))
      {
        if (!white)
          {
            error("whitespace required before attribute definition");
          }
        parseAttDef(elementName);
        white = tryWhitespace();
      }
  }

  /**
   * Parse a single attribute definition.
   * <pre>
   * [53] AttDef ::= S Name S AttType S DefaultDecl
   * </pre>
   */
  private void parseAttDef(String elementName)
    throws Exception
  {
    String name;
    String type;
    String enumer = null;

    // Read the attribute name.
    name = readNmtoken(true);

    // Read the attribute type.
    requireWhitespace();
    type = readAttType();

    // Get the string of enumerated values if necessary.
    if (handler.stringInterning)
      {
        if ("ENUMERATION" == type || "NOTATION" == type)
          {
            enumer = dataBufferToString();
          }
      }
    else
      {
        if ("ENUMERATION".equals(type) || "NOTATION".equals(type))
          {
            enumer = dataBufferToString();
          }
      }

    // Read the default value.
    requireWhitespace();
    parseDefault(elementName, name, type, enumer);
  }

  /**
   * Parse the attribute type.
   * <pre>
   * [54] AttType ::= StringType | TokenizedType | EnumeratedType
   * [55] StringType ::= 'CDATA'
   * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY'
   *    | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
   * [57] EnumeratedType ::= NotationType | Enumeration
   * </pre>
   */
  private String readAttType()
    throws Exception
  {
    if (tryRead('('))
      {
        parseEnumeration(false);
        return "ENUMERATION";
      }
    else
      {
        String typeString = readNmtoken(true);
        if (handler.stringInterning)
          {
            if ("NOTATION" == typeString)
              {
                parseNotationType();
                return typeString;
              }
            else if ("CDATA" == typeString
                     || "ID" == typeString
                     || "IDREF" == typeString
                     || "IDREFS" == typeString
                     || "ENTITY" == typeString
                     || "ENTITIES" == typeString
                     || "NMTOKEN" == typeString
                     || "NMTOKENS" == typeString)
              {
                return typeString;
              }
          }
        else
          {
            if ("NOTATION".equals(typeString))
              {
                parseNotationType();
                return typeString;
              }
            else if ("CDATA".equals(typeString)
                     || "ID".equals(typeString)
                     || "IDREF".equals(typeString)
                     || "IDREFS".equals(typeString)
                     || "ENTITY".equals(typeString)
                     || "ENTITIES".equals(typeString)
                     || "NMTOKEN".equals(typeString)
                     || "NMTOKENS".equals(typeString))
              {
                return typeString;
              }
          }
        error("illegal attribute type", typeString, null);
        return null;
      }
  }

  /**
   * Parse an enumeration.
   * <pre>
   * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
   * </pre>
   * <p>NOTE: the '(' has already been read.
   */
  private void parseEnumeration(boolean isNames)
    throws Exception
  {
    dataBufferAppend('(');

    // Read the first token.
    skipWhitespace();
    dataBufferAppend(readNmtoken(isNames));
    // Read the remaining tokens.
    skipWhitespace();
    while (!tryRead(')'))
      {
        require('|');
        dataBufferAppend('|');
        skipWhitespace();
        dataBufferAppend(readNmtoken (isNames));
        skipWhitespace();
      }
    dataBufferAppend(')');
  }

  /**
   * Parse a notation type for an attribute.
   * <pre>
   * [58] NotationType ::= 'NOTATION' S '(' S? NameNtoks
   *    (S? '|' S? name)* S? ')'
   * </pre>
   * <p>NOTE: the 'NOTATION' has already been read
   */
  private void parseNotationType()
    throws Exception
  {
    requireWhitespace();
    require('(');

    parseEnumeration(true);
  }

  /**
   * Parse the default value for an attribute.
   * <pre>
   * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED'
   *    | (('#FIXED' S)? AttValue)
   * </pre>
   */
  private void parseDefault(String elementName, String name,
                            String type, String enumer)
    throws Exception
  {
    int valueType = ATTRIBUTE_DEFAULT_SPECIFIED;
    String value = null;
    int flags = LIT_ATTRIBUTE;
    boolean saved = expandPE;
    String defaultType = null;

    // LIT_ATTRIBUTE forces '<' checks now (ASAP) and turns whitespace
    // chars to spaces (doesn't matter when that's done if it doesn't
    // interfere with char refs expanding to whitespace).

    if (!skippedPE)
      {
        flags |= LIT_ENTITY_REF;
        if (handler.stringInterning)
          {
            if ("CDATA" != type)
              {
                flags |= LIT_NORMALIZE;
              }
          }
        else
          {
            if (!"CDATA".equals(type))
              {
                flags |= LIT_NORMALIZE;
              }
          }
      }

    expandPE = false;
    if (tryRead('#'))
      {
        if (tryRead("FIXED"))
          {
            defaultType = "#FIXED";
            valueType = ATTRIBUTE_DEFAULT_FIXED;
            requireWhitespace();
            value = readLiteral(flags);
          }
        else if (tryRead("REQUIRED"))
          {
            defaultType = "#REQUIRED";
            valueType = ATTRIBUTE_DEFAULT_REQUIRED;
          }
        else if (tryRead("IMPLIED"))
          {
            defaultType = "#IMPLIED";
            valueType = ATTRIBUTE_DEFAULT_IMPLIED;
          }
        else
          {
            error("illegal keyword for attribute default value");
          }
      }
    else
      {
        value = readLiteral(flags);
      }
    expandPE = saved;
    setAttribute(elementName, name, type, enumer, value, valueType);
    if (handler.stringInterning)
      {
        if ("ENUMERATION" == type)
          {
            type = enumer;
          }
        else if ("NOTATION" == type)
          {
            type = "NOTATION " + enumer;
          }
      }
    else
      {
        if ("ENUMERATION".equals(type))
          {
            type = enumer;
          }
        else if ("NOTATION".equals(type))
          {
            type = "NOTATION " + enumer;
          }
      }
    if (!skippedPE)
      {
        handler.getDeclHandler().attributeDecl(elementName, name, type,
                                               defaultType, value);
      }
  }

  /**
   * Parse a conditional section.
   * <pre>
   * [61] conditionalSect ::= includeSect || ignoreSect
   * [62] includeSect ::= '&lt;![' S? 'INCLUDE' S? '['
   *    extSubsetDecl ']]&gt;'
   * [63] ignoreSect ::= '&lt;![' S? 'IGNORE' S? '['
   *    ignoreSectContents* ']]&gt;'
   * [64] ignoreSectContents ::= Ignore
   *    ('&lt;![' ignoreSectContents* ']]&gt;' Ignore )*
   * [65] Ignore ::= Char* - (Char* ( '&lt;![' | ']]&gt;') Char* )
   * </pre>
   * <p> NOTE: the '&gt;![' has already been read.
   */
  private void parseConditionalSect(char[] saved)
    throws Exception
  {
    skipWhitespace();
    if (tryRead("INCLUDE"))
      {
        skipWhitespace();
        require('[');
        // VC: Proper Conditional Section/PE Nesting
        if (readBuffer != saved)
          {
            handler.verror("Illegal Conditional Section/PE nesting");
          }
        skipWhitespace();
        while (!tryRead("]]>"))
          {
            parseMarkupdecl();
            skipWhitespace();
          }
      }
    else if (tryRead("IGNORE"))
      {
        skipWhitespace();
        require('[');
        // VC: Proper Conditional Section/PE Nesting
        if (readBuffer != saved)
          {
            handler.verror("Illegal Conditional Section/PE nesting");
          }
        int nesting = 1;
        char c;
        expandPE = false;
        for (int nest = 1; nest > 0; )
          {
            c = readCh();
            switch (c)
              {
              case '<':
                if (tryRead("!["))
                  {
                    nest++;
                  }
                break;
              case ']':
                if (tryRead("]>"))
                  {
                    nest--;
                  }
              }
          }
        expandPE = true;
      }
    else
      {
        error("conditional section must begin with INCLUDE or IGNORE");
      }
  }

  private void parseCharRef()
    throws SAXException, IOException
  {
    parseCharRef(true /* do flushDataBuffer by default */);
  }

  /**
   * Try to read a character reference without consuming data from buffer.
   * <pre>
   * [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
   * </pre>
   * <p>NOTE: the '&#' has already been read.
   */
  private void tryReadCharRef()
    throws SAXException, IOException
  {
    int value = 0;
    char c;

    if (tryRead('x'))
      {
loop1:
        while (true)
          {
            c = readCh();
            if (c == ';')
              {
                break loop1;
              }
            else
              {
                int n = Character.digit(c, 16);
                if (n == -1)
                  {
                    error("illegal character in character reference", c, null);
                    break loop1;
                  }
                value *= 16;
                value += n;
              }
          }
      }
    else
      {
loop2:
        while (true)
          {
            c = readCh();
            if (c == ';')
              {
                break loop2;
              }
            else
              {
                int n = Character.digit(c, 10);
                if (n == -1)
                  {
                    error("illegal character in character reference", c, null);
                    break loop2;
                  }
                value *= 10;
                value += n;
              }
          }
      }

    // check for character refs being legal XML
    if ((value < 0x0020
         && ! (value == '\n' || value == '\t' || value == '\r'))
        || (value >= 0xD800 && value <= 0xDFFF)
        || value == 0xFFFE || value == 0xFFFF
        || value > 0x0010ffff)
      {
        error("illegal XML character reference U+"
              + Integer.toHexString(value));
      }

    // Check for surrogates: 00000000 0000xxxx yyyyyyyy zzzzzzzz
    //  (1101|10xx|xxyy|yyyy + 1101|11yy|zzzz|zzzz:
    if (value > 0x0010ffff)
      {
        // too big for surrogate
        error("character reference " + value + " is too large for UTF-16",
              Integer.toString(value), null);
      }

  }

  /**
   * Read and interpret a character reference.
   * <pre>
   * [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
   * </pre>
   * <p>NOTE: the '&#' has already been read.
   */
  private void parseCharRef(boolean doFlush)
    throws SAXException, IOException
  {
    int value = 0;
    char c;

    if (tryRead('x'))
      {
loop1:
        while (true)
          {
            c = readCh();
            if (c == ';')
              {
                break loop1;
              }
            else
              {
                int n = Character.digit(c, 16);
                if (n == -1)
                  {
                    error("illegal character in character reference", c, null);
                    break loop1;
                  }
                value *= 16;
                value += n;
              }
          }
      }
    else
      {
loop2:
        while (true)
          {
            c = readCh();
            if (c == ';')
              {
                break loop2;
              }
            else
              {
                int n = Character.digit(c, 10);
                if (n == -1)
                  {
                    error("illegal character in character reference", c, null);
                    break loop2;
                  }
                value *= 10;
                value += c - '0';
              }
          }
      }

    // check for character refs being legal XML
    if ((value < 0x0020
         && ! (value == '\n' || value == '\t' || value == '\r'))
        || (value >= 0xD800 && value <= 0xDFFF)
        || value == 0xFFFE || value == 0xFFFF
        || value > 0x0010ffff)
      {
        error("illegal XML character reference U+"
              + Integer.toHexString(value));
      }

    // Check for surrogates: 00000000 0000xxxx yyyyyyyy zzzzzzzz
    //  (1101|10xx|xxyy|yyyy + 1101|11yy|zzzz|zzzz:
    if (value <= 0x0000ffff)
      {
        // no surrogates needed
        dataBufferAppend((char) value);
      }
    else if (value <= 0x0010ffff)
      {
        value -= 0x10000;
        // > 16 bits, surrogate needed
        dataBufferAppend((char) (0xd800 | (value >> 10)));
        dataBufferAppend((char) (0xdc00 | (value & 0x0003ff)));
      }
    else
      {
        // too big for surrogate
        error("character reference " + value + " is too large for UTF-16",
              Integer.toString(value), null);
      }
    if (doFlush)
      {
        dataBufferFlush();
      }
  }

  /**
   * Parse and expand an entity reference.
   * <pre>
   * [68] EntityRef ::= '&' Name ';'
   * </pre>
   * <p>NOTE: the '&amp;' has already been read.
   * @param externalAllowed External entities are allowed here.
   */
  private void parseEntityRef(boolean externalAllowed)
    throws SAXException, IOException
  {
    String name;

    name = readNmtoken(true);
    require(';');
    switch (getEntityType(name))
      {
      case ENTITY_UNDECLARED:
        // NOTE:  XML REC describes amazingly convoluted handling for
        // this case.  Nothing as meaningful as being a WFness error
        // unless the processor might _legitimately_ not have seen a
        // declaration ... which is what this implements.
        String message;

        message = "reference to undeclared general entity " + name;
        if (skippedPE && !docIsStandalone)
          {
            handler.verror(message);
            // we don't know this entity, and it might be external...
            if (externalAllowed)
              {
                handler.skippedEntity(name);
              }
          }
        else
          {
            error(message);
          }
        break;
      case ENTITY_INTERNAL:
          pushString(name, getEntityValue(name));

          //workaround for possible input pop before marking
          //the buffer reading position
          char t = readCh();
          unread(t);
          int bufferPosMark = readBufferPos;

          int end = readBufferPos + getEntityValue(name).length();
          for (int k = readBufferPos; k < end; k++)
            {
              t = readCh();
              if (t == '&')
                {
                  t = readCh();
                  if (t  == '#')
                    {
                      //try to match a character ref
                      tryReadCharRef();

                      //everything has been read
                      if (readBufferPos >= end)
                        {
                          break;
                        }
                      k = readBufferPos;
                      continue;
                    }
                  else if (Character.isLetter(t))
                    {
                      //looks like an entity ref
                      unread(t);
                      readNmtoken(true);
                      require(';');

                      //everything has been read
                      if (readBufferPos >= end)
                        {
                          break;
                        }
                      k = readBufferPos;
                      continue;
                    }
                  error(" malformed entity reference");
                }

            }
          readBufferPos = bufferPosMark;
          break;
      case ENTITY_TEXT:
          if (externalAllowed)
            {
              pushURL(false, name, getEntityIds(name),
                      null, null, null, true);
            }
          else
            {
              error("reference to external entity in attribute value.",
                    name, null);
            }
          break;
      case ENTITY_NDATA:
          if (externalAllowed)
            {
              error("unparsed entity reference in content", name, null);
            }
          else
            {
              error("reference to external entity in attribute value.",
                    name, null);
            }
          break;
      default:
          throw new RuntimeException();
      }
  }

  /**
   * Parse and expand a parameter entity reference.
   * <pre>
   * [69] PEReference ::= '%' Name ';'
   * </pre>
   * <p>NOTE: the '%' has already been read.
   */
  private void parsePEReference()
    throws SAXException, IOException
  {
    String name;

    name = "%" + readNmtoken(true);
    require(';');
    switch (getEntityType(name))
      {
      case ENTITY_UNDECLARED:
        // VC: Entity Declared
        handler.verror("reference to undeclared parameter entity " + name);

        // we should disable handling of all subsequent declarations
        // unless this is a standalone document (info discarded)
        break;
      case ENTITY_INTERNAL:
        if (inLiteral)
          {
            pushString(name, getEntityValue(name));
          }
        else
          {
            pushString(name, ' ' + getEntityValue(name) + ' ');
          }
        break;
      case ENTITY_TEXT:
        if (!inLiteral)
          {
            pushString(null, " ");
          }
        pushURL(true, name, getEntityIds(name), null, null, null, true);
        if (!inLiteral)
          {
            pushString(null, " ");
          }
        break;
      }
  }

  /**
   * Parse an entity declaration.
   * <pre>
   * [70] EntityDecl ::= GEDecl | PEDecl
   * [71] GEDecl ::= '&lt;!ENTITY' S Name S EntityDef S? '&gt;'
   * [72] PEDecl ::= '&lt;!ENTITY' S '%' S Name S PEDef S? '&gt;'
   * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
   * [74] PEDef ::= EntityValue | ExternalID
   * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
   *       | 'PUBLIC' S PubidLiteral S SystemLiteral
   * [76] NDataDecl ::= S 'NDATA' S Name
   * </pre>
   * <p>NOTE: the '&lt;!ENTITY' has already been read.
   */
  private void parseEntityDecl()
    throws Exception
  {
    boolean peFlag = false;
    int flags = 0;

    // Check for a parameter entity.
    expandPE = false;
    requireWhitespace();
    if (tryRead('%'))
      {
        peFlag = true;
        requireWhitespace();
      }
    expandPE = true;

    // Read the entity name, and prepend
    // '%' if necessary.
    String name = readNmtoken(true);
    //NE08
    if (name.indexOf(':') >= 0)
      {
        error("Illegal character(':') in entity name ", name, null);
      }
    if (peFlag)
      {
        name = "%" + name;
      }

    // Read the entity value.
    requireWhitespace();
    char c = readCh();
    unread (c);
    if (c == '"' || c == '\'')
      {
        // Internal entity ... replacement text has expanded refs
        // to characters and PEs, but not to general entities
        String value = readLiteral(flags);
        setInternalEntity(name, value);
      }
    else
      {
        // Read the external IDs
        ExternalIdentifiers ids = readExternalIds(false, false);

        // Check for NDATA declaration.
        boolean white = tryWhitespace();
        if (!peFlag && tryRead("NDATA"))
          {
            if (!white)
              {
                error("whitespace required before NDATA");
              }
            requireWhitespace();
            String notationName = readNmtoken(true);
            if (!skippedPE)
              {
                setExternalEntity(name, ENTITY_NDATA, ids, notationName);
                handler.unparsedEntityDecl(name, ids.publicId, ids.systemId,
                                           ids.baseUri, notationName);
              }
          }
        else if (!skippedPE)
          {
            setExternalEntity(name, ENTITY_TEXT, ids, null);
            handler.getDeclHandler()
              .externalEntityDecl(name, ids.publicId,
                                   handler.resolveURIs()
                                   // FIXME: ASSUMES not skipped
                                   // "false" forces error on bad URI
                                   ? handler.absolutize(ids.baseUri,
                                                        ids.systemId,
                                                        false)
                                   : ids.systemId);
          }
      }

    // Finish the declaration.
    skipWhitespace();
    require('>');
  }

  /**
   * Parse a notation declaration.
   * <pre>
   * [82] NotationDecl ::= '&lt;!NOTATION' S Name S
   *    (ExternalID | PublicID) S? '&gt;'
   * [83] PublicID ::= 'PUBLIC' S PubidLiteral
   * </pre>
   * <P>NOTE: the '&lt;!NOTATION' has already been read.
   */
  private void parseNotationDecl()
    throws Exception
  {
    String nname;
    ExternalIdentifiers ids;

    requireWhitespace();
    nname = readNmtoken(true);
    //NE08
    if (nname.indexOf(':') >= 0)
      {
        error("Illegal character(':') in notation name ", nname, null);
      }
    requireWhitespace();

    // Read the external identifiers.
    ids = readExternalIds(true, false);

    // Register the notation.
    setNotation(nname, ids);

    skipWhitespace();
    require('>');
  }

  /**
   * Parse character data.
   * <pre>
   * [14] CharData ::= [^&lt;&amp;]* - ([^&lt;&amp;]* ']]&gt;' [^&lt;&amp;]*)
   * </pre>
   */
  private void parseCharData()
    throws Exception
  {
    char c;
    int state = 0;
    boolean pureWhite = false;

    // assert (dataBufferPos == 0);

    // are we expecting pure whitespace?  it might be dirty...
    if ((currentElementContent == CONTENT_ELEMENTS) && !isDirtyCurrentElement)
      {
        pureWhite = true;
      }

    // always report right out of readBuffer
    // to minimize (pointless) buffer copies
    while (true)
      {
        int lineAugment = 0;
        int columnAugment = 0;
        int i;

loop:
        for (i = readBufferPos; i < readBufferLength; i++)
          {
            switch (c = readBuffer[i])
              {
              case '\n':
                lineAugment++;
                columnAugment = 0;
                // pureWhite unmodified
                break;
              case '\r':  // should not happen!!
              case '\t':
              case ' ':
                // pureWhite unmodified
                columnAugment++;
                break;
              case '&':
              case '<':
                columnAugment++;
                // pureWhite unmodified
                // CLEAN end of text sequence
                state = 1;
                break loop;
              case ']':
                // that's not a whitespace char, and
                // can not terminate pure whitespace either
                pureWhite = false;
                if ((i + 2) < readBufferLength)
                  {
                    if (readBuffer [i + 1] == ']'
                        && readBuffer [i + 2] == '>')
                      {
                        // ERROR end of text sequence
                        state = 2;
                        break loop;
                      }
                  }
                else
                  {
                    // FIXME missing two end-of-buffer cases
                  }
                columnAugment++;
                break;
              default:
                if ((c < 0x0020 || c > 0xFFFD)
                    || ((c >= 0x007f) && (c <= 0x009f) && (c != 0x0085)
                        && xmlVersion == XML_11))
                  {
                    error("illegal XML character U+"
                          + Integer.toHexString(c));
                  }
                // that's not a whitespace char
                pureWhite = false;
                columnAugment++;
              }
          }

        // report text thus far
        if (lineAugment > 0)
          {
            line += lineAugment;
            column = columnAugment;
          }
        else
          {
            column += columnAugment;
          }

        // report characters/whitspace
        int length = i - readBufferPos;

        if (length != 0)
          {
            if (pureWhite)
              {
                handler.ignorableWhitespace(readBuffer,
                                            readBufferPos, length);
              }
            else
              {
                handler.charData(readBuffer, readBufferPos, length);
              }
            readBufferPos = i;
          }

        if (state != 0)
          {
            break;
          }

        // fill next buffer from this entity, or
        // pop stack and continue with previous entity
        unread(readCh());
      }
    if (!pureWhite)
      {
        isDirtyCurrentElement = true;
      }
    // finish, maybe with error
    if (state != 1)  // finish, no error
      {
        error("character data may not contain ']]>'");
      }
  }

  //////////////////////////////////////////////////////////////////////
  // High-level reading and scanning methods.
  //////////////////////////////////////////////////////////////////////

  /**
   * Require whitespace characters.
   */
  private void requireWhitespace()
    throws SAXException, IOException
  {
    char c = readCh();
    if (isWhitespace(c))
      {
        skipWhitespace();
      }
    else
      {
        error("whitespace required", c, null);
      }
  }

  /**
   * Skip whitespace characters.
   * <pre>
   * [3] S ::= (#x20 | #x9 | #xd | #xa)+
   * </pre>
   */
  private void skipWhitespace()
    throws SAXException, IOException
  {
    // Start with a little cheat.  Most of
    // the time, the white space will fall
    // within the current read buffer; if
    // not, then fall through.
    if (USE_CHEATS)
      {
        int lineAugment = 0;
        int columnAugment = 0;

loop:
        for (int i = readBufferPos; i < readBufferLength; i++)
          {
            switch (readBuffer[i])
              {
              case ' ':
              case '\t':
              case '\r':
                columnAugment++;
                break;
              case '\n':
                lineAugment++;
                columnAugment = 0;
                break;
              case '%':
                if (expandPE)
                  {
                    break loop;
                  }
                // else fall through...
              default:
                readBufferPos = i;
                if (lineAugment > 0)
                  {
                    line += lineAugment;
                    column = columnAugment;
                  }
                else
                  {
                    column += columnAugment;
                  }
                return;
              }
          }
      }

    // OK, do it the slow way.
    char c = readCh ();
    while (isWhitespace(c))
      {
        c = readCh();
      }
    unread(c);
  }

  /**
   * Read a name or (when parsing an enumeration) name token.
   * <pre>
   * [5] Name ::= (Letter | '_' | ':') (NameChar)*
   * [7] Nmtoken ::= (NameChar)+
   * </pre>
   */
  private String readNmtoken(boolean isName)
    throws SAXException, IOException
  {
    char c;

    if (USE_CHEATS)
      {
loop:
        for (int i = readBufferPos; i < readBufferLength; i++)
          {
            c = readBuffer[i];
            switch (c)
              {
              case '%':
                if (expandPE)
                  {
                    break loop;
                  }
                // else fall through...

                // What may legitimately come AFTER a name/nmtoken?
              case '<': case '>': case '&':
              case ',': case '|': case '*': case '+': case '?':
              case ')':
              case '=':
              case '\'': case '"':
              case '[':
              case ' ': case '\t': case '\r': case '\n':
              case ';':
              case '/':
                int start = readBufferPos;
                if (i == start)
                  {
                    error("name expected", readBuffer[i], null);
                  }
                readBufferPos = i;
                return intern(readBuffer, start, i - start);

              default:
                // FIXME ... per IBM's OASIS test submission, these:
                //   ?    U+06dd
                //   Combining  U+309B
                //these switches are kind of ugly but at least we won't
                //have to go over the whole lits for each char
                if (isName && i == readBufferPos)
                  {
                    char c2 = (char) (c & 0x00f0);
                    switch (c & 0xff00)
                      {
                        //starting with 01
                      case 0x0100:
                        switch (c2)
                          {
                          case 0x0030:
                            if (c == 0x0132 || c == 0x0133 || c == 0x013f)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x0040:
                            if (c == 0x0140 || c == 0x0149)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x00c0:
                            if (c == 0x01c4 || c == 0x01cc)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x00f0:
                            if (c == 0x01f1 || c == 0x01f3)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x00b0:
                            if (c == 0x01f1 || c == 0x01f3)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          default:
                            if (c == 0x017f)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                          }

                        break;
                        //starting with 11
                      case 0x1100:
                        switch (c2)
                          {
                          case 0x0000:
                            if (c == 0x1104 || c == 0x1108 ||
                                c == 0x110a || c == 0x110d)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x0030:
                            if (c == 0x113b || c == 0x113f)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x0040:
                            if (c == 0x1141 || c == 0x114d
                                || c == 0x114f )
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x0050:
                            if (c == 0x1151 || c == 0x1156)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x0060:
                            if (c == 0x1162 || c == 0x1164
                                || c == 0x1166 || c == 0x116b
                                || c == 0x116f)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          case 0x00b0:
                            if (c == 0x11b6 || c == 0x11b9
                                || c == 0x11bb || c == 0x116f)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                            break;
                          default:
                            if (c == 0x1174 || c == 0x119f
                                || c == 0x11ac || c == 0x11c3
                                || c == 0x11f1)
                              {
                                error("Not a name start character, U+"
                                      + Integer.toHexString(c));
                              }
                          }
                        break;
                      default:
                        if (c == 0x0e46 || c == 0x1011
                            || c == 0x212f || c == 0x0587
                            || c == 0x0230 )
                          {
                            error("Not a name start character, U+"
                                  + Integer.toHexString(c));
                          }
                      }
                  }
                // punt on exact tests from Appendix A; approximate
                // them using the Unicode ID start/part rules
                if (i == readBufferPos && isName)
                  {
                    if (!Character.isUnicodeIdentifierStart(c)
                        && c != ':' && c != '_')
                      {
                        error("Not a name start character, U+"
                              + Integer.toHexString(c));
                      }
                  }
                else if (!Character.isUnicodeIdentifierPart(c)
                         && c != '-' && c != ':' && c != '_' && c != '.'
                         && !isExtender(c))
                  {
                    error("Not a name character, U+"
                          + Integer.toHexString(c));
                  }
              }
          }
      }

    nameBufferPos = 0;

    // Read the first character.
    while (true)
      {
        c = readCh();
        switch (c)
          {
          case '%':
          case '<': case '>': case '&':
          case ',': case '|': case '*': case '+': case '?':
          case ')':
          case '=':
          case '\'': case '"':
          case '[':
          case ' ': case '\t': case '\n': case '\r':
          case ';':
          case '/':
            unread(c);
            if (nameBufferPos == 0)
              {
                error ("name expected");
              }
            // punt on exact tests from Appendix A, but approximate them
            if (isName
                && !Character.isUnicodeIdentifierStart(nameBuffer[0])
                && ":_".indexOf(nameBuffer[0]) == -1)
              {
                error("Not a name start character, U+"
                      + Integer.toHexString(nameBuffer[0]));
              }
            String s = intern(nameBuffer, 0, nameBufferPos);
            nameBufferPos = 0;
            return s;
          default:
            // punt on exact tests from Appendix A, but approximate them

            if ((nameBufferPos != 0 || !isName)
                && !Character.isUnicodeIdentifierPart(c)
                && ":-_.".indexOf(c) == -1
                && !isExtender(c))
              {
                error("Not a name character, U+"
                      + Integer.toHexString(c));
              }
            if (nameBufferPos >= nameBuffer.length)
              {
                nameBuffer =
                  (char[]) extendArray(nameBuffer,
                                       nameBuffer.length, nameBufferPos);
              }
            nameBuffer[nameBufferPos++] = c;
          }
      }
  }

  private static boolean isExtender(char c)
  {
    // [88] Extender ::= ...
    return c == 0x00b7 || c == 0x02d0 || c == 0x02d1 || c == 0x0387
      || c == 0x0640 || c == 0x0e46 || c == 0x0ec6 || c == 0x3005
      || (c >= 0x3031 && c <= 0x3035)
      || (c >= 0x309d && c <= 0x309e)
      || (c >= 0x30fc && c <= 0x30fe);
  }

  /**
   * Read a literal.  With matching single or double quotes as
   * delimiters (and not embedded!) this is used to parse:
   * <pre>
   *  [9] EntityValue ::= ... ([^%&amp;] | PEReference | Reference)* ...
   *  [10] AttValue ::= ... ([^<&] | Reference)* ...
   *  [11] SystemLiteral ::= ... (URLchar - "'")* ...
   *  [12] PubidLiteral ::= ... (PubidChar - "'")* ...
   * </pre>
   * as well as the quoted strings in XML and text declarations
   * (for version, encoding, and standalone) which have their
   * own constraints.
   */
  private String readLiteral(int flags)
    throws SAXException, IOException
  {
    char delim, c;
    int startLine = line;
    boolean saved = expandPE;
    boolean savedReport = doReport;

    // Find the first delimiter.
    delim = readCh();
    if (delim != '"' && delim != '\'')
      {
        error("expected '\"' or \"'\"", delim, null);
        return null;
      }
    inLiteral = true;
    if ((flags & LIT_DISABLE_PE) != 0)
      {
        expandPE = false;
      }
    doReport = false;

    // Each level of input source has its own buffer; remember
    // ours, so we won't read the ending delimiter from any
    // other input source, regardless of entity processing.
    char[] ourBuf = readBuffer;

    // Read the literal.
    try
      {
        c = readCh();
        boolean ampRead = false;
loop:
        while (! (c == delim && readBuffer == ourBuf))
          {
            switch (c)
              {
                // attributes and public ids are normalized
                // in almost the same ways
              case '\n':
              case '\r':
                if ((flags & (LIT_ATTRIBUTE | LIT_PUBID)) != 0)
                  {
                    c = ' ';
                  }
                break;
              case '\t':
                if ((flags & LIT_ATTRIBUTE) != 0)
                  {
                    c = ' ';
                  }
                break;
              case '&':
                c = readCh();
                // Char refs are expanded immediately, except for
                // all the cases where it's deferred.
                if (c == '#')
                  {
                    if ((flags & LIT_DISABLE_CREF) != 0)
                      {
                        dataBufferAppend('&');
                        break;
                      }
                    parseCharRef(false /* Do not do flushDataBuffer */);

                    // exotic WFness risk: this is an entity literal,
                    // dataBuffer [dataBufferPos - 1] == '&', and
                    // following chars are a _partial_ entity/char ref

                    // It looks like an entity ref ...
                  }
                else
                  {
                    unread(c);
                    // Expand it?
                    if ((flags & LIT_ENTITY_REF) > 0)
                      {
                        parseEntityRef(false);
                        if (String.valueOf(readBuffer).equals("&#38;"))
                          {
                            ampRead = true;
                          }
                        //Is it just data?
                      }
                    else if ((flags & LIT_DISABLE_EREF) != 0)
                      {
                        dataBufferAppend('&');

                        // OK, it will be an entity ref -- expanded later.
                      }
                    else
                      {
                        String name = readNmtoken(true);
                        require(';');
                        dataBufferAppend('&');
                        dataBufferAppend(name);
                        dataBufferAppend(';');
                      }
                  }
                c = readCh();
                continue loop;

              case '<':
                // and why?  Perhaps so "&foo;" expands the same
                // inside and outside an attribute?
                if ((flags & LIT_ATTRIBUTE) != 0)
                  {
                    error("attribute values may not contain '<'");
                  }
                break;

                // We don't worry about case '%' and PE refs, readCh does.

              default:
                break;
              }
            dataBufferAppend(c);
            c = readCh();
          }
      }
    catch (EOFException e)
      {
        error("end of input while looking for delimiter (started on line "
              + startLine + ')', null, Character.toString(delim));
      }
    inLiteral = false;
    expandPE = saved;
    doReport = savedReport;

    // Normalise whitespace if necessary.
    if ((flags & LIT_NORMALIZE) > 0)
      {
        dataBufferNormalize();
      }

    // Return the value.
    return dataBufferToString();
  }

  /**
   * Try reading external identifiers.
   * A system identifier is not required for notations.
   * @param inNotation Are we parsing a notation decl?
   * @param isSubset Parsing external subset decl (may be omitted)?
   * @return A three-member String array containing the identifiers,
   *  or nulls. Order: public, system, baseURI.
   */
  private ExternalIdentifiers readExternalIds(boolean inNotation,
                                              boolean isSubset)
    throws Exception
  {
    char c;
    ExternalIdentifiers ids = new ExternalIdentifiers();
    int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;

    if (tryRead("PUBLIC"))
      {
        requireWhitespace();
        ids.publicId = readLiteral(LIT_NORMALIZE | LIT_PUBID | flags);
        if (inNotation)
          {
            skipWhitespace();
            c = readCh();
            unread(c);
            if (c == '"' || c == '\'')
              {
                ids.systemId = readLiteral(flags);
              }
          }
        else
          {
            requireWhitespace();
            ids.systemId = readLiteral(flags);
          }

        for (int i = 0; i < ids.publicId.length(); i++)
          {
            c = ids.publicId.charAt(i);
            if (c >= 'a' && c <= 'z')
              {
                continue;
              }
            if (c >= 'A' && c <= 'Z')
              {
                continue;
              }
            if (" \r\n0123456789-' ()+,./:=?;!*#@$_%".indexOf(c) != -1)
              {
                continue;
              }
            error("illegal PUBLIC id character U+"
                  + Integer.toHexString(c));
          }
      }
    else if (tryRead("SYSTEM"))
      {
        requireWhitespace();
        ids.systemId = readLiteral(flags);
      }
    else if (!isSubset)
      {
        error("missing SYSTEM or PUBLIC keyword");
      }

    if (ids.systemId != null)
      {
        if (ids.systemId.indexOf('#') != -1)
          {
            handler.verror("SYSTEM id has a URI fragment: " + ids.systemId);
          }
        ids.baseUri = handler.getSystemId();
        if (ids.baseUri == null && uriWarnings)
          {
            handler.warn("No base URI; hope URI is absolute: "
                         + ids.systemId);
          }
      }

    return ids;
  }

  /**
   * Test if a character is whitespace.
   * <pre>
   * [3] S ::= (#x20 | #x9 | #xd | #xa)+
   * </pre>
   * @param c The character to test.
   * @return true if the character is whitespace.
   */
  private final boolean isWhitespace(char c)
  {
    if (c > 0x20)
      {
        return false;
      }
    if (c == 0x20 || c == 0x0a || c == 0x09 || c == 0x0d)
      {
        return true;
      }
    return false;  // illegal ...
  }

  //////////////////////////////////////////////////////////////////////
  // Utility routines.
  //////////////////////////////////////////////////////////////////////

  /**
   * Add a character to the data buffer.
   */
  private void dataBufferAppend(char c)
  {
    // Expand buffer if necessary.
    if (dataBufferPos >= dataBuffer.length)
      {
        dataBuffer = (char[]) extendArray(dataBuffer,
                                          dataBuffer.length, dataBufferPos);
      }
    dataBuffer[dataBufferPos++] = c;
  }

  /**
   * Add a string to the data buffer.
   */
  private void dataBufferAppend(String s)
  {
    dataBufferAppend(s.toCharArray(), 0, s.length());
  }

  /**
   * Append (part of) a character array to the data buffer.
   */
  private void dataBufferAppend(char[] ch, int start, int length)
  {
    dataBuffer = (char[]) extendArray(dataBuffer, dataBuffer.length,
                                      dataBufferPos + length);

    System.arraycopy(ch, start, dataBuffer, dataBufferPos, length);
    dataBufferPos += length;
  }

  /**
   * Normalise space characters in the data buffer.
   */
  private void dataBufferNormalize()
  {
    int i = 0;
    int j = 0;
    int end = dataBufferPos;

    // Skip spaces at the start.
    while (j < end && dataBuffer[j] == ' ')
      {
        j++;
      }

    // Skip whitespace at the end.
    while (end > j && dataBuffer[end - 1] == ' ')
      {
        end --;
      }

    // Start copying to the left.
    while (j < end)
      {

        char c = dataBuffer[j++];

        // Normalise all other spaces to
        // a single space.
        if (c == ' ')
          {
            while (j < end && dataBuffer[j++] == ' ')
              {
                continue;
              }
            dataBuffer[i++] = ' ';
            dataBuffer[i++] = dataBuffer[j - 1];
          }
        else
          {
            dataBuffer[i++] = c;
          }
      }

    // The new length is <= the old one.
    dataBufferPos = i;
  }

  /**
   * Convert the data buffer to a string.
   */
  private String dataBufferToString()
  {
    String s = new String(dataBuffer, 0, dataBufferPos);
    dataBufferPos = 0;
    return s;
  }

  /**
   * Flush the contents of the data buffer to the handler, as
   * appropriate, and reset the buffer for new input.
   */
  private void dataBufferFlush()
    throws SAXException
  {
    if (currentElementContent == CONTENT_ELEMENTS
        && dataBufferPos > 0
        && !inCDATA)
      {
        // We can't just trust the buffer to be whitespace, there
        // are (error) cases when it isn't
        for (int i = 0; i < dataBufferPos; i++)
          {
            if (!isWhitespace(dataBuffer[i]))
              {
                handler.charData(dataBuffer, 0, dataBufferPos);
                dataBufferPos = 0;
              }
          }
        if (dataBufferPos > 0)
          {
            handler.ignorableWhitespace(dataBuffer, 0, dataBufferPos);
            dataBufferPos = 0;
          }
      }
    else if (dataBufferPos > 0)
      {
        handler.charData(dataBuffer, 0, dataBufferPos);
        dataBufferPos = 0;
      }
  }

  /**
   * Require a string to appear, or throw an exception.
   * <p><em>Precondition:</em> Entity expansion is not required.
   * <p><em>Precondition:</em> data buffer has no characters that
   * will get sent to the application.
   */
  private void require(String delim)
    throws SAXException, IOException
  {
    int length = delim.length();
    char[] ch;

    if (length < dataBuffer.length)
      {
        ch = dataBuffer;
        delim.getChars(0, length, ch, 0);
      }
    else
      {
        ch = delim.toCharArray();
      }

    if (USE_CHEATS && length <= (readBufferLength - readBufferPos))
      {
        int offset = readBufferPos;

        for (int i = 0; i < length; i++, offset++)
          {
            if (ch[i] != readBuffer[offset])
              {
                error ("required string", null, delim);
              }
          }
        readBufferPos = offset;

      }
    else
      {
        for (int i = 0; i < length; i++)
          {
            require(ch[i]);
          }
      }
  }

  /**
   * Require a character to appear, or throw an exception.
   */
  private void require(char delim)
    throws SAXException, IOException
  {
    char c = readCh();

    if (c != delim)
      {
        error("required character", c, Character.toString(delim));
      }
  }

  /**
   * Create an interned string from a character array.
   * &AElig;lfred uses this method to create an interned version
   * of all names and name tokens, so that it can test equality
   * with <code>==</code> instead of <code>String.equals ()</code>.
   *
   * <p>This is much more efficient than constructing a non-interned
   * string first, and then interning it.
   *
   * @param ch an array of characters for building the string.
   * @param start the starting position in the array.
   * @param length the number of characters to place in the string.
   * @return an interned string.
   * @see #intern (String)
   * @see java.lang.String#intern
   */
  public String intern(char[] ch, int start, int length)
  {
    int index = 0;
    int hash = 0;
    Object[] bucket;

    // Generate a hash code.  This is a widely used string hash,
    // often attributed to Brian Kernighan.
    for (int i = start; i < start + length; i++)
      {
        hash = 31 * hash + ch[i];
      }
    hash = (hash & 0x7fffffff) % SYMBOL_TABLE_LENGTH;

    // Get the bucket -- consists of {array,String} pairs
    if ((bucket = symbolTable[hash]) == null)
      {
        // first string in this bucket
        bucket = new Object[8];

        // Search for a matching tuple, and
        // return the string if we find one.
      }
    else
      {
        while (index < bucket.length)
          {
            char[] chFound = (char[]) bucket[index];

            // Stop when we hit an empty entry.
            if (chFound == null)
              {
                break;
              }

            // If they're the same length, check for a match.
            if (chFound.length == length)
              {
                for (int i = 0; i < chFound.length; i++)
                  {
                    // continue search on failure
                    if (ch[start + i] != chFound[i])
                      {
                        break;
                      }
                    else if (i == length - 1)
                      {
                        // That's it, we have a match!
                        return (String) bucket[index + 1];
                      }
                  }
              }
            index += 2;
          }
        // Not found -- we'll have to add it.

        // Do we have to grow the bucket?
        bucket = (Object[]) extendArray(bucket, bucket.length, index);
      }
    symbolTable[hash] = bucket;

    // OK, add it to the end of the bucket -- "local" interning.
    // Intern "globally" to let applications share interning benefits.
    // That is, "!=" and "==" work on our strings, not just equals().
    String s = new String(ch, start, length).intern();
    bucket[index] = s.toCharArray();
    bucket[index + 1] = s;
    return s;
  }

  /**
   * Ensure the capacity of an array, allocating a new one if
   * necessary.  Usually extends only for name hash collisions.
   */
  private Object extendArray(Object array, int currentSize, int requiredSize)
  {
    if (requiredSize < currentSize)
      {
        return array;
      }
    else
      {
        Object newArray = null;
        int newSize = currentSize * 2;

        if (newSize <= requiredSize)
          {
            newSize = requiredSize + 1;
          }

        if (array instanceof char[])
          {
            newArray = new char[newSize];
          }
        else if (array instanceof Object[])
          {
            newArray = new Object[newSize];
          }
        else
          {
            throw new RuntimeException();
          }

        System.arraycopy(array, 0, newArray, 0, currentSize);
        return newArray;
      }
  }

  //////////////////////////////////////////////////////////////////////
  // XML query routines.
  //////////////////////////////////////////////////////////////////////

  boolean isStandalone()
  {
    return docIsStandalone;
  }

  //
  // Elements
  //

  private int getContentType(ElementDecl element, int defaultType)
  {
    int retval;

    if (element == null)
      {
        return defaultType;
      }
    retval = element.contentType;
    if (retval == CONTENT_UNDECLARED)
      {
        retval = defaultType;
      }
    return retval;
  }

  /**
   * Look up the content type of an element.
   * @param name The element type name.
   * @return An integer constant representing the content type.
   * @see #CONTENT_UNDECLARED
   * @see #CONTENT_ANY
   * @see #CONTENT_EMPTY
   * @see #CONTENT_MIXED
   * @see #CONTENT_ELEMENTS
   */
  public int getElementContentType(String name)
  {
    ElementDecl element = (ElementDecl) elementInfo.get(name);
    return getContentType(element, CONTENT_UNDECLARED);
  }

  /**
   * Register an element.
   * Array format:
   *  [0] element type name
   *  [1] content model (mixed, elements only)
   *  [2] attribute hash table
   */
  private void setElement(String name, int contentType,
                          String contentModel, HashMap attributes)
    throws SAXException
  {
    if (skippedPE)
      {
        return;
      }

    ElementDecl element = (ElementDecl) elementInfo.get(name);

    // first <!ELEMENT ...> or <!ATTLIST ...> for this type?
    if (element == null)
      {
        element = new ElementDecl();
        element.contentType = contentType;
        element.contentModel = contentModel;
        element.attributes = attributes;
        elementInfo.put(name, element);
        return;
      }

    // <!ELEMENT ...> declaration?
    if (contentType != CONTENT_UNDECLARED)
      {
        // ... following an associated <!ATTLIST ...>
        if (element.contentType == CONTENT_UNDECLARED)
          {
            element.contentType = contentType;
            element.contentModel = contentModel;
          }
        else
          {
            // VC: Unique Element Type Declaration
            handler.verror("multiple declarations for element type: "
                           + name);
          }
      }

    // first <!ATTLIST ...>, before <!ELEMENT ...> ?
    else if (attributes != null)
      {
        element.attributes = attributes;
      }
  }

  /**
   * Look up the attribute hash table for an element.
   * The hash table is the second item in the element array.
   */
  private HashMap getElementAttributes(String name)
  {
    ElementDecl element = (ElementDecl) elementInfo.get(name);
    return (element == null) ? null : element.attributes;
  }

  //
  // Attributes
  //

  /**
   * Get the declared attributes for an element type.
   * @param elname The name of the element type.
   * @return An iterator over all the attributes declared for
   *   a specific element type.  The results will be valid only
   *   after the DTD (if any) has been parsed.
   * @see #getAttributeType
   * @see #getAttributeEnumeration
   * @see #getAttributeDefaultValueType
   * @see #getAttributeDefaultValue
   * @see #getAttributeExpandedValue
   */
  private Iterator declaredAttributes(ElementDecl element)
  {
    HashMap attlist;

    if (element == null)
      {
        return null;
      }
    if ((attlist = element.attributes) == null)
      {
        return null;
      }
    return attlist.keySet().iterator();
  }

  /**
   * Get the declared attributes for an element type.
   * @param elname The name of the element type.
   * @return An iterator over all the attributes declared for
   *   a specific element type.  The results will be valid only
   *   after the DTD (if any) has been parsed.
   * @see #getAttributeType
   * @see #getAttributeEnumeration
   * @see #getAttributeDefaultValueType
   * @see #getAttributeDefaultValue
   * @see #getAttributeExpandedValue
   */
  public Iterator declaredAttributes(String elname)
  {
    return declaredAttributes((ElementDecl) elementInfo.get(elname));
  }

  /**
   * Retrieve the declared type of an attribute.
   * @param name The name of the associated element.
   * @param aname The name of the attribute.
   * @return An interend string denoting the type, or null
   *  indicating an undeclared attribute.
   */
  public String getAttributeType(String name, String aname)
  {
    AttributeDecl attribute = getAttribute(name, aname);
    return (attribute == null) ? null : attribute.type;
  }

  /**
   * Retrieve the allowed values for an enumerated attribute type.
   * @param name The name of the associated element.
   * @param aname The name of the attribute.
   * @return A string containing the token list.
   */
  public String getAttributeEnumeration(String name, String aname)
  {
    AttributeDecl attribute = getAttribute(name, aname);
    // assert:  attribute.enumeration is "ENUMERATION" or "NOTATION"
    return (attribute == null) ? null : attribute.enumeration;
  }

  /**
   * Retrieve the default value of a declared attribute.
   * @param name The name of the associated element.
   * @param aname The name of the attribute.
   * @return The default value, or null if the attribute was
   *   #IMPLIED or simply undeclared and unspecified.
   * @see #getAttributeExpandedValue
   */
  public String getAttributeDefaultValue(String name, String aname)
  {
    AttributeDecl attribute = getAttribute(name, aname);
    return (attribute == null) ? null : attribute.value;
  }

    /*

// FIXME:  Leaving this in, until W3C finally resolves the confusion
// between parts of the XML 2nd REC about when entity declararations
// are guaranteed to be known.  Current code matches what section 5.1
// (conformance) describes, but some readings of the self-contradicting
// text in 4.1 (the "Entity Declared" WFC and VC) seem to expect that
// attribute expansion/normalization must be deferred in some cases
// (just TRY to identify them!).

     * Retrieve the expanded value of a declared attribute.
     * <p>General entities (and char refs) will be expanded (once).
     * @param name The name of the associated element.
     * @param aname The name of the attribute.
     * @return The expanded default value, or null if the attribute was
     *   #IMPLIED or simply undeclared
     * @see #getAttributeDefaultValue
    public String getAttributeExpandedValue (String name, String aname)
    throws Exception
    {
  AttributeDecl attribute = getAttribute (name, aname);

  if (attribute == null) {
      return null;
  } else if (attribute.defaultValue == null && attribute.value != null) {
      // we MUST use the same buf for both quotes else the literal
      // can't be properly terminated
      char buf [] = new char [1];
      int  flags = LIT_ENTITY_REF | LIT_ATTRIBUTE;
      String type = getAttributeType (name, aname);

      if (type != "CDATA" && type != null)
    flags |= LIT_NORMALIZE;
      buf [0] = '"';
      pushCharArray (null, buf, 0, 1);
      pushString (null, attribute.value);
      pushCharArray (null, buf, 0, 1);
      attribute.defaultValue = readLiteral (flags);
  }
  return attribute.defaultValue;
    }
     */

  /**
   * Retrieve the default value mode of a declared attribute.
   * @see #ATTRIBUTE_DEFAULT_SPECIFIED
   * @see #ATTRIBUTE_DEFAULT_IMPLIED
   * @see #ATTRIBUTE_DEFAULT_REQUIRED
   * @see #ATTRIBUTE_DEFAULT_FIXED
   */
  public int getAttributeDefaultValueType(String name, String aname)
  {
    AttributeDecl attribute = getAttribute(name, aname);
    return (attribute == null) ? ATTRIBUTE_DEFAULT_UNDECLARED :
      attribute.valueType;
  }

  /**
   * Register an attribute declaration for later retrieval.
   * Format:
   * - String type
   * - String default value
   * - int value type
   * - enumeration
   * - processed default value
   */
  private void setAttribute(String elName, String name, String type,
                            String enumeration, String value, int valueType)
    throws Exception
  {
    HashMap attlist;

    if (skippedPE)
      {
        return;
      }

    // Create a new hashtable if necessary.
    attlist = getElementAttributes(elName);
    if (attlist == null)
      {
        attlist = new HashMap();
      }

    // ignore multiple attribute declarations!
    if (attlist.get(name) != null)
      {
        // warn ...
        return;
      }
    else
      {
        AttributeDecl attribute = new AttributeDecl();
        attribute.type = type;
        attribute.value = value;
        attribute.valueType = valueType;
        attribute.enumeration = enumeration;
        attlist.put(name, attribute);

        // save; but don't overwrite any existing <!ELEMENT ...>
        setElement(elName, CONTENT_UNDECLARED, null, attlist);
      }
  }

  /**
   * Retrieve the attribute declaration for the given element name and name.
   */
  private AttributeDecl getAttribute(String elName, String name)
  {
    HashMap attlist = getElementAttributes(elName);
    return (attlist == null) ? null : (AttributeDecl) attlist.get(name);
  }

  //
  // Entities
  //

  /**
   * Find the type of an entity.
   * @returns An integer constant representing the entity type.
   * @see #ENTITY_UNDECLARED
   * @see #ENTITY_INTERNAL
   * @see #ENTITY_NDATA
   * @see #ENTITY_TEXT
   */
  public int getEntityType(String ename)
  {
    EntityInfo entity = (EntityInfo) entityInfo.get(ename);
    return (entity == null) ?  ENTITY_UNDECLARED : entity.type;
  }

  /**
   * Return an external entity's identifiers.
   * @param ename The name of the external entity.
   * @return The entity's public identifier, system identifier, and base URI.
   *  Null if the entity was not declared as an external entity.
   * @see #getEntityType
   */
  public ExternalIdentifiers getEntityIds(String ename)
  {
    EntityInfo entity = (EntityInfo) entityInfo.get(ename);
    return (entity == null) ? null : entity.ids;
  }

  /**
   * Return an internal entity's replacement text.
   * @param ename The name of the internal entity.
   * @return The entity's replacement text, or null if
   *   the entity was not declared as an internal entity.
   * @see #getEntityType
   */
  public String getEntityValue(String ename)
  {
    EntityInfo entity = (EntityInfo) entityInfo.get(ename);
    return (entity == null) ? null : entity.value;
  }

  /**
   * Register an entity declaration for later retrieval.
   */
  private void setInternalEntity(String eName, String value)
    throws SAXException
  {
    if (skippedPE)
      {
        return;
      }

    if (entityInfo.get(eName) == null)
      {
        EntityInfo entity = new EntityInfo();
        entity.type = ENTITY_INTERNAL;
        entity.value = value;
        entityInfo.put(eName, entity);
      }
    if (handler.stringInterning)
      {
        if ("lt" == eName || "gt" == eName || "quot" == eName
            || "apos" == eName || "amp" == eName)
          {
            return;
          }
      }
    else
      {
        if ("lt".equals(eName) || "gt".equals(eName) || "quot".equals(eName)
            || "apos".equals(eName) || "amp".equals(eName))
          {
            return;
          }
      }
    handler.getDeclHandler().internalEntityDecl(eName, value);
  }

  /**
   * Register an external entity declaration for later retrieval.
   */
  private void setExternalEntity(String eName, int eClass,
                                 ExternalIdentifiers ids, String nName)
  {
    if (entityInfo.get(eName) == null)
      {
        EntityInfo entity = new EntityInfo();
        entity.type = eClass;
        entity.ids = ids;
        entity.notationName = nName;
        entityInfo.put(eName, entity);
      }
  }

  //
  // Notations.
  //

  /**
   * Report a notation declaration, checking for duplicates.
   */
  private void setNotation(String nname, ExternalIdentifiers ids)
    throws SAXException
  {
    if (skippedPE)
      {
        return;
      }

    handler.notationDecl(nname, ids.publicId, ids.systemId, ids.baseUri);
    if (notationInfo.get(nname) == null)
      {
        notationInfo.put(nname, nname);
      }
    else
      {
        // VC: Unique Notation Name
        handler.verror("Duplicate notation name decl: " + nname);
      }
  }

  //
  // Location.
  //

  /**
   * Return the current line number.
   */
  public int getLineNumber()
  {
    return line;
  }

  /**
   * Return the current column number.
   */
  public int getColumnNumber()
  {
    return column;
  }

  //////////////////////////////////////////////////////////////////////
  // High-level I/O.
  //////////////////////////////////////////////////////////////////////

  /**
   * Read a single character from the readBuffer.
   * <p>The readDataChunk () method maintains the buffer.
   * <p>If we hit the end of an entity, try to pop the stack and
   * keep going.
   * <p> (This approach doesn't really enforce XML's rules about
   * entity boundaries, but this is not currently a validating
   * parser).
   * <p>This routine also attempts to keep track of the current
   * position in external entities, but it's not entirely accurate.
   * @return The next available input character.
   * @see #unread (char)
   * @see #readDataChunk
   * @see #readBuffer
   * @see #line
   * @return The next character from the current input source.
   */
  private char readCh()
    throws SAXException, IOException
  {
    // As long as there's nothing in the
    // read buffer, try reading more data
    // (for an external entity) or popping
    // the entity stack (for either).
    while (readBufferPos >= readBufferLength)
      {
        switch (sourceType)
          {
          case INPUT_READER:
          case INPUT_STREAM:
            readDataChunk();
            while (readBufferLength < 1)
              {
                popInput();
                if (readBufferLength < 1)
                  {
                    readDataChunk();
                  }
              }
            break;

          default:

            popInput();
            break;
          }
      }

    char c = readBuffer[readBufferPos++];

    if (c == '\n')
      {
        line++;
        column = 0;
      }
    else
      {
        if (c == '<')
          {
            /* the most common return to parseContent () ... NOP */
          }
        else if (((c < 0x0020 && (c != '\t') && (c != '\r')) || c > 0xFFFD)
                 || ((c >= 0x007f) && (c <= 0x009f) && (c != 0x0085)
                     && xmlVersion == XML_11))
          {
            error("illegal XML character U+" + Integer.toHexString(c));
          }

        // If we're in the DTD and in a context where PEs get expanded,
        // do so ... 1/14/2000 errata identify those contexts.  There
        // are also spots in the internal subset where PE refs are fatal
        // errors, hence yet another flag.
        else if (c == '%' && expandPE)
          {
            if (peIsError)
              {
                error("PE reference within decl in internal subset.");
              }
            parsePEReference();
            return readCh();
          }
        column++;
      }

    return c;
  }

  /**
   * Push a single character back onto the current input stream.
   * <p>This method usually pushes the character back onto
   * the readBuffer.
   * <p>I don't think that this would ever be called with
   * readBufferPos = 0, because the methods always reads a character
   * before unreading it, but just in case, I've added a boundary
   * condition.
   * @param c The character to push back.
   * @see #readCh
   * @see #unread (char[])
   * @see #readBuffer
   */
  private void unread(char c)
    throws SAXException
  {
    // Normal condition.
    if (c == '\n')
      {
        line--;
        column = -1;
      }
    if (readBufferPos > 0)
      {
        readBuffer[--readBufferPos] = c;
      }
    else
      {
        pushString(null, Character.toString(c));
      }
  }

  /**
   * Push a char array back onto the current input stream.
   * <p>NOTE: you must <em>never</em> push back characters that you
   * haven't actually read: use pushString () instead.
   * @see #readCh
   * @see #unread (char)
   * @see #readBuffer
   * @see #pushString
   */
  private void unread(char[] ch, int length)
    throws SAXException
  {
    for (int i = 0; i < length; i++)
      {
        if (ch[i] == '\n')
          {
            line--;
            column = -1;
          }
      }
    if (length < readBufferPos)
      {
        readBufferPos -= length;
      }
    else
      {
        pushCharArray(null, ch, 0, length);
      }
  }

  /**
   * Push, or skip, a new external input source.
   * The source will be some kind of parsed entity, such as a PE
   * (including the external DTD subset) or content for the body.
   *
   * @param url The java.net.URL object for the entity.
   * @see SAXDriver#resolveEntity
   * @see #pushString
   * @see #sourceType
   * @see #pushInput
   * @see #detectEncoding
   * @see #sourceType
   * @see #readBuffer
   */
  private void pushURL(boolean isPE,
                       String ename,
                       ExternalIdentifiers ids,
                       Reader reader,
                       InputStream stream,
                       String encoding,
                       boolean doResolve)
    throws SAXException, IOException
  {
    boolean ignoreEncoding;
    String systemId;
    InputSource source;

    if (!isPE)
      {
        dataBufferFlush();
      }

    scratch.setPublicId(ids.publicId);
    scratch.setSystemId(ids.systemId);

    // See if we should skip or substitute the entity.
    // If we're not skipping, resolving reports startEntity()
    // and updates the (handler's) stack of URIs.
    if (doResolve)
      {
        // assert (stream == null && reader == null && encoding == null)
        source = handler.resolveEntity(isPE, ename, scratch, ids.baseUri);
        if (source == null)
          {
            handler.warn("skipping entity: " + ename);
            handler.skippedEntity(ename);
            if (isPE)
              {
                skippedPE = true;
              }
            return;
          }

        // we might be using alternate IDs/encoding
        systemId = source.getSystemId();
        // The following warning and setting systemId was deleted bcause
        // the application has the option of not setting systemId
        // provided that it has set the characte/byte stream.
        /*
           if (systemId == null) {
           handler.warn ("missing system ID, using " + ids.systemId);
           systemId = ids.systemId;
           }
         */
      }
    else
      {
        // "[document]", or "[dtd]" via getExternalSubset()
        scratch.setCharacterStream(reader);
        scratch.setByteStream(stream);
        scratch.setEncoding(encoding);
        source = scratch;
        systemId = ids.systemId;
        if (handler.stringInterning)
          {
            handler.startExternalEntity(ename, systemId,
                                        "[document]" == ename);
          }
        else
          {
            handler.startExternalEntity(ename, systemId,
                                        "[document]".equals(ename));
          }
      }

    // we may have been given I/O streams directly
    if (source.getCharacterStream() != null)
      {
        if (source.getByteStream() != null)
          error("InputSource has two streams!");
        reader = source.getCharacterStream();
      }
    else if (source.getByteStream() != null)
      {
        encoding = source.getEncoding();
        if (encoding == null)
          {
            stream = source.getByteStream();
          }
        else
          {
            try
              {
                reader = new InputStreamReader(source.getByteStream(),
                                               encoding);
              }
            catch (IOException e)
              {
                stream = source.getByteStream();
              }
          }
      }
    else if (systemId == null)
      {
        error("InputSource has no URI!");
      }
    scratch.setCharacterStream(null);
    scratch.setByteStream(null);
    scratch.setEncoding(null);

    // Push the existing status.
    pushInput(ename);

    // Create a new read buffer.
    // (Note the four-character margin)
    readBuffer = new char[READ_BUFFER_MAX + 4];
    readBufferPos = 0;
    readBufferLength = 0;
    readBufferOverflow = -1;
    is = null;
    line = 1;
    column = 0;
    currentByteCount = 0;

    // If there's an explicit character stream, just
    // ignore encoding declarations.
    if (reader != null)
      {
        sourceType = INPUT_READER;
        this.reader = reader;
        tryEncodingDecl(true);
        return;
      }

    // Else we handle the conversion, and need to ensure
    // it's done right.
    sourceType = INPUT_STREAM;
    if (stream != null)
      {
        is = stream;
      }
    else
      {
        // We have to open our own stream to the URL.
        URL url = new URL(systemId);

        externalEntity = url.openConnection();
        externalEntity.connect();
        is = externalEntity.getInputStream();
      }

    // If we get to here, there must be
    // an InputStream available.
    if (!is.markSupported())
      {
        is = new BufferedInputStream(is);
      }

    // Get any external encoding label.
    if (encoding == null && externalEntity != null)
      {
        // External labels can be untrustworthy; filesystems in
        // particular often have the wrong default for content
        // that wasn't locally originated.  Those we autodetect.
        if (!"file".equals(externalEntity.getURL().getProtocol()))
          {
            int temp;

            // application/xml;charset=something;otherAttr=...
            // ... with many variants on 'something'
            encoding = externalEntity.getContentType();

            // MHK code (fix for Saxon 5.5.1/007):
            // protect against encoding==null
            if (encoding == null)
              {
                temp = -1;
              }
            else
              {
                temp = encoding.indexOf("charset");
              }

            // RFC 2376 sez MIME text defaults to ASCII, but since the
            // JDK will create a MIME type out of thin air, we always
            // autodetect when there's no explicit charset attribute.
            if (temp < 0)
              {
                encoding = null;  // autodetect
              }
            else
              {
                // only this one attribute
                if ((temp = encoding.indexOf(';')) > 0)
                  {
                    encoding = encoding.substring(0, temp);
                  }

                if ((temp = encoding.indexOf('=', temp + 7)) > 0)
                  {
                    encoding = encoding.substring(temp + 1);

                    // attributes can have comment fields (RFC 822)
                    if ((temp = encoding.indexOf('(')) > 0)
                      {
                        encoding = encoding.substring(0, temp);
                      }
                    // ... and values may be quoted
                    if ((temp = encoding.indexOf('"')) > 0)
                      {
                        encoding =
                          encoding.substring(temp + 1,
                                             encoding.indexOf('"', temp + 2));
                      }
                    encoding = encoding.trim();
                  }
                else
                  {
                    handler.warn("ignoring illegal MIME attribute: "
                                 + encoding);
                    encoding = null;
                  }
              }
          }
      }

    // if we got an external encoding label, use it ...
    if (encoding != null)
      {
        this.encoding = ENCODING_EXTERNAL;
        setupDecoding(encoding);
        ignoreEncoding = true;

        // ... else autodetect from first bytes.
      }
    else
      {
        detectEncoding();
        ignoreEncoding = false;
      }

    // Read any XML or text declaration.
    // If we autodetected, it may tell us the "real" encoding.
    try
      {
        tryEncodingDecl(ignoreEncoding);
      }
    catch (UnsupportedEncodingException x)
      {
        encoding = x.getMessage();

        // if we don't handle the declared encoding,
        // try letting a JVM InputStreamReader do it
        try
          {
            if (sourceType != INPUT_STREAM)
              {
                throw x;
              }

            is.reset();
            readBufferPos = 0;
            readBufferLength = 0;
            readBufferOverflow = -1;
            line = 1;
            currentByteCount = column = 0;

            sourceType = INPUT_READER;
            this.reader = new InputStreamReader(is, encoding);
            is = null;

            tryEncodingDecl(true);

          }
        catch (IOException e)
          {
            error("unsupported text encoding",
                  encoding,
                  null);
          }
      }
  }

  /**
   * Check for an encoding declaration.  This is the second part of the
   * XML encoding autodetection algorithm, relying on detectEncoding to
   * get to the point that this part can read any encoding declaration
   * in the document (using only US-ASCII characters).
   *
   * <p> Because this part starts to fill parser buffers with this data,
   * it's tricky to setup a reader so that Java's built-in decoders can be
   * used for the character encodings that aren't built in to this parser
   * (such as EUC-JP, KOI8-R, Big5, etc).
   *
   * @return any encoding in the declaration, uppercased; or null
   * @see detectEncoding
   */
  private String tryEncodingDecl(boolean ignoreEncoding)
    throws SAXException, IOException
  {
    // Read the XML/text declaration.
    if (tryRead("<?xml"))
      {
        if (tryWhitespace())
          {
            if (inputStack.size() > 0)
              {
                return parseTextDecl(ignoreEncoding);
              }
            else
              {
                return parseXMLDecl(ignoreEncoding);
              }
          }
        else
          {
            // <?xml-stylesheet ...?> or similar
            unread('l');
            unread('m');
            unread('x');
            unread('?');
            unread('<');
          }
      }
    return null;
  }

  /**
   * Attempt to detect the encoding of an entity.
   * <p>The trick here (as suggested in the XML standard) is that
   * any entity not in UTF-8, or in UCS-2 with a byte-order mark,
   * <b>must</b> begin with an XML declaration or an encoding
   * declaration; we simply have to look for "&lt;?xml" in various
   * encodings.
   * <p>This method has no way to distinguish among 8-bit encodings.
   * Instead, it sets up for UTF-8, then (possibly) revises its assumption
   * later in setupDecoding ().  Any ASCII-derived 8-bit encoding
   * should work, but most will be rejected later by setupDecoding ().
   * @see #tryEncoding (byte[], byte, byte, byte, byte)
   * @see #tryEncoding (byte[], byte, byte)
   * @see #setupDecoding
   */
  private void detectEncoding()
    throws SAXException, IOException
  {
    byte[] signature = new byte[4];

    // Read the first four bytes for
    // autodetection.
    is.mark(4);
    is.read(signature);
    is.reset();

    //
    // FIRST:  four byte encodings (who uses these?)
    //
    if (tryEncoding(signature, (byte) 0x00, (byte) 0x00,
                    (byte) 0x00, (byte) 0x3c))
      {
        // UCS-4 must begin with "<?xml"
        // 0x00 0x00 0x00 0x3c: UCS-4, big-endian (1234)
        // "UTF-32BE"
        encoding = ENCODING_UCS_4_1234;
      }
    else if (tryEncoding(signature, (byte) 0x3c, (byte) 0x00,
                         (byte) 0x00, (byte) 0x00))
      {
        // 0x3c 0x00 0x00 0x00: UCS-4, little-endian (4321)
        // "UTF-32LE"
        encoding = ENCODING_UCS_4_4321;
      }
    else if (tryEncoding(signature, (byte) 0x00, (byte) 0x00,
                         (byte) 0x3c, (byte) 0x00))
      {
        // 0x00 0x00 0x3c 0x00: UCS-4, unusual (2143)
        encoding = ENCODING_UCS_4_2143;
      }
    else if (tryEncoding(signature, (byte) 0x00, (byte) 0x3c,
                         (byte) 0x00, (byte) 0x00))
      {
        // 0x00 0x3c 0x00 0x00: UCS-4, unusual (3421)
        encoding = ENCODING_UCS_4_3412;

        // 00 00 fe ff UCS_4_1234 (with BOM)
        // ff fe 00 00 UCS_4_4321 (with BOM)
      }

    //
    // SECOND:  two byte encodings
    // note ... with 1/14/2000 errata the XML spec identifies some
    // more "broken UTF-16" autodetection cases, with no XML decl,
    // which we don't handle here (that's legal too).
    //
    else if (tryEncoding(signature, (byte) 0xfe, (byte) 0xff))
      {
        // UCS-2 with a byte-order marker. (UTF-16)
        // 0xfe 0xff: UCS-2, big-endian (12)
        encoding = ENCODING_UCS_2_12;
        is.read(); is.read();
      }
    else if (tryEncoding(signature, (byte) 0xff, (byte) 0xfe))
      {
        // UCS-2 with a byte-order marker. (UTF-16)
        // 0xff 0xfe: UCS-2, little-endian (21)
        encoding = ENCODING_UCS_2_21;
        is.read(); is.read();
      }
    else if (tryEncoding(signature, (byte) 0x00, (byte) 0x3c,
                         (byte) 0x00, (byte) 0x3f))
      {
        // UTF-16BE (otherwise, malformed UTF-16)
        // 0x00 0x3c 0x00 0x3f: UCS-2, big-endian, no byte-order mark
        encoding = ENCODING_UCS_2_12;
        error("no byte-order mark for UCS-2 entity");
      }
    else if (tryEncoding(signature, (byte) 0x3c, (byte) 0x00,
                         (byte) 0x3f, (byte) 0x00))
      {
        // UTF-16LE (otherwise, malformed UTF-16)
        // 0x3c 0x00 0x3f 0x00: UCS-2, little-endian, no byte-order mark
        encoding = ENCODING_UCS_2_21;
        error("no byte-order mark for UCS-2 entity");
      }

    //
    // THIRD:  ASCII-derived encodings, fixed and variable lengths
    //
    else if (tryEncoding(signature, (byte) 0x3c, (byte) 0x3f,
                         (byte) 0x78, (byte) 0x6d))
      {
        // ASCII derived
        // 0x3c 0x3f 0x78 0x6d: UTF-8 or other 8-bit markup (read ENCODING)
        encoding = ENCODING_UTF_8;
        prefetchASCIIEncodingDecl();
      }
    else if (signature[0] == (byte) 0xef
             && signature[1] == (byte) 0xbb
             && signature[2] == (byte) 0xbf)
      {
        // 0xef 0xbb 0xbf: UTF-8 BOM (not part of document text)
        // this un-needed notion slipped into XML 2nd ed through a
        // "non-normative" erratum; now required by MSFT and UDDI,
        // and E22 made it normative.
        encoding = ENCODING_UTF_8;
        is.read(); is.read(); is.read();
      }
    else
      {
        // 4c 6f a7 94 ... we don't understand EBCDIC flavors
        // ... but we COULD at least kick in some fixed code page

        // (default) UTF-8 without encoding/XML declaration
        encoding = ENCODING_UTF_8;
      }
  }

  /**
   * Check for a four-byte signature.
   * <p>Utility routine for detectEncoding ().
   * <p>Always looks for some part of "<?XML" in a specific encoding.
   * @param sig The first four bytes read.
   * @param b1 The first byte of the signature
   * @param b2 The second byte of the signature
   * @param b3 The third byte of the signature
   * @param b4 The fourth byte of the signature
   * @see #detectEncoding
   */
  private static boolean tryEncoding(byte[] sig, byte b1, byte b2,
                                     byte b3, byte b4)
  {
    return (sig[0] == b1 && sig[1] == b2
            && sig[2] == b3 && sig[3] == b4);
  }

  /**
   * Check for a two-byte signature.
   * <p>Looks for a UCS-2 byte-order mark.
   * <p>Utility routine for detectEncoding ().
   * @param sig The first four bytes read.
   * @param b1 The first byte of the signature
   * @param b2 The second byte of the signature
   * @see #detectEncoding
   */
  private static boolean tryEncoding(byte[] sig, byte b1, byte b2)
  {
    return ((sig[0] == b1) && (sig[1] == b2));
  }

  /**
   * This method pushes a string back onto input.
   * <p>It is useful either as the expansion of an internal entity,
   * or for backtracking during the parse.
   * <p>Call pushCharArray () to do the actual work.
   * @param s The string to push back onto input.
   * @see #pushCharArray
   */
  private void pushString(String ename, String s)
    throws SAXException
  {
    char[] ch = s.toCharArray();
    pushCharArray(ename, ch, 0, ch.length);
  }

  /**
   * Push a new internal input source.
   * <p>This method is useful for expanding an internal entity,
   * or for unreading a string of characters.  It creates a new
   * readBuffer containing the characters in the array, instead
   * of characters converted from an input byte stream.
   * @param ch The char array to push.
   * @see #pushString
   * @see #pushURL
   * @see #readBuffer
   * @see #sourceType
   * @see #pushInput
   */
  private void pushCharArray(String ename, char[] ch, int start, int length)
    throws SAXException
  {
    // Push the existing status
    pushInput(ename);
    if (ename != null && doReport)
      {
        dataBufferFlush();
        handler.startInternalEntity(ename);
      }
    sourceType = INPUT_INTERNAL;
    readBuffer = ch;
    readBufferPos = start;
    readBufferLength = length;
    readBufferOverflow = -1;
  }

  /**
   * Save the current input source onto the stack.
   * <p>This method saves all of the global variables associated with
   * the current input source, so that they can be restored when a new
   * input source has finished.  It also tests for entity recursion.
   * <p>The method saves the following global variables onto a stack
   * using a fixed-length array:
   * <ol>
   * <li>sourceType
   * <li>externalEntity
   * <li>readBuffer
   * <li>readBufferPos
   * <li>readBufferLength
   * <li>line
   * <li>encoding
   * </ol>
   * @param ename The name of the entity (if any) causing the new input.
   * @see #popInput
   * @see #sourceType
   * @see #externalEntity
   * @see #readBuffer
   * @see #readBufferPos
   * @see #readBufferLength
   * @see #line
   * @see #encoding
   */
  private void pushInput(String ename)
    throws SAXException
  {
    // Check for entity recursion.
    if (ename != null)
      {
        Iterator entities = entityStack.iterator();
        while (entities.hasNext())
          {
            String e = (String) entities.next();
            if (e != null && e == ename)
              {
                error("recursive reference to entity", ename, null);
              }
          }
      }
    entityStack.addLast(ename);

    // Don't bother if there is no current input.
    if (sourceType == INPUT_NONE)
      {
        return;
      }

    // Set up a snapshot of the current
    // input source.
    Input input = new Input();

    input.sourceType = sourceType;
    input.externalEntity = externalEntity;
    input.readBuffer = readBuffer;
    input.readBufferPos = readBufferPos;
    input.readBufferLength = readBufferLength;
    input.line = line;
    input.encoding = encoding;
    input.readBufferOverflow = readBufferOverflow;
    input.is = is;
    input.currentByteCount = currentByteCount;
    input.column = column;
    input.reader = reader;

    // Push it onto the stack.
    inputStack.addLast(input);
  }

  /**
   * Restore a previous input source.
   * <p>This method restores all of the global variables associated with
   * the current input source.
   * @exception java.io.EOFException
   *    If there are no more entries on the input stack.
   * @see #pushInput
   * @see #sourceType
   * @see #externalEntity
   * @see #readBuffer
   * @see #readBufferPos
   * @see #readBufferLength
   * @see #line
   * @see #encoding
   */
  private void popInput()
    throws SAXException, IOException
  {
    String ename = (String) entityStack.removeLast();

    if (ename != null && doReport)
      {
        dataBufferFlush();
      }
    switch (sourceType)
      {
      case INPUT_STREAM:
        handler.endExternalEntity(ename);
        is.close();
        break;
      case INPUT_READER:
        handler.endExternalEntity(ename);
        reader.close();
        break;
      case INPUT_INTERNAL:
        if (ename != null && doReport)
          {
            handler.endInternalEntity(ename);
          }
        break;
      }

    // Throw an EOFException if there
    // is nothing else to pop.
    if (inputStack.isEmpty())
      {
        throw new EOFException("no more input");
      }

    Input input = (Input) inputStack.removeLast();

    sourceType = input.sourceType;
    externalEntity = input.externalEntity;
    readBuffer = input.readBuffer;
    readBufferPos = input.readBufferPos;
    readBufferLength = input.readBufferLength;
    line = input.line;
    encoding = input.encoding;
    readBufferOverflow = input.readBufferOverflow;
    is = input.is;
    currentByteCount = input.currentByteCount;
    column = input.column;
    reader = input.reader;
  }

  /**
   * Return true if we can read the expected character.
   * <p>Note that the character will be removed from the input stream
   * on success, but will be put back on failure.  Do not attempt to
   * read the character again if the method succeeds.
   * @param delim The character that should appear next.  For a
   *        insensitive match, you must supply this in upper-case.
   * @return true if the character was successfully read, or false if
   *   it was not.
   * @see #tryRead (String)
   */
  private boolean tryRead(char delim)
    throws SAXException, IOException
  {
    char c;

    // Read the character
    c = readCh();

    // Test for a match, and push the character
    // back if the match fails.
    if (c == delim)
      {
        return true;
      }
    else
      {
        unread(c);
        return false;
      }
  }

  /**
   * Return true if we can read the expected string.
   * <p>This is simply a convenience method.
   * <p>Note that the string will be removed from the input stream
   * on success, but will be put back on failure.  Do not attempt to
   * read the string again if the method succeeds.
   * <p>This method will push back a character rather than an
   * array whenever possible (probably the majority of cases).
   * @param delim The string that should appear next.
   * @return true if the string was successfully read, or false if
   *   it was not.
   * @see #tryRead (char)
   */
  private boolean tryRead(String delim)
    throws SAXException, IOException
  {
    return tryRead(delim.toCharArray());
  }

  private boolean tryRead(char[] ch)
    throws SAXException, IOException
  {
    char c;

    // Compare the input, character-
    // by character.

    for (int i = 0; i < ch.length; i++)
      {
        c = readCh();
        if (c != ch[i])
          {
            unread(c);
            if (i != 0)
              {
                unread(ch, i);
              }
            return false;
          }
      }
    return true;
  }

  /**
   * Return true if we can read some whitespace.
   * <p>This is simply a convenience method.
   * <p>This method will push back a character rather than an
   * array whenever possible (probably the majority of cases).
   * @return true if whitespace was found.
   */
  private boolean tryWhitespace()
    throws SAXException, IOException
  {
    char c;
    c = readCh();
    if (isWhitespace(c))
      {
        skipWhitespace();
        return true;
      }
    else
      {
        unread(c);
        return false;
      }
  }

  /**
   * Read all data until we find the specified string.
   * This is useful for scanning CDATA sections and PIs.
   * <p>This is inefficient right now, since it calls tryRead ()
   * for every character.
   * @param delim The string delimiter
   * @see #tryRead (String, boolean)
   * @see #readCh
   */
  private void parseUntil(String delim)
    throws SAXException, IOException
  {
    parseUntil(delim.toCharArray());
  }

  private void parseUntil(char[] delim)
    throws SAXException, IOException
  {
    char c;
    int startLine = line;

    try
      {
        while (!tryRead(delim))
          {
            c = readCh();
            dataBufferAppend(c);
          }
      }
    catch (EOFException e)
      {
        error("end of input while looking for delimiter "
              + "(started on line " + startLine
              + ')', null, new String(delim));
      }
  }

  //////////////////////////////////////////////////////////////////////
  // Low-level I/O.
  //////////////////////////////////////////////////////////////////////

  /**
   * Prefetch US-ASCII XML/text decl from input stream into read buffer.
   * Doesn't buffer more than absolutely needed, so that when an encoding
   * decl says we need to create an InputStreamReader, we can discard our
   * buffer and reset().  Caller knows the first chars of the decl exist
   * in the input stream.
   */
  private void prefetchASCIIEncodingDecl()
    throws SAXException, IOException
  {
    int ch;
    readBufferPos = readBufferLength = 0;

    is.mark(readBuffer.length);
    while (true)
      {
        ch = is.read();
        readBuffer[readBufferLength++] = (char) ch;
        switch (ch)
          {
          case (int) '>':
            return;
          case -1:
            error("file ends before end of XML or encoding declaration.",
                  null, "?>");
          }
        if (readBuffer.length == readBufferLength)
          {
            error("unfinished XML or encoding declaration");
          }
      }
  }

  /**
   * Read a chunk of data from an external input source.
   * <p>This is simply a front-end that fills the rawReadBuffer
   * with bytes, then calls the appropriate encoding handler.
   * @see #encoding
   * @see #rawReadBuffer
   * @see #readBuffer
   * @see #filterCR
   * @see #copyUtf8ReadBuffer
   * @see #copyIso8859_1ReadBuffer
   * @see #copyUcs_2ReadBuffer
   * @see #copyUcs_4ReadBuffer
   */
  private void readDataChunk()
    throws SAXException, IOException
  {
    int count;

    // See if we have any overflow (filterCR sets for CR at end)
    if (readBufferOverflow > -1)
      {
        readBuffer[0] = (char) readBufferOverflow;
        readBufferOverflow = -1;
        readBufferPos = 1;
        sawCR = true;
      }
    else
      {
        readBufferPos = 0;
        sawCR = false;
      }

    // input from a character stream.
    if (sourceType == INPUT_READER)
      {
        count = reader.read(readBuffer,
                            readBufferPos, READ_BUFFER_MAX - readBufferPos);
        if (count < 0)
          {
            readBufferLength = readBufferPos;
          }
        else
          {
            readBufferLength = readBufferPos + count;
          }
        if (readBufferLength > 0)
          {
            filterCR(count >= 0);
          }
        sawCR = false;
        return;
      }

    // Read as many bytes as possible into the raw buffer.
    count = is.read(rawReadBuffer, 0, READ_BUFFER_MAX);

    // Dispatch to an encoding-specific reader method to populate
    // the readBuffer.  In most parser speed profiles, these routines
    // show up at the top of the CPU usage chart.
    if (count > 0)
      {
        switch (encoding)
          {
            // one byte builtins
          case ENCODING_ASCII:
            copyIso8859_1ReadBuffer(count, (char) 0x0080);
            break;
          case ENCODING_UTF_8:
            copyUtf8ReadBuffer(count);
            break;
          case ENCODING_ISO_8859_1:
            copyIso8859_1ReadBuffer(count, (char) 0);
            break;

            // two byte builtins
          case ENCODING_UCS_2_12:
            copyUcs2ReadBuffer(count, 8, 0);
            break;
          case ENCODING_UCS_2_21:
            copyUcs2ReadBuffer(count, 0, 8);
            break;

            // four byte builtins
          case ENCODING_UCS_4_1234:
            copyUcs4ReadBuffer(count, 24, 16, 8, 0);
            break;
          case ENCODING_UCS_4_4321:
            copyUcs4ReadBuffer(count, 0, 8, 16, 24);
            break;
          case ENCODING_UCS_4_2143:
            copyUcs4ReadBuffer(count, 16, 24, 0, 8);
            break;
          case ENCODING_UCS_4_3412:
            copyUcs4ReadBuffer(count, 8, 0, 24, 16);
            break;
          }
      }
    else
      {
        readBufferLength = readBufferPos;
      }

    readBufferPos = 0;

    // Filter out all carriage returns if we've seen any
    // (including any saved from a previous read)
    if (sawCR)
      {
        filterCR(count >= 0);
        sawCR = false;

        // must actively report EOF, lest some CRs get lost.
        if (readBufferLength == 0 && count >= 0)
          {
            readDataChunk();
          }
      }

    if (count > 0)
      {
        currentByteCount += count;
      }
  }

  /**
   * Filter carriage returns in the read buffer.
   * CRLF becomes LF; CR becomes LF.
   * @param moreData true iff more data might come from the same source
   * @see #readDataChunk
   * @see #readBuffer
   * @see #readBufferOverflow
   */
  private void filterCR(boolean moreData)
  {
    int i, j;

    readBufferOverflow = -1;

loop:
    for (i = j = readBufferPos; j < readBufferLength; i++, j++)
      {
        switch (readBuffer[j])
          {
          case '\r':
            if (j == readBufferLength - 1)
              {
                if (moreData)
                  {
                    readBufferOverflow = '\r';
                    readBufferLength--;
                  }
                else   // CR at end of buffer
                  {
                    readBuffer[i++] = '\n';
                  }
                break loop;
              }
            else if (readBuffer[j + 1] == '\n')
              {
                j++;
              }
            readBuffer[i] = '\n';
            break;

          case '\n':
          default:
            readBuffer[i] = readBuffer[j];
            break;
          }
      }
    readBufferLength = i;
  }

  /**
   * Convert a buffer of UTF-8-encoded bytes into UTF-16 characters.
   * <p>When readDataChunk () calls this method, the raw bytes are in
   * rawReadBuffer, and the final characters will appear in
   * readBuffer.
   * <p>Note that as of Unicode 3.1, good practice became a requirement,
   * so that each Unicode character has exactly one UTF-8 representation.
   * @param count The number of bytes to convert.
   * @see #readDataChunk
   * @see #rawReadBuffer
   * @see #readBuffer
   * @see #getNextUtf8Byte
   */
  private void copyUtf8ReadBuffer(int count)
    throws SAXException, IOException
  {
    int i = 0;
    int j = readBufferPos;
    int b1;
    char c = 0;

    /*
    // check once, so the runtime won't (if it's smart enough)
    if (count < 0 || count > rawReadBuffer.length)
    throw new ArrayIndexOutOfBoundsException (Integer.toString (count));
     */

    while (i < count)
      {
        b1 = rawReadBuffer[i++];

        // Determine whether we are dealing
        // with a one-, two-, three-, or four-
        // byte sequence.
        if (b1 < 0)
          {
            if ((b1 & 0xe0) == 0xc0)
              {
                // 2-byte sequence: 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
                c = (char) (((b1 & 0x1f) << 6)
                            | getNextUtf8Byte(i++, count));
                if (c < 0x0080)
                  {
                    encodingError("Illegal two byte UTF-8 sequence",
                                  c, 0);
                  }

                //Sec 2.11
                // [1] the two-character sequence #xD #xA
                // [2] the two-character sequence #xD #x85
                if ((c == 0x0085 || c == 0x000a) && sawCR)
                  {
                    continue;
                  }

                // Sec 2.11
                // [3] the single character #x85

                if (c == 0x0085 && xmlVersion == XML_11)
                  {
                    readBuffer[j++] = '\r';
                  }
              }
            else if ((b1 & 0xf0) == 0xe0)
              {
                // 3-byte sequence:
                // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
                // most CJKV characters
                c = (char) (((b1 & 0x0f) << 12) |
                            (getNextUtf8Byte(i++, count) << 6) |
                            getNextUtf8Byte(i++, count));
                //sec 2.11
                //[4] the single character #x2028
                if (c == 0x2028 && xmlVersion == XML_11)
                  {
                    readBuffer[j++] = '\r';
                    sawCR = true;
                    continue;
                  }
                if (c < 0x0800 || (c >= 0xd800 && c <= 0xdfff))
                  {
                    encodingError("Illegal three byte UTF-8 sequence",
                                  c, 0);
                  }
              }
            else if ((b1 & 0xf8) == 0xf0)
              {
                // 4-byte sequence: 11101110wwwwzzzzyy + 110111yyyyxxxxxx
                //     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
                // (uuuuu = wwww + 1)
                // "Surrogate Pairs" ... from the "Astral Planes"
                // Unicode 3.1 assigned the first characters there
                int iso646 = b1 & 07;
                iso646 = (iso646 << 6) + getNextUtf8Byte(i++, count);
                iso646 = (iso646 << 6) + getNextUtf8Byte(i++, count);
                iso646 = (iso646 << 6) + getNextUtf8Byte(i++, count);

                if (iso646 <= 0xffff)
                  {
                    encodingError("Illegal four byte UTF-8 sequence",
                                  iso646, 0);
                  }
                else
                  {
                    if (iso646 > 0x0010ffff)
                      {
                        encodingError("UTF-8 value out of range for Unicode",
                                      iso646, 0);
                      }
                    iso646 -= 0x010000;
                    readBuffer[j++] = (char) (0xd800 | (iso646 >> 10));
                    readBuffer[j++] = (char) (0xdc00 | (iso646 & 0x03ff));
                    continue;
                  }
              }
            else
              {
                // The five and six byte encodings aren't supported;
                // they exceed the Unicode (and XML) range.
                encodingError("unsupported five or six byte UTF-8 sequence",
                              0xff & b1, i);
                // NOTREACHED
                c = 0;
              }
          }
        else
          {
            // 1-byte sequence: 000000000xxxxxxx = 0xxxxxxx
            // (US-ASCII character, "common" case, one branch to here)
            c = (char) b1;
          }
        readBuffer[j++] = c;
        if (c == '\r')
          {
            sawCR = true;
          }
      }
    // How many characters have we read?
    readBufferLength = j;
  }

  /**
   * Return the next byte value in a UTF-8 sequence.
   * If it is not possible to get a byte from the current
   * entity, throw an exception.
   * @param pos The current position in the rawReadBuffer.
   * @param count The number of bytes in the rawReadBuffer
   * @return The significant six bits of a non-initial byte in
   *   a UTF-8 sequence.
   * @exception EOFException If the sequence is incomplete.
   */
  private int getNextUtf8Byte(int pos, int count)
    throws SAXException, IOException
  {
    int val;

    // Take a character from the buffer
    // or from the actual input stream.
    if (pos < count)
      {
        val = rawReadBuffer[pos];
      }
    else
      {
        val = is.read();
        if (val == -1)
          {
            encodingError("unfinished multi-byte UTF-8 sequence at EOF",
                          -1, pos);
          }
      }

    // Check for the correct bits at the start.
    if ((val & 0xc0) != 0x80)
      {
        encodingError("bad continuation of multi-byte UTF-8 sequence",
                      val, pos + 1);
      }

    // Return the significant bits.
    return (val & 0x3f);
  }

  /**
   * Convert a buffer of US-ASCII or ISO-8859-1-encoded bytes into
   * UTF-16 characters.
   *
   * <p>When readDataChunk () calls this method, the raw bytes are in
   * rawReadBuffer, and the final characters will appear in
   * readBuffer.
   *
   * @param count The number of bytes to convert.
   * @param mask For ASCII conversion, 0x7f; else, 0xff.
   * @see #readDataChunk
   * @see #rawReadBuffer
   * @see #readBuffer
   */
  private void copyIso8859_1ReadBuffer(int count, char mask)
    throws IOException
  {
    int i, j;
    for (i = 0, j = readBufferPos; i < count; i++, j++)
      {
        char c = (char) (rawReadBuffer[i] & 0xff);
        if ((c & mask) != 0)
          {
            throw new CharConversionException("non-ASCII character U+"
                                              + Integer.toHexString(c));
          }
        if (c == 0x0085 && xmlVersion == XML_11)
          {
            c = '\r';
          }
        readBuffer[j] = c;
        if (c == '\r')
          {
            sawCR = true;
          }
      }
    readBufferLength = j;
  }

  /**
   * Convert a buffer of UCS-2-encoded bytes into UTF-16 characters
   * (as used in Java string manipulation).
   *
   * <p>When readDataChunk () calls this method, the raw bytes are in
   * rawReadBuffer, and the final characters will appear in
   * readBuffer.
   * @param count The number of bytes to convert.
   * @param shift1 The number of bits to shift byte 1.
   * @param shift2 The number of bits to shift byte 2
   * @see #readDataChunk
   * @see #rawReadBuffer
   * @see #readBuffer
   */
  private void copyUcs2ReadBuffer(int count, int shift1, int shift2)
    throws SAXException
  {
    int j = readBufferPos;

    if (count > 0 && (count % 2) != 0)
      {
        encodingError("odd number of bytes in UCS-2 encoding", -1, count);
      }
    // The loops are faster with less internal brancing; hence two
    if (shift1 == 0)
      {  // "UTF-16-LE"
        for (int i = 0; i < count; i += 2)
          {
            char c = (char) (rawReadBuffer[i + 1] << 8);
            c |= 0xff & rawReadBuffer[i];
            readBuffer[j++] = c;
            if (c == '\r')
              {
                sawCR = true;
              }
          }
      }
    else
      {  // "UTF-16-BE"
        for (int i = 0; i < count; i += 2)
          {
            char c = (char) (rawReadBuffer[i] << 8);
            c |= 0xff & rawReadBuffer[i + 1];
            readBuffer[j++] = c;
            if (c == '\r')
              {
                sawCR = true;
              }
          }
      }
    readBufferLength = j;
  }

  /**
   * Convert a buffer of UCS-4-encoded bytes into UTF-16 characters.
   *
   * <p>When readDataChunk () calls this method, the raw bytes are in
   * rawReadBuffer, and the final characters will appear in
   * readBuffer.
   * <p>Java has Unicode chars, and this routine uses surrogate pairs
   * for ISO-10646 values between 0x00010000 and 0x000fffff.  An
   * exception is thrown if the ISO-10646 character has no Unicode
   * representation.
   *
   * @param count The number of bytes to convert.
   * @param shift1 The number of bits to shift byte 1.
   * @param shift2 The number of bits to shift byte 2
   * @param shift3 The number of bits to shift byte 2
   * @param shift4 The number of bits to shift byte 2
   * @see #readDataChunk
   * @see #rawReadBuffer
   * @see #readBuffer
   */
  private void copyUcs4ReadBuffer(int count, int shift1, int shift2,
                                  int shift3, int shift4)
    throws SAXException
  {
    int j = readBufferPos;

    if (count > 0 && (count % 4) != 0)
      {
        encodingError("number of bytes in UCS-4 encoding " +
                      "not divisible by 4",
                      -1, count);
      }
    for (int i = 0; i < count; i += 4)
      {
        int value = (((rawReadBuffer [i] & 0xff) << shift1) |
                     ((rawReadBuffer [i + 1] & 0xff) << shift2) |
                     ((rawReadBuffer [i + 2] & 0xff) << shift3) |
                     ((rawReadBuffer [i + 3] & 0xff) << shift4));
        if (value < 0x0000ffff)
          {
            readBuffer [j++] = (char) value;
            if (value == (int) '\r')
              {
                sawCR = true;
              }
          }
        else if (value < 0x0010ffff)
          {
            value -= 0x010000;
            readBuffer[j++] = (char) (0xd8 | ((value >> 10) & 0x03ff));
            readBuffer[j++] = (char) (0xdc | (value & 0x03ff));
          }
        else
          {
            encodingError("UCS-4 value out of range for Unicode",
                          value, i);
          }
      }
    readBufferLength = j;
  }

  /**
   * Report a character encoding error.
   */
  private void encodingError(String message, int value, int offset)
    throws SAXException
  {
    if (value != -1)
      {
        message = message + " (character code: 0x" +
          Integer.toHexString(value) + ')';
        error(message);
      }
  }

  //////////////////////////////////////////////////////////////////////
  // Local Variables.
  //////////////////////////////////////////////////////////////////////

  /**
   * Re-initialize the variables for each parse.
   */
  private void initializeVariables()
  {
    // First line
    line = 1;
    column = 0;

    // Set up the buffers for data and names
    dataBufferPos = 0;
    dataBuffer = new char[DATA_BUFFER_INITIAL];
    nameBufferPos = 0;
    nameBuffer = new char[NAME_BUFFER_INITIAL];

    // Set up the DTD hash tables
    elementInfo = new HashMap();
    entityInfo = new HashMap();
    notationInfo = new HashMap();
    skippedPE = false;

    // Set up the variables for the current
    // element context.
    currentElement = null;
    currentElementContent = CONTENT_UNDECLARED;

    // Set up the input variables
    sourceType = INPUT_NONE;
    inputStack = new LinkedList();
    entityStack = new LinkedList();
    externalEntity = null;
    tagAttributePos = 0;
    tagAttributes = new String[100];
    rawReadBuffer = new byte[READ_BUFFER_MAX];
    readBufferOverflow = -1;

    scratch = new InputSource();

    inLiteral = false;
    expandPE = false;
    peIsError = false;

    doReport = false;

    inCDATA = false;

    symbolTable = new Object[SYMBOL_TABLE_LENGTH][];
  }

  static class ExternalIdentifiers
  {

    String publicId;
    String systemId;
    String baseUri;

    ExternalIdentifiers()
    {
    }

    ExternalIdentifiers(String publicId, String systemId, String baseUri)
    {
      this.publicId = publicId;
      this.systemId = systemId;
      this.baseUri = baseUri;
    }

  }

  static class EntityInfo
  {

    int type;
    ExternalIdentifiers ids;
    String value;
    String notationName;

  }

  static class AttributeDecl
  {

    String type;
    String value;
    int valueType;
    String enumeration;
    String defaultValue;

  }

  static class ElementDecl
  {

    int contentType;
    String contentModel;
    HashMap attributes;

  }

  static class Input
  {

    int sourceType;
    URLConnection externalEntity;
    char[] readBuffer;
    int readBufferPos;
    int readBufferLength;
    int line;
    int encoding;
    int readBufferOverflow;
    InputStream is;
    int currentByteCount;
    int column;
    Reader reader;

  }

}
