/* 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, new Character(textFound).toString(), 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",
              new Integer(value).toString(), 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",
              new Integer(value).toString(), 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.
loop:
    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, new Character(delim).toString());
      }
    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, new Character(delim).toString());
      }
  }
  
  /**
   * 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, new Character(c).toString());
      }
  }

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

