/* XMLParser.java -- 
   Copyright (C) 2005  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.stream;

import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLReporter;
import javax.xml.stream.XMLResolver;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import gnu.java.net.CRLFInputStream;
import gnu.classpath.debug.TeeInputStream;
import gnu.classpath.debug.TeeReader;

/**
 * An XML parser.
 * This parser supports the following additional StAX properties:
 * <table>
 * <tr><td>gnu.xml.stream.stringInterning</td>
 * <td>Boolean</td>
 * <td>Indicates whether markup strings will be interned</td></tr>
 * <tr><td>gnu.xml.stream.xmlBase</td>
 * <td>Boolean</td>
 * <td>Indicates whether XML Base processing will be performed</td></tr>
 * <tr><td>gnu.xml.stream.baseURI</td>
 * <td>String</td>
 * <td>Returns the base URI of the current event</td></tr>
 * </table>
 *
 * @see http://www.w3.org/TR/REC-xml/
 * @see http://www.w3.org/TR/xml11/
 * @see http://www.w3.org/TR/REC-xml-names
 * @see http://www.w3.org/TR/xml-names11
 * @see http://www.w3.org/TR/xmlbase/
 * 
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public class XMLParser
  implements XMLStreamReader, NamespaceContext
{

  // -- parser state machine states --
  private static final int INIT = 0; // start state
  private static final int PROLOG = 1; // in prolog
  private static final int CONTENT = 2; // in content
  private static final int EMPTY_ELEMENT = 3; // empty element state
  private static final int MISC = 4; // in Misc (after root element)

  // -- parameters for parsing literals --
  private final static int LIT_ENTITY_REF = 2;
  private final static int LIT_NORMALIZE = 4;
  private final static int LIT_ATTRIBUTE = 8;
  private final static int LIT_DISABLE_PE = 16;
  private final static int LIT_DISABLE_CREF = 32;
  private final static int LIT_DISABLE_EREF = 64;
  private final static int LIT_PUBID = 256;

  // -- types of attribute values --
  final static int ATTRIBUTE_DEFAULT_UNDECLARED = 30;
  final static int ATTRIBUTE_DEFAULT_SPECIFIED = 31;
  final static int ATTRIBUTE_DEFAULT_IMPLIED = 32;
  final static int ATTRIBUTE_DEFAULT_REQUIRED = 33;
  final static int ATTRIBUTE_DEFAULT_FIXED = 34;

  // -- additional event types --
  final static int START_ENTITY = 50;
  final static int END_ENTITY = 51;

  /**
   * The current input.
   */
  private Input input;

  /**
   * Stack of inputs representing XML general entities.
   * The input representing the XML input stream or reader is always the
   * first element in this stack.
   */
  private LinkedList inputStack = new LinkedList();

  /**
   * Stack of start-entity events to be reported.
   */
  private LinkedList startEntityStack = new LinkedList();

  /**
   * Stack of end-entity events to be reported.
   */
  private LinkedList endEntityStack = new LinkedList();
  
  /**
   * Current parser state within the main state machine.
   */
  private int state = INIT;

  /**
   * The (type of the) current event.
   */
  private int event;

  /**
   * Whether we are looking ahead. Used by hasNext.
   */
  private boolean lookahead;

  /**
   * The element name stack. The first element in this stack will be the
   * root element.
   */
  private LinkedList stack = new LinkedList();

  /**
   * Stack of namespace contexts. These are maps specifying prefix-to-URI
   * mappings. The first element in this stack is the most recent namespace
   * context (i.e. the other way around from the element name stack).
   */
  private LinkedList namespaces = new LinkedList();

  /**
   * The base-URI stack. This holds the base URI context for each element.
   * The first element in this stack is the most recent context (i.e. the
   * other way around from the element name stack).
   */
  private LinkedList bases = new LinkedList();

  /**
   * The list of attributes for the current element, in the order defined in
   * the XML stream.
   */
  private ArrayList attrs = new ArrayList();

  /**
   * Buffer for text and character data.
   */
  private StringBuffer buf = new StringBuffer();

  /**
   * Buffer for NMTOKEN strings (markup).
   */
  private StringBuffer nmtokenBuf = new StringBuffer();

  /**
   * Buffer for string literals. (e.g. attribute values)
   */
  private StringBuffer literalBuf = new StringBuffer();

  /**
   * Temporary Unicode character buffer used during character data reads.
   */
  private int[] tmpBuf = new int[1024];
  
  /**
   * The element content model for the current element.
   */
  private ContentModel currentContentModel;

  /**
   * The validation stack. This holds lists of the elements seen for each
   * element, in order to determine whether the names and order of these
   * elements match the content model for the element. The last entry in
   * this stack represents the current element.
   */
  private LinkedList validationStack;

  /**
   * These sets contain the IDs and the IDREFs seen in the document, to
   * ensure that IDs are unique and that each IDREF refers to an ID in the
   * document.
   */
  private HashSet ids, idrefs;

  /**
   * The target and data associated with the current processing instruction
   * event.
   */
  private String piTarget, piData;

  /**
   * The XML version declared in the XML declaration.
   */
  private String xmlVersion;

  /**
   * The encoding declared in the XML declaration.
   */
  private String xmlEncoding;

  /**
   * The standalone value declared in the XML declaration.
   */
  private Boolean xmlStandalone;

  /**
   * The document type definition.
   */
  Doctype doctype;

  /**
   * State variables for determining parameter-entity expansion.
   */
  private boolean expandPE, peIsError;

  /**
   * Whether this is a validating parser.
   */
  private final boolean validating;

  /**
   * Whether strings representing markup will be interned.
   */
  private final boolean stringInterning;

  /**
   * If true, CDATA sections will be merged with adjacent text nodes into a
   * single event.
   */
  private final boolean coalescing;

  /**
   * Whether to replace general entity references with their replacement
   * text automatically during parsing.
   * Otherwise entity-reference events will be issued.
   */
  private final boolean replaceERefs;

  /**
   * Whether to support external entities.
   */
  private final boolean externalEntities;

  /**
   * Whether to support DTDs.
   */
  private final boolean supportDTD;

  /**
   * Whether to support XML namespaces. If true, namespace information will
   * be available. Otherwise namespaces will simply be reported as ordinary
   * attributes.
   */
  private final boolean namespaceAware;

  /**
   * Whether to support XML Base. If true, URIs specified in xml:base
   * attributes will be honoured when resolving external entities.
   */
  private final boolean baseAware;

  /**
   * Whether to report extended event types (START_ENTITY and END_ENTITY)
   * in addition to the standard event types. Used by the SAX parser.
   */
  private final boolean extendedEventTypes;

  /**
   * The reporter to receive parsing warnings.
   */
  final XMLReporter reporter;

  /**
   * Callback interface for resolving external entities.
   */
  final XMLResolver resolver;

  // -- Constants for testing the next kind of markup event --
  private static final String TEST_START_ELEMENT = "<";
  private static final String TEST_END_ELEMENT = "</";
  private static final String TEST_COMMENT = "<!--";
  private static final String TEST_PI = "<?";
  private static final String TEST_CDATA = "<![CDATA[";
  private static final String TEST_XML_DECL = "<?xml";
  private static final String TEST_DOCTYPE_DECL = "<!DOCTYPE";
  private static final String TEST_ELEMENT_DECL = "<!ELEMENT";
  private static final String TEST_ATTLIST_DECL = "<!ATTLIST";
  private static final String TEST_ENTITY_DECL = "<!ENTITY";
  private static final String TEST_NOTATION_DECL = "<!NOTATION";
  private static final String TEST_KET = ">";
  private static final String TEST_END_COMMENT = "--";
  private static final String TEST_END_PI = "?>";
  private static final String TEST_END_CDATA = "]]>";

  /**
   * The general entities predefined by the XML specification.
   */
  private static final LinkedHashMap PREDEFINED_ENTITIES = new LinkedHashMap();
  static
  {
    PREDEFINED_ENTITIES.put("amp", "&");
    PREDEFINED_ENTITIES.put("lt", "<");
    PREDEFINED_ENTITIES.put("gt", ">");
    PREDEFINED_ENTITIES.put("apos", "'");
    PREDEFINED_ENTITIES.put("quot", "\"");
  }

  /**
   * Creates a new XML parser for the given input stream.
   * This constructor should be used where possible, as it allows the
   * encoding of the XML data to be correctly determined from the stream.
   * @param in the input stream
   * @param systemId the URL from which the input stream was retrieved
   * (necessary if there are external entities to be resolved)
   * @param validating if the parser is to be a validating parser
   * @param namespaceAware if the parser should support XML Namespaces
   * @param coalescing if CDATA sections should be merged into adjacent text
   * nodes
   * @param replaceERefs if entity references should be automatically
   * replaced by their replacement text (otherwise they will be reported as
   * entity-reference events)
   * @param externalEntities if external entities should be loaded
   * @param supportDTD if support for the XML DTD should be enabled
   * @param baseAware if the parser should support XML Base to resolve
   * external entities
   * @param stringInterning whether strings will be interned during parsing
   * @param reporter the reporter to receive warnings during processing
   * @param resolver the callback interface used to resolve external
   * entities
   */
  public XMLParser(InputStream in, String systemId,
                   boolean validating,
                   boolean namespaceAware,
                   boolean coalescing,
                   boolean replaceERefs,
                   boolean externalEntities,
                   boolean supportDTD,
                   boolean baseAware,
                   boolean stringInterning,
                   boolean extendedEventTypes,
                   XMLReporter reporter,
                   XMLResolver resolver)
  {
    this.validating = validating;
    this.namespaceAware = namespaceAware;
    this.coalescing = coalescing;
    this.replaceERefs = replaceERefs;
    this.externalEntities = externalEntities;
    this.supportDTD = supportDTD;
    this.baseAware = baseAware;
    this.stringInterning = stringInterning;
    this.extendedEventTypes = extendedEventTypes;
    this.reporter = reporter;
    this.resolver = resolver;
    if (validating)
      {
        validationStack = new LinkedList();
        ids = new HashSet();
        idrefs = new HashSet();
      }
    String debug = System.getProperty("gnu.xml.debug.input");
    if (debug != null)
      {
        try
          {
            File file = File.createTempFile(debug, ".xml");
            in = new TeeInputStream(in, new FileOutputStream(file));
          }
        catch (IOException e)
          {
            RuntimeException e2 = new RuntimeException();
            e2.initCause(e);
            throw e2;
          }
      }
    pushInput(new Input(in, null, null, systemId, null, null, false, true));
  }

  /**
   * Creates a new XML parser for the given character stream.
   * This constructor is only available for compatibility with the JAXP
   * APIs, which permit XML to be parsed from a character stream. Because
   * the encoding specified by the character stream may conflict with that
   * specified in the XML declaration, this method should be avoided where
   * possible.
   * @param in the input stream
   * @param systemId the URL from which the input stream was retrieved
   * (necessary if there are external entities to be resolved)
   * @param validating if the parser is to be a validating parser
   * @param namespaceAware if the parser should support XML Namespaces
   * @param coalescing if CDATA sections should be merged into adjacent text
   * nodes
   * @param replaceERefs if entity references should be automatically
   * replaced by their replacement text (otherwise they will be reported as
   * entity-reference events)
   * @param externalEntities if external entities should be loaded
   * @param supportDTD if support for the XML DTD should be enabled
   * @param baseAware if the parser should support XML Base to resolve
   * external entities
   * @param stringInterning whether strings will be interned during parsing
   * @param reporter the reporter to receive warnings during processing
   * @param resolver the callback interface used to resolve external
   * entities
   */
  public XMLParser(Reader reader, String systemId,
                   boolean validating,
                   boolean namespaceAware,
                   boolean coalescing,
                   boolean replaceERefs,
                   boolean externalEntities,
                   boolean supportDTD,
                   boolean baseAware,
                   boolean stringInterning,
                   boolean extendedEventTypes,
                   XMLReporter reporter,
                   XMLResolver resolver)
  {
    this.validating = validating;
    this.namespaceAware = namespaceAware;
    this.coalescing = coalescing;
    this.replaceERefs = replaceERefs;
    this.externalEntities = externalEntities;
    this.supportDTD = supportDTD;
    this.baseAware = baseAware;
    this.stringInterning = stringInterning;
    this.extendedEventTypes = extendedEventTypes;
    this.reporter = reporter;
    this.resolver = resolver;
    if (validating)
      {
        validationStack = new LinkedList();
        ids = new HashSet();
        idrefs = new HashSet();
      }
    String debug = System.getProperty("gnu.xml.debug.input");
    if (debug != null)
      {
        try
          {
            File file = File.createTempFile(debug, ".xml");
            reader = new TeeReader(reader, new FileWriter(file));
          }
        catch (IOException e)
          {
            RuntimeException e2 = new RuntimeException();
            e2.initCause(e);
            throw e2;
          }
      }
    pushInput(new Input(null, reader, null, systemId, null, null, false, true));
  }

  // -- NamespaceContext --

  public String getNamespaceURI(String prefix)
  {
    if (XMLConstants.XML_NS_PREFIX.equals(prefix))
      return XMLConstants.XML_NS_URI;
    if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix))
      return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
    for (Iterator i = namespaces.iterator(); i.hasNext(); )
      {
        LinkedHashMap ctx = (LinkedHashMap) i.next();
        String namespaceURI = (String) ctx.get(prefix);
        if (namespaceURI != null)
          return namespaceURI;
      }
    return null;
  }

  public String getPrefix(String namespaceURI)
  {
    if (XMLConstants.XML_NS_URI.equals(namespaceURI))
      return XMLConstants.XML_NS_PREFIX;
    if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI))
      return XMLConstants.XMLNS_ATTRIBUTE;
    for (Iterator i = namespaces.iterator(); i.hasNext(); )
      {
        LinkedHashMap ctx = (LinkedHashMap) i.next();
        if (ctx.containsValue(namespaceURI))
          {
            for (Iterator j = ctx.entrySet().iterator(); j.hasNext(); )
              {
                Map.Entry entry = (Map.Entry) i.next();
                String uri = (String) entry.getValue();
                if (uri.equals(namespaceURI))
                  return (String) entry.getKey();
              }
          }
      }
    return null;
  }

  public Iterator getPrefixes(String namespaceURI)
  {
    if (XMLConstants.XML_NS_URI.equals(namespaceURI))
      return Collections.singleton(XMLConstants.XML_NS_PREFIX).iterator();
    if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI))
      return Collections.singleton(XMLConstants.XMLNS_ATTRIBUTE).iterator();
    LinkedList acc = new LinkedList();
    for (Iterator i = namespaces.iterator(); i.hasNext(); )
      {
        LinkedHashMap ctx = (LinkedHashMap) i.next();
        if (ctx.containsValue(namespaceURI))
          {
            for (Iterator j = ctx.entrySet().iterator(); j.hasNext(); )
              {
                Map.Entry entry = (Map.Entry) i.next();
                String uri = (String) entry.getValue();
                if (uri.equals(namespaceURI))
                  acc.add(entry.getKey());
              }
          }
      }
    return acc.iterator();
  }

  // -- XMLStreamReader --

  public void close()
    throws XMLStreamException
  {
    stack = null;
    namespaces = null;
    bases = null;
    buf = null;
    attrs = null;
    doctype = null;

    inputStack = null;
    validationStack = null;
    ids = null;
    idrefs = null;
  }

  public NamespaceContext getNamespaceContext()
  {
    return this;
  }

  public int getAttributeCount()
  {
    return attrs.size();
  }

  public String getAttributeLocalName(int index)
  {
    Attribute a = (Attribute) attrs.get(index);
    return a.localName;
  }

  public String getAttributeNamespace(int index)
  {
    String prefix = getAttributePrefix(index);
    return getNamespaceURI(prefix);
  }

  public String getAttributePrefix(int index)
  {
    Attribute a = (Attribute) attrs.get(index);
    return a.prefix;
  }

  public QName getAttributeName(int index)
  {
    Attribute a = (Attribute) attrs.get(index);
    String namespaceURI = getNamespaceURI(a.prefix);
    return new QName(namespaceURI, a.localName, a.prefix);
  }

  public String getAttributeType(int index)
  {
    Attribute a = (Attribute) attrs.get(index);
    return a.type;
  }

  private String getAttributeType(String elementName, String attName)
  {
    if (doctype != null)
      {
        AttributeDecl att = doctype.getAttributeDecl(elementName, attName);
        if (att != null)
          return att.type;
      }
    return "CDATA";
  }

  public String getAttributeValue(int index)
  {
    Attribute a = (Attribute) attrs.get(index);
    return a.value;
  }

  public String getAttributeValue(String namespaceURI, String localName)
  {
    for (Iterator i = attrs.iterator(); i.hasNext(); )
      {
        Attribute a = (Attribute) i.next();
        if (a.localName.equals(localName))
          {
            String uri = getNamespaceURI(a.prefix);
            if ((uri == null && namespaceURI == null) ||
                (uri != null && uri.equals(namespaceURI)))
              return a.value;
          }
      }
    return null;
  }

  boolean isAttributeDeclared(int index)
  {
    if (doctype == null)
      return false;
    Attribute a = (Attribute) attrs.get(index);
    String qn = ("".equals(a.prefix)) ? a.localName :
      a.prefix + ":" + a.localName;
    String elementName = buf.toString();
    return doctype.isAttributeDeclared(elementName, qn);
  }
  
  public String getCharacterEncodingScheme()
  {
    return xmlEncoding;
  }

  public String getElementText()
    throws XMLStreamException
  {
    if (event != XMLStreamConstants.START_ELEMENT)
      throw new XMLStreamException("current event must be START_ELEMENT");
    StringBuffer elementText = new StringBuffer();
    int depth = stack.size();
    while (event != XMLStreamConstants.END_ELEMENT || stack.size() > depth)
      {
        switch (next())
          {
          case XMLStreamConstants.CHARACTERS:
          case XMLStreamConstants.SPACE:
            elementText.append(buf.toString());
          }
      }
    return elementText.toString();
  }

  public String getEncoding()
  {
    return (input.inputEncoding == null) ? "UTF-8" : input.inputEncoding;
  }

  public int getEventType()
  {
    return event;
  }

  public String getLocalName()
  {
    switch (event)
      {
      case XMLStreamConstants.START_ELEMENT:
      case XMLStreamConstants.END_ELEMENT:
        String qName = buf.toString();
        int ci = qName.indexOf(':');
        return (ci == -1) ? qName : qName.substring(ci + 1);
      default:
        return null;
      }
  }

  public Location getLocation()
  {
    return input;
  }

  public QName getName()
  {
    switch (event)
      {
      case XMLStreamConstants.START_ELEMENT:
      case XMLStreamConstants.END_ELEMENT:
        String qName = buf.toString();
        int ci = qName.indexOf(':');
        String localName = (ci == -1) ? qName : qName.substring(ci + 1);
        String prefix = (ci == -1) ?
          (namespaceAware ? XMLConstants.DEFAULT_NS_PREFIX : null) :
          qName.substring(0, ci);
        String namespaceURI = getNamespaceURI(prefix);
        return new QName(namespaceURI, localName, prefix);
      default:
        return null;
      }
  }

  public int getNamespaceCount()
  {
    if (!namespaceAware || namespaces.isEmpty())
      return 0;
    switch (event)
      {
      case XMLStreamConstants.START_ELEMENT:
      case XMLStreamConstants.END_ELEMENT:
        LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();
        return ctx.size();
      default:
        return 0;
      }
  }

  public String getNamespacePrefix(int index)
  {
    LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();
    int count = 0;
    for (Iterator i = ctx.keySet().iterator(); i.hasNext(); )
      {
        String prefix = (String) i.next();
        if (count++ == index)
          return prefix;
      }
    return null;
  }

  public String getNamespaceURI()
  {
    switch (event)
      {
      case XMLStreamConstants.START_ELEMENT:
      case XMLStreamConstants.END_ELEMENT:
        String qName = buf.toString();
        int ci = qName.indexOf(':');
        if (ci == -1)
          return null;
        String prefix = qName.substring(0, ci);
        return getNamespaceURI(prefix);
      default:
        return null;
      }
  }

  public String getNamespaceURI(int index)
  {
    LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();
    int count = 0;
    for (Iterator i = ctx.values().iterator(); i.hasNext(); )
      {
        String uri = (String) i.next();
        if (count++ == index)
          return uri;
      }
    return null;
  }

  public String getPIData()
  {
    return piData;
  }

  public String getPITarget()
  {
    return piTarget;
  }

  public String getPrefix()
  {
    switch (event)
      {
      case XMLStreamConstants.START_ELEMENT:
      case XMLStreamConstants.END_ELEMENT:
        String qName = buf.toString();
        int ci = qName.indexOf(':');
        return (ci == -1) ?
          (namespaceAware ? XMLConstants.DEFAULT_NS_PREFIX : null) :
          qName.substring(0, ci);
      default:
        return null;
      }
  }

  public Object getProperty(String name)
    throws IllegalArgumentException
  {
    if (name == null)
      throw new IllegalArgumentException("name is null");
    if (XMLInputFactory.ALLOCATOR.equals(name))
      return null;
    if (XMLInputFactory.IS_COALESCING.equals(name))
      return coalescing ? Boolean.TRUE : Boolean.FALSE;
    if (XMLInputFactory.IS_NAMESPACE_AWARE.equals(name))
      return namespaceAware ? Boolean.TRUE : Boolean.FALSE;
    if (XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES.equals(name))
      return replaceERefs ? Boolean.TRUE : Boolean.FALSE;
    if (XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES.equals(name))
      return externalEntities ? Boolean.TRUE : Boolean.FALSE;
    if (XMLInputFactory.IS_VALIDATING.equals(name))
      return Boolean.FALSE;
    if (XMLInputFactory.REPORTER.equals(name))
      return reporter;
    if (XMLInputFactory.RESOLVER.equals(name))
      return resolver;
    if (XMLInputFactory.SUPPORT_DTD.equals(name))
      return supportDTD ? Boolean.TRUE : Boolean.FALSE;
    if ("gnu.xml.stream.stringInterning".equals(name))
      return stringInterning ? Boolean.TRUE : Boolean.FALSE;
    if ("gnu.xml.stream.xmlBase".equals(name))
      return baseAware ? Boolean.TRUE : Boolean.FALSE;
    if ("gnu.xml.stream.baseURI".equals(name))
      return getXMLBase();
    return null;
  }

  public String getText()
  {
    return buf.toString();
  }

  public char[] getTextCharacters()
  {
    return buf.toString().toCharArray();
  }

  public int getTextCharacters(int sourceStart, char[] target,
                               int targetStart, int length)
    throws XMLStreamException
  {
    length = Math.min(sourceStart + buf.length(), length);
    int sourceEnd = sourceStart + length;
    buf.getChars(sourceStart, sourceEnd, target, targetStart);
    return length;
  }

  public int getTextLength()
  {
    return buf.length();
  }

  public int getTextStart()
  {
    return 0;
  }

  public String getVersion()
  {
    return (xmlVersion == null) ? "1.0" : xmlVersion;
  }

  public boolean hasName()
  {
    switch (event)
      {
      case XMLStreamConstants.START_ELEMENT:
      case XMLStreamConstants.END_ELEMENT:
        return true;
      default:
        return false;
      }
  }

  public boolean hasText()
  {
    switch (event)
      {
      case XMLStreamConstants.CHARACTERS:
      case XMLStreamConstants.SPACE:
        return true;
      default:
        return false;
      }
  }

  public boolean isAttributeSpecified(int index)
  {
    Attribute a = (Attribute) attrs.get(index);
    return a.specified;
  }

  public boolean isCharacters()
  {
    return (event == XMLStreamConstants.CHARACTERS);
  }

  public boolean isEndElement()
  {
    return (event == XMLStreamConstants.END_ELEMENT);
  }

  public boolean isStandalone()
  {
    return Boolean.TRUE.equals(xmlStandalone);
  }

  public boolean isStartElement()
  {
    return (event == XMLStreamConstants.START_ELEMENT);
  }

  public boolean isWhiteSpace()
  {
    return (event == XMLStreamConstants.SPACE);
  }

  public int nextTag()
    throws XMLStreamException
  {
    do
      {
        switch (next())
          {
          case XMLStreamConstants.START_ELEMENT:
          case XMLStreamConstants.END_ELEMENT:
          case XMLStreamConstants.CHARACTERS:
          case XMLStreamConstants.SPACE:
          case XMLStreamConstants.COMMENT:
          case XMLStreamConstants.PROCESSING_INSTRUCTION:
            break;
          default:
            throw new XMLStreamException("Unexpected event type: " + event);
          }
      }
    while (event != XMLStreamConstants.START_ELEMENT &&
           event != XMLStreamConstants.END_ELEMENT);
    return event;
  }

  public void require(int type, String namespaceURI, String localName)
    throws XMLStreamException
  {
    if (event != type)
      throw new XMLStreamException("Current event type is " + event);
    if (event == XMLStreamConstants.START_ELEMENT ||
        event == XMLStreamConstants.END_ELEMENT)
      {
        String ln = getLocalName();
        if (!ln.equals(localName))
          throw new XMLStreamException("Current local-name is " + ln);
        String uri = getNamespaceURI();
        if ((uri == null && namespaceURI != null) ||
            (uri != null && !uri.equals(namespaceURI)))
          throw new XMLStreamException("Current namespace URI is " + uri);
      }
  }

  public boolean standaloneSet()
  {
    return (xmlStandalone != null);
  }

  public boolean hasNext()
    throws XMLStreamException
  {
    if (event == XMLStreamConstants.END_DOCUMENT)
      return false;
    if (!lookahead)
      {
        next();
        lookahead = true;
      }
    return event != -1;
  }
  
  public int next()
    throws XMLStreamException
  {
    if (lookahead)
      {
        lookahead = false;
        return event;
      }
    if (event == XMLStreamConstants.END_ELEMENT)
      {
        // Pop namespace context
        if (namespaceAware && !namespaces.isEmpty())
          namespaces.removeFirst();
        // Pop base context
        if (baseAware && !bases.isEmpty())
          bases.removeFirst();
      }
    if (!startEntityStack.isEmpty())
      {
        String entityName = (String) startEntityStack.removeFirst();
        buf.setLength(0);
        buf.append(entityName);
        event = START_ENTITY;
        return extendedEventTypes ? event : next();
      }
    else if (!endEntityStack.isEmpty())
      {
        String entityName = (String) endEntityStack.removeFirst();
        buf.setLength(0);
        buf.append(entityName);
        event = END_ENTITY;
        return extendedEventTypes ? event : next();
      }
    try
      {
        if (!input.initialized)
          input.init();
        switch (state)
          {
          case CONTENT:
            if (tryRead(TEST_END_ELEMENT))
              {
                readEndElement();
                if (stack.isEmpty())
                  state = MISC;
                event = XMLStreamConstants.END_ELEMENT;
              }
            else if (tryRead(TEST_COMMENT))
              {
                readComment(false);
                event = XMLStreamConstants.COMMENT;
              }
            else if (tryRead(TEST_PI))
              {
                readPI(false);
                event = XMLStreamConstants.PROCESSING_INSTRUCTION;
              }
            else if (tryRead(TEST_CDATA))
              {
                readCDSect();
                event = XMLStreamConstants.CDATA;
              }
            else if (tryRead(TEST_START_ELEMENT))
              {
                state = readStartElement();
                event = XMLStreamConstants.START_ELEMENT;
              }
            else
              {
                // Check for character reference or predefined entity
                mark(8);
                int c = readCh();
                if (c == 0x26) // '&'
                  {
                    c = readCh();
                    if (c == 0x23) // '#'
                      {
                        reset();
                        event = readCharData(null);
                      }
                    else
                      {
                        // entity reference
                        reset();
                        readCh(); // &
                        readReference();
                        String ref = buf.toString();
                        String text = (String) PREDEFINED_ENTITIES.get(ref);
                        if (text != null)
                          {
                            event = readCharData(text);
                          }
                        else if (replaceERefs && !isUnparsedEntity(ref))
                          {
                            // this will report a start-entity event
                            boolean external = false;
                            if (doctype != null)
                              {
                                Object entity = doctype.getEntity(ref);
                                if (entity instanceof ExternalIds)
                                  external = true;
                              }
                            expandEntity(ref, false, external);
                            event = next();
                          }
                        else
                          {
                            event = XMLStreamConstants.ENTITY_REFERENCE;
                          }
                      }
                  }
                else
                  {
                    reset();
                    event = readCharData(null);
                    if (validating && doctype != null)
                      validatePCData(buf.toString());
                  }
              }
            break;
          case EMPTY_ELEMENT:
            String elementName = (String) stack.removeLast();
            buf.setLength(0);
            buf.append(elementName);
            state = stack.isEmpty() ? MISC : CONTENT;
            event = XMLStreamConstants.END_ELEMENT;
            if (validating && doctype != null)
              endElementValidationHook();
            break;
          case INIT: // XMLDecl?
            if (tryRead(TEST_XML_DECL))
              readXMLDecl();
            input.finalizeEncoding();
            event = XMLStreamConstants.START_DOCUMENT;
            state = PROLOG;
            break;
          case PROLOG: // Misc* (doctypedecl Misc*)?
            skipWhitespace();
            if (doctype == null && tryRead(TEST_DOCTYPE_DECL))
              {
                readDoctypeDecl();
                event = XMLStreamConstants.DTD;
              }
            else if (tryRead(TEST_COMMENT))
              {
                readComment(false);
                event = XMLStreamConstants.COMMENT;
              }
            else if (tryRead(TEST_PI))
              {
                readPI(false);
                event = XMLStreamConstants.PROCESSING_INSTRUCTION;
              }
            else if (tryRead(TEST_START_ELEMENT))
              {
                state = readStartElement();
                event = XMLStreamConstants.START_ELEMENT;
              }
            else
              {
                int c = readCh();
                error("no root element: U+" + Integer.toHexString(c));
              }
            break;
          case MISC: // Comment | PI | S
            skipWhitespace();
            if (tryRead(TEST_COMMENT))
              {
                readComment(false);
                event = XMLStreamConstants.COMMENT;
              }
            else if (tryRead(TEST_PI))
              {
                readPI(false);
                event = XMLStreamConstants.PROCESSING_INSTRUCTION;
              }
            else
              {
                if (event == XMLStreamConstants.END_DOCUMENT)
                  throw new NoSuchElementException();
                int c = readCh();
                if (c != -1)
                  error("Only comments and PIs may appear after " +
                        "the root element");
                event = XMLStreamConstants.END_DOCUMENT;
              }
            break;
          default:
            event = -1;
          }
        return event;
      }
    catch (IOException e)
      {
        XMLStreamException e2 = new XMLStreamException();
        e2.initCause(e);
        throw e2;
      }
  }

  // package private

  /**
   * Returns the current element name.
   */
  String getCurrentElement()
  {
    return (String) stack.getLast();
  }

  // private

  private void mark(int limit)
    throws IOException
  {
    input.mark(limit);
  }

  private void reset()
    throws IOException
  {
    input.reset();
  }

  private int read()
    throws IOException
  {
    return input.read();
  }

  private int read(int[] b, int off, int len)
    throws IOException
  {
    return input.read(b, off, len);
  }
  
  /**
   * Parsed character read.
   */
  private int readCh()
    throws IOException, XMLStreamException
  {
    int c = read();
    if (expandPE && c == 0x25) // '%'
      {
        if (peIsError)
          error("PE reference within decl in internal subset.");
        expandPEReference();
        return readCh();
      }
    return c;
  }

  /**
   * Reads the next character, ensuring it is the character specified.
   * @param delim the character to match
   * @exception XMLStreamException if the next character is not the
   * specified one
   */
  private void require(char delim)
    throws IOException, XMLStreamException
  {
    mark(1);
    int c = readCh();
    if (delim != c)
      {
        reset();
        error("required character (got U+" + Integer.toHexString(c) + ")",
              new Character(delim));
      }
  }

  /**
   * Reads the next few characters, ensuring they match the string specified.
   * @param delim the string to match
   * @exception XMLStreamException if the next characters do not match the
   * specified string
   */
  private void require(String delim)
    throws IOException, XMLStreamException
  {
    char[] chars = delim.toCharArray();
    int len = chars.length;
    mark(len);
    int off = 0;
    do
      {
        int l2 = read(tmpBuf, off, len - off);
        if (l2 == -1)
          {
            reset();
            error("EOF before required string", delim);
          }
        off += l2;
      }
    while (off < len);
    for (int i = 0; i < chars.length; i++)
      {
        if (chars[i] != tmpBuf[i])
          {
            reset();
            error("required string", delim);
          }
      }
  }

  /**
   * Try to read a single character. On failure, reset the stream.
   * @param delim the character to test
   * @return true if the character matched delim, false otherwise.
   */
  private boolean tryRead(char delim)
    throws IOException, XMLStreamException
  {
    mark(1);
    int c = readCh();
    if (delim != c)
      {
        reset();
        return false;
      }
    return true;
  }

  /**
   * Tries to read the specified characters.
   * If successful, the stream is positioned after the last character,
   * otherwise it is reset.
   * @param test the string to test
   * @return true if the characters matched the test string, false otherwise.
   */
  private boolean tryRead(String test)
    throws IOException
  {
    char[] chars = test.toCharArray();
    int len = chars.length;
    mark(len);
    int count = 0;
    int l2 = read(tmpBuf, 0, len);
    if (l2 == -1)
      {
        reset();
        return false;
      }
    count += l2;
    // check the characters we received first before doing additional reads
    for (int i = 0; i < count; i++)
      {
        if (chars[i] != tmpBuf[i])
          {
            reset();
            return false;
          }
      }
    while (count < len)
      {
        // force read
        int c = read();
        if (c == -1)
          {
            reset();
            return false;
          }
        tmpBuf[count] = (char) c;
        // check each character as it is read
        if (chars[count] != tmpBuf[count])
          {
            reset();
            return false;
          }
        count++;
      }
    return true;
  }

  /**
   * Reads characters until the specified test string is encountered.
   * @param delim the string delimiting the end of the characters
   */
  private void readUntil(String delim)
    throws IOException, XMLStreamException
  {
    int startLine = input.line;
    try
      {
        while (!tryRead(delim))
          {
            int c = readCh();
            if (c == -1)
              throw new EOFException();
            else if (input.xml11)
              {
                if (!isXML11Char(c) || isXML11RestrictedChar(c))
                  error("illegal XML 1.1 character",
                        "U+" + Integer.toHexString(c));
              }
            else if (!isChar(c))
              error("illegal XML character", 
                    "U+" + Integer.toHexString(c));
            buf.append(Character.toChars(c));
          }
      }
    catch (EOFException e)
      {
        error("end of input while looking for delimiter "+
              "(started on line " + startLine + ')', delim);
      }
  }

  /**
   * Reads any whitespace characters.
   * @return true if whitespace characters were read, false otherwise
   */
  private boolean tryWhitespace()
    throws IOException, XMLStreamException
  {
    boolean white;
    boolean ret = false;
    do
      {
        mark(1);
        int c = readCh();
        while (c == -1 && inputStack.size() > 1)
          {
            popInput();
            c = readCh();
          }
        white = (c == 0x20 || c == 0x09 || c == 0x0a || c == 0x0d);
        if (white)
          ret = true;
      }
    while (white);
    reset();
    return ret;
  }

  /**
   * Skip over any whitespace characters.
   */
  private void skipWhitespace()
    throws IOException, XMLStreamException
  {
    boolean white;
    do
      {
        mark(1);
        int c = readCh();
        while (c == -1 && inputStack.size() > 1)
          {
            popInput();
            c = readCh();
          }
        white = (c == 0x20 || c == 0x09 || c == 0x0a || c == 0x0d);
      }
    while (white);
    reset();
  }

  /**
   * Try to read as many whitespace characters as are available.
   * @exception XMLStreamException if no whitespace characters were seen
   */
  private void requireWhitespace()
    throws IOException, XMLStreamException
  {
    if (!tryWhitespace())
      error("whitespace required");
  }

  /**
   * Returns the current base URI for resolving external entities.
   */
  String getXMLBase()
  {
    if (baseAware)
      {
        for (Iterator i = bases.iterator(); i.hasNext(); )
          {
            String base = (String) i.next();
            if (base != null)
              return base;
          }
      }
    return input.systemId;
  }

  /**
   * Push the specified text input source.
   */
  private void pushInput(String name, String text, boolean report,
                         boolean normalize)
    throws IOException, XMLStreamException
  {
    // Check for recursion
    if (name != null && !"".equals(name))
      {
        for (Iterator i = inputStack.iterator(); i.hasNext(); )
          {
            Input ctx = (Input) i.next();
            if (name.equals(ctx.name))
              error("entities may not be self-recursive", name);
          }
      }
    else
      report = false;
    pushInput(new Input(null, new StringReader(text), input.publicId,
                        input.systemId, name, input.inputEncoding, report,
                        normalize));
  }

  /**
   * Push the specified external input source.
   */
  private void pushInput(String name, ExternalIds ids, boolean report,
                         boolean normalize)
    throws IOException, XMLStreamException
  {
    if (!externalEntities)
      return;
    String url = absolutize(input.systemId, ids.systemId);
    // Check for recursion
    for (Iterator i = inputStack.iterator(); i.hasNext(); )
      {
        Input ctx = (Input) i.next();
        if (url.equals(ctx.systemId))
          error("entities may not be self-recursive", url);
        if (name != null && !"".equals(name) && name.equals(ctx.name))
          error("entities may not be self-recursive", name);
      }
    if (name == null || "".equals(name))
      report = false;
    InputStream in = null;
    if (resolver != null)
      {
        Object obj = resolver.resolveEntity(ids.publicId, url, getXMLBase(),
                                            null);
        if (obj instanceof InputStream)
          in = (InputStream) obj;
      }
    if (in == null)
      in = resolve(url);
    if (in == null)
      error("unable to resolve external entity",
            (ids.systemId != null) ? ids.systemId : ids.publicId);
    pushInput(new Input(in, null, ids.publicId, url, name, null, report,
                        normalize));
    input.init();
    if (tryRead(TEST_XML_DECL))
      readTextDecl();
    input.finalizeEncoding();
  }

  /**
   * Push the specified input source (general entity) onto the input stack.
   */
  private void pushInput(Input input)
  {
    if (input.report)
      startEntityStack.addFirst(input.name);
    inputStack.addLast(input);
    if (this.input != null)
      input.xml11 = this.input.xml11;
    this.input = input;
  }

  /**
   * "Absolutize" a URL. This resolves a relative URL into an absolute one.
   * @param base the current base URL
   * @param href the (absolute or relative) URL to resolve
   */
  public static String absolutize(String base, String href)
    throws MalformedURLException
  {
    if (href == null)
      return null;
    int ci = href.indexOf(':');
    if (ci > 1 && isURLScheme(href.substring(0, ci)))
      {
        // href is absolute already
        return href;
      }
    if (base == null)
      base = "";
    else
      {
        int i = base.lastIndexOf('/');
        if (i != -1)
          base = base.substring(0, i + 1);
        else
          base = "";
      }
    if ("".equals(base))
      {
        // assume file URL relative to current directory
        base = System.getProperty("user.dir");
        if (base.charAt(0) == '/')
          base = base.substring(1);
        base = "file:///" + base.replace(File.separatorChar, '/');
        if (!base.endsWith("/"))
          base += "/";
      }
    return new URL(new URL(base), href).toString();
  }

  /**
   * Indicates whether the specified characters match the scheme portion of
   * a URL.
   * @see RFC 1738 section 2.1
   */
  private static boolean isURLScheme(String text)
  {
    int len = text.length();
    for (int i = 0; i < len; i++)
      {
        char c = text.charAt(i);
        if (c == '+' || c == '.' || c == '-')
          continue;
        if (c < 65 || (c > 90 && c < 97) || c > 122)
          return false;
      }
    return true;
  }

  /**
   * Returns an input stream for the given URL.
   */
  static InputStream resolve(String url)
    throws IOException
  {
    try
      {
        return new URL(url).openStream();
      }
    catch (MalformedURLException e)
      {
        return null;
      }
    catch (IOException e)
      {
        IOException e2 = new IOException("error resolving " + url);
        e2.initCause(e);
        throw e2;
      }
  }

  /**
   * Pops the current input source (general entity) off the stack.
   */
  private void popInput()
  {
    Input old = (Input) inputStack.removeLast();
    if (old.report)
      endEntityStack.addFirst(old.name);
    input = (Input) inputStack.getLast();
  }

  /**
   * Parse an entity text declaration.
   */
  private void readTextDecl()
    throws IOException, XMLStreamException
  {
    final int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;
    requireWhitespace();
    if (tryRead("version"))
      {
        readEq();
        String v = readLiteral(flags, false);
        if ("1.0".equals(v))
          input.xml11 = false;
        else if ("1.1".equals(v))
          {
            Input i1 = (Input) inputStack.getFirst();
            if (!i1.xml11)
              error("external entity specifies later version number");
            input.xml11 = true;
          }
        else
          throw new XMLStreamException("illegal XML version: " + v);
        requireWhitespace();
      }
    require("encoding");
    readEq();
    String enc = readLiteral(flags, false);
    skipWhitespace();
    require("?>");
    input.setInputEncoding(enc);
  }

  /**
   * Parse the XML declaration.
   */
  private void readXMLDecl()
    throws IOException, XMLStreamException
  {
    final int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;
    
    requireWhitespace();
    require("version");
    readEq();
    xmlVersion = readLiteral(flags, false);
    if ("1.0".equals(xmlVersion))
      input.xml11 = false;
    else if ("1.1".equals(xmlVersion))
      input.xml11 = true;
    else
      throw new XMLStreamException("illegal XML version: " + xmlVersion);
    
    boolean white = tryWhitespace();
    
    if (tryRead("encoding"))
      {
        if (!white)
          error("whitespace required before 'encoding='");
        readEq();
        xmlEncoding = readLiteral(flags, false);
        white = tryWhitespace();
      }
    
    if (tryRead("standalone"))
      {
        if (!white)
          error("whitespace required before 'standalone='");
        readEq();
        String standalone = readLiteral(flags, false);
        if ("yes".equals(standalone))
          xmlStandalone = Boolean.TRUE;
        else if ("no".equals(standalone))
          xmlStandalone = Boolean.FALSE;
        else
          error("standalone flag must be 'yes' or 'no'", standalone);
      }

    skipWhitespace();
    require("?>");
    if (xmlEncoding != null)
      input.setInputEncoding(xmlEncoding);
  }

  /**
   * Parse the DOCTYPE declaration.
   */
  private void readDoctypeDecl()
    throws IOException, XMLStreamException
  {
    if (!supportDTD)
      error("parser was configured not to support DTDs");
    requireWhitespace();
    String rootName = readNmtoken(true);
    skipWhitespace();
    ExternalIds ids = readExternalIds(false, true);
    doctype =
      this.new Doctype(rootName, ids.publicId, ids.systemId);
    
    // Parse internal subset first
    skipWhitespace();
    if (tryRead('['))
      {
        while (true)
          {
            expandPE = true;
            skipWhitespace();
            expandPE = false;
            if (tryRead(']'))
              break;
            else
              readMarkupdecl(false);
          }
      }
    skipWhitespace();
    require('>');

    // Parse external subset
    if (ids.systemId != null && externalEntities)
      {
        pushInput("", ">", false, false);
        pushInput("[dtd]", ids, true, true);
        // loop until we get back to ">"
        while (true)
          {
            expandPE = true;
            skipWhitespace();
            expandPE = false;
            mark(1);
            int c = readCh();
            if (c == 0x3e) // '>'
              break;
            else if (c == -1)
              popInput();
            else
              {
                reset();
                expandPE = true;
                readMarkupdecl(true);
                expandPE = true;
              }
          }
        if (inputStack.size() != 2)
          error("external subset has unmatched '>'");
        popInput();
      }
    checkDoctype();
    if (validating)
      validateDoctype();

    // Make rootName available for reading
    buf.setLength(0);
    buf.append(rootName);
  }

  /**
   * Checks the well-formedness of the DTD.
   */
  private void checkDoctype()
    throws XMLStreamException
  {
    // TODO check entity recursion
  }

  /**
   * Parse the markupdecl production.
   */
  private void readMarkupdecl(boolean inExternalSubset)
    throws IOException, XMLStreamException
  {
    boolean saved = expandPE;
    mark(1);
    require('<');
    reset();
    expandPE = false;
    if (tryRead(TEST_ELEMENT_DECL))
      {
        expandPE = saved;
        readElementDecl();
      }
    else if (tryRead(TEST_ATTLIST_DECL))
      {
        expandPE = saved;
        readAttlistDecl();
      }
    else if (tryRead(TEST_ENTITY_DECL))
      {
        expandPE = saved;
        readEntityDecl(inExternalSubset);
      }
    else if (tryRead(TEST_NOTATION_DECL))
      {
        expandPE = saved;
        readNotationDecl(inExternalSubset);
      }
    else if (tryRead(TEST_PI))
      {
        readPI(true);
        expandPE = saved;
      }
    else if (tryRead(TEST_COMMENT))
      {
        readComment(true);
        expandPE = saved;
      }
    else if (tryRead("<!["))
      {
        // conditional section
        expandPE = saved;
        if (inputStack.size() < 2)
          error("conditional sections illegal in internal subset");
        skipWhitespace();
        if (tryRead("INCLUDE"))
          {
            skipWhitespace();
            require('[');
            skipWhitespace();
            while (!tryRead("]]>"))
              {
                readMarkupdecl(inExternalSubset);
                skipWhitespace();
              }
          }
        else if (tryRead("IGNORE"))
          {
            skipWhitespace();
            require('[');
            expandPE = false;
            for (int nesting = 1; nesting > 0; )
              {
                int c = readCh();
                switch (c)
                  {
                  case 0x3c: // '<'
                    if (tryRead("!["))
                      nesting++;
                    break;
                  case 0x5d: // ']'
                    if (tryRead("]>"))
                      nesting--;
                    break;
                  case -1:
                    throw new EOFException();
                  }
              }
            expandPE = saved;
          }
        else
          error("conditional section must begin with INCLUDE or IGNORE");
      }
    else
      error("expected markup declaration");
  }

  /**
   * Parse the elementdecl production.
   */
  private void readElementDecl()
    throws IOException, XMLStreamException
  {
    requireWhitespace();
    boolean saved = expandPE;
    expandPE = (inputStack.size() > 1);
    String name = readNmtoken(true);
    expandPE = saved;
    requireWhitespace();
    readContentspec(name);
    skipWhitespace();
    require('>');
  }

  /**
   * Parse the contentspec production.
   */
  private void readContentspec(String elementName)
    throws IOException, XMLStreamException
  {
    if (tryRead("EMPTY"))
      doctype.addElementDecl(elementName, "EMPTY", new EmptyContentModel());
    else if (tryRead("ANY"))
      doctype.addElementDecl(elementName, "ANY", new AnyContentModel());
    else
      {
        ContentModel model;
        StringBuffer acc = new StringBuffer();
        require('(');
        acc.append('(');
        skipWhitespace();
        if (tryRead("#PCDATA"))
          {
            // mixed content
            acc.append("#PCDATA");
            MixedContentModel mm = new MixedContentModel();
            model = mm;
            skipWhitespace();
            if (tryRead(')'))
              {
                acc.append(")");
                if (tryRead('*'))
                  {
                    mm.min = 0;
                    mm.max = -1;
                  }
              }
            else
              {
                while (!tryRead(")"))
                  {
                    require('|');
                    acc.append('|');
                    skipWhitespace();
                    String name = readNmtoken(true);
                    acc.append(name);
                    mm.addName(name);
                    skipWhitespace();
                  }
                require('*');
                acc.append(")*");
                mm.min = 0;
                mm.max = -1;
              }
          }
        else
          model = readElements(acc);
        doctype.addElementDecl(elementName, acc.toString(), model);
      }
  }

  /**
   * Parses an element content model.
   */
  private ElementContentModel readElements(StringBuffer acc)
    throws IOException, XMLStreamException
  {
    int separator;
    ElementContentModel model = new ElementContentModel();
    
    // Parse first content particle
    skipWhitespace();
    model.addContentParticle(readContentParticle(acc));
    // End or separator
    skipWhitespace();
    int c = readCh();
    switch (c)
      {
      case 0x29: // ')'
        acc.append(')');
        mark(1);
        c = readCh();
        switch (c)
          {
          case 0x3f: // '?'
            acc.append('?');
            model.min = 0;
            model.max = 1;
            break;
          case 0x2a: // '*'
            acc.append('*');
            model.min = 0;
            model.max = -1;
            break;
          case 0x2b: // '+'
            acc.append('+');
            model.min = 1;
            model.max = -1;
            break;
          default:
            reset();
          }
        return model; // done
      case 0x7c: // '|'
        model.or = true;
        // fall through
      case 0x2c: // ','
        separator = c;
        acc.append(Character.toChars(c));
        break;
      default:
        error("bad separator in content model",
              "U+" + Integer.toHexString(c));
        return model;
      }
    // Parse subsequent content particles
    while (true)
      {
        skipWhitespace();
        model.addContentParticle(readContentParticle(acc));
        skipWhitespace();
        c = readCh();
        if (c == 0x29) // ')'
          {
            acc.append(')');
            break;
          }
        else if (c != separator)
          {
            error("bad separator in content model",
                  "U+" + Integer.toHexString(c));
            return model;
          }
        else
          acc.append(c);
      }
    // Check for occurrence indicator
    mark(1);
    c = readCh();
    switch (c)
      {
      case 0x3f: // '?'
        acc.append('?');
        model.min = 0;
        model.max = 1;
        break;
      case 0x2a: // '*'
        acc.append('*');
        model.min = 0;
        model.max = -1;
        break;
      case 0x2b: // '+'
        acc.append('+');
        model.min = 1;
        model.max = -1;
        break;
      default:
        reset();
      }
    return model;
  }

  /**
   * Parse a cp production.
   */
  private ContentParticle readContentParticle(StringBuffer acc)
    throws IOException, XMLStreamException
  {
    ContentParticle cp = new ContentParticle();
    if (tryRead('('))
      {
        acc.append('(');
        cp.content = readElements(acc);
      }
    else
      {
        String name = readNmtoken(true);
        acc.append(name);
        cp.content = name;
        mark(1);
        int c = readCh();
        switch (c)
          {
          case 0x3f: // '?'
            acc.append('?');
            cp.min = 0;
            cp.max = 1;
            break;
          case 0x2a: // '*'
            acc.append('*');
            cp.min = 0;
            cp.max = -1;
            break;
          case 0x2b: // '+'
            acc.append('+');
            cp.min = 1;
            cp.max = -1;
            break;
          default:
            reset();
          }
      }
    return cp;
  }

  /**
   * Parse an attribute-list definition.
   */
  private void readAttlistDecl()
    throws IOException, XMLStreamException
  {
    requireWhitespace();
    boolean saved = expandPE;
    expandPE = (inputStack.size() > 1);
    String elementName = readNmtoken(true);
    expandPE = saved;
    boolean white = tryWhitespace();
    while (!tryRead('>'))
      {
        if (!white)
          error("whitespace required before attribute definition");
        readAttDef(elementName);
        white = tryWhitespace();
      }
  }

  /**
   * Parse a single attribute definition.
   */
  private void readAttDef(String elementName)
    throws IOException, XMLStreamException
  {
    String name = readNmtoken(true);
    requireWhitespace();
    StringBuffer acc = new StringBuffer();
    HashSet values = new HashSet();
    String type = readAttType(acc, values);
    if (validating)
      {
        if ("ID".equals(type))
          {
            // VC: One ID per Element Type
            for (Iterator i = doctype.attlistIterator(elementName);
                 i.hasNext(); )
              {
                Map.Entry entry = (Map.Entry) i.next();
                AttributeDecl decl = (AttributeDecl) entry.getValue();
                if ("ID".equals(decl.type))
                  error("element types must not have more than one ID " +
                        "attribute");
              }
          }
        else if ("NOTATION".equals(type))
          {
            // VC: One Notation Per Element Type
            for (Iterator i = doctype.attlistIterator(elementName);
                 i.hasNext(); )
              {
                Map.Entry entry = (Map.Entry) i.next();
                AttributeDecl decl = (AttributeDecl) entry.getValue();
                if ("NOTATION".equals(decl.type))
                  error("element types must not have more than one NOTATION " +
                        "attribute");
              }
            // VC: No Notation on Empty Element
            ContentModel model = doctype.getElementModel(elementName);
            if (model != null && model.type == ContentModel.EMPTY)
              error("attributes of type NOTATION must not be declared on an " +
                    "element declared EMPTY");
          }
      }
    String enumer = null;
    if ("ENUMERATION".equals(type) || "NOTATION".equals(type))
      enumer = acc.toString();
    else
      values = null;
    requireWhitespace();
    readDefault(elementName, name, type, enumer, values);
  }

  /**
   * Parse an attribute type.
   */
  private String readAttType(StringBuffer acc, HashSet values)
    throws IOException, XMLStreamException
  {
    if (tryRead('('))
      {
        readEnumeration(false, acc, values);
        return "ENUMERATION";
      }
    else
      {
        String typeString = readNmtoken(true);
        if ("NOTATION".equals(typeString))
          {
            readNotationType(acc, values);
            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;
        else
          {
            error("illegal attribute type", typeString);
            return null;
          }
      }
  }

  /**
   * Parse an enumeration.
   */
  private void readEnumeration(boolean isNames, StringBuffer acc,
                               HashSet values)
    throws IOException, XMLStreamException
  {
    acc.append('(');
    // first token
    skipWhitespace();
    String token = readNmtoken(isNames);
    acc.append(token);
    values.add(token);
    // subsequent tokens
    skipWhitespace();
    while (!tryRead(')'))
      {
        require('|');
        acc.append('|');
        skipWhitespace();
        token = readNmtoken(isNames);
        // VC: No Duplicate Tokens
        if (validating && values.contains(token))
          error("duplicate token", token);
        acc.append(token);
        values.add(token);
        skipWhitespace();
      }
    acc.append(')');
  }

  /**
   * Parse a notation type for an attribute.
   */
  private void readNotationType(StringBuffer acc, HashSet values)
    throws IOException, XMLStreamException
  {
    requireWhitespace();
    require('(');
    readEnumeration(true, acc, values);
  }

  /**
   * Parse the default value for an attribute.
   */
  private void readDefault(String elementName, String name,
                           String type, String enumeration, HashSet values)
    throws IOException, XMLStreamException
  {
    int valueType = ATTRIBUTE_DEFAULT_SPECIFIED;
    int flags = LIT_ATTRIBUTE;
    String value = null, defaultType = null;
    boolean saved = expandPE;
    
    if (!"CDATA".equals(type))
      flags |= LIT_NORMALIZE;

    expandPE = false;
    if (tryRead('#'))
      {
        if (tryRead("FIXED"))
          {
            defaultType = "#FIXED";
            valueType = ATTRIBUTE_DEFAULT_FIXED;
            requireWhitespace();
            value = readLiteral(flags, false);
          }
        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, false);
    expandPE = saved;
    if (validating)
      {
        if ("ID".equals(type))
          {
            // VC: Attribute Default Value Syntactically Correct
            if (value != null && !isNmtoken(value, true))
              error("default value must match Name production", value);
            // VC: ID Attribute Default
            if (valueType != ATTRIBUTE_DEFAULT_REQUIRED &&
                valueType != ATTRIBUTE_DEFAULT_IMPLIED)
              error("ID attributes must have a declared default of " +
                    "#IMPLIED or #REQUIRED");
          }
        else if (value != null)
          {
            // VC: Attribute Default Value Syntactically Correct
            if ("IDREF".equals(type) || "ENTITY".equals(type))
              {
                if (!isNmtoken(value, true))
                  error("default value must match Name production", value);
              }
            else if ("IDREFS".equals(type) || "ENTITIES".equals(type))
              {
                StringTokenizer st = new StringTokenizer(value);
                while (st.hasMoreTokens())
                  {
                    String token = st.nextToken();
                    if (!isNmtoken(token, true))
                      error("default value must match Name production", token);
                  }
              }
            else if ("NMTOKEN".equals(type) || "ENUMERATION".equals(type))
              {
                if (!isNmtoken(value, false))
                  error("default value must match Nmtoken production", value);
              }
            else if ("NMTOKENS".equals(type))
              {
                StringTokenizer st = new StringTokenizer(value);
                while (st.hasMoreTokens())
                  {
                    String token = st.nextToken();
                    if (!isNmtoken(token, false))
                      error("default value must match Nmtoken production",
                            token);
                  }
              }
          }
      }
    // Register attribute def
    AttributeDecl attribute =
      new AttributeDecl(type, value, valueType, enumeration, values,
                        inputStack.size() != 1);
    doctype.addAttributeDecl(elementName, name, attribute);
  }

  /**
   * Parse the EntityDecl production.
   */
  private void readEntityDecl(boolean inExternalSubset)
    throws IOException, XMLStreamException
  {
    int flags = 0;
    // Check if parameter entity
    boolean peFlag = false;
    expandPE = false;
    requireWhitespace();
    if (tryRead('%'))
      {
        peFlag = true;
        requireWhitespace();
      }
    expandPE = true;
    // Read entity name
    String name = readNmtoken(true);
    if (name.indexOf(':') != -1)
      error("illegal character ':' in entity name", name);
    if (peFlag)
      name = "%" + name;
    requireWhitespace();
    mark(1);
    int c = readCh();
    reset();
    if (c == 0x22 || c == 0x27) // " | '
      {
        // Internal entity replacement text
        String value = readLiteral(flags | LIT_DISABLE_EREF, true);
        int ai = value.indexOf('&');
        while (ai != -1)
          {
            int sci = value.indexOf(';', ai);
            if (sci == -1)
              error("malformed reference in entity value", value);
            String ref = value.substring(ai + 1, sci);
            int[] cp = UnicodeReader.toCodePointArray(ref);
            if (cp.length == 0)
              error("malformed reference in entity value", value);
            if (cp[0] == 0x23) // #
              {
                if (cp.length == 1)
                  error("malformed reference in entity value", value);
                if (cp[1] == 0x78) // 'x'
                  {
                    if (cp.length == 2)
                      error("malformed reference in entity value", value);
                    for (int i = 2; i < cp.length; i++)
                      {
                        int x = cp[i];
                        if (x < 0x30 ||
                            (x > 0x39 && x < 0x41) ||
                            (x > 0x46 && x < 0x61) ||
                            x > 0x66)
                          error("malformed character reference in entity value",
                                value);
                      }
                  }
                else
                  {
                    for (int i = 1; i < cp.length; i++)
                      {
                        int x = cp[i];
                        if (x < 0x30 || x > 0x39)
                          error("malformed character reference in entity value",
                                value);
                      }
                  }
              }
            else
              {
                if (!isNameStartCharacter(cp[0], input.xml11))
                  error("malformed reference in entity value", value);
                for (int i = 1; i < cp.length; i++)
                  {
                    if (!isNameCharacter(cp[i], input.xml11))
                      error("malformed reference in entity value", value);
                  }
              }
            ai = value.indexOf('&', sci);
          }
        doctype.addEntityDecl(name, value, inExternalSubset);
      }
    else
      {
        ExternalIds ids = readExternalIds(false, false);
        // Check for NDATA
        boolean white = tryWhitespace();
        if (!peFlag && tryRead("NDATA"))
          {
            if (!white)
              error("whitespace required before NDATA");
            requireWhitespace();
            ids.notationName = readNmtoken(true);
          }
        doctype.addEntityDecl(name, ids, inExternalSubset);
      }
    // finish
    skipWhitespace();
    require('>');
  }

  /**
   * Parse the NotationDecl production.
   */
  private void readNotationDecl(boolean inExternalSubset)
    throws IOException, XMLStreamException
  {
    requireWhitespace();
    String notationName = readNmtoken(true);
    if (notationName.indexOf(':') != -1)
      error("illegal character ':' in notation name", notationName);
    if (validating)
      {
        // VC: Unique Notation Name
        ExternalIds notation = doctype.getNotation(notationName);
        if (notation != null)
          error("duplicate notation name", notationName);
      }
    requireWhitespace();
    ExternalIds ids = readExternalIds(true, false);
    ids.notationName = notationName;
    doctype.addNotationDecl(notationName, ids, inExternalSubset);
    skipWhitespace();
    require('>');
  }

  /**
   * Returns a tuple {publicId, systemId}.
   */
  private ExternalIds readExternalIds(boolean inNotation, boolean isSubset)
    throws IOException, XMLStreamException
  {
    int c;
    int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;
    ExternalIds ids = new ExternalIds();
    
    if (tryRead("PUBLIC"))
      {
        requireWhitespace();
        ids.publicId = readLiteral(LIT_NORMALIZE | LIT_PUBID | flags, false);
        if (inNotation)
          {
            skipWhitespace();
            mark(1);
            c = readCh();
            reset();
            if (c == 0x22 || c == 0x27) // " | '
              {
                String href = readLiteral(flags, false);
                ids.systemId = absolutize(input.systemId, href);
              }
          }
        else
          {
            requireWhitespace();
            String href = readLiteral(flags, false);
            ids.systemId = absolutize(input.systemId, href);
          }
        // Check valid URI characters
        for (int i = 0; i < ids.publicId.length(); i++)
          {
            char d = ids.publicId.charAt(i);
            if (d >= 'a' && d <= 'z')
              continue;
            if (d >= 'A' && d <= 'Z')
              continue;
            if (" \r\n0123456789-' ()+,./:=?;!*#@$_%".indexOf(d) != -1)
              continue;
            error("illegal PUBLIC id character",
                  "U+" + Integer.toHexString(d));
          }
      }
    else if (tryRead("SYSTEM"))
      {
        requireWhitespace();
        String href = readLiteral(flags, false);
        ids.systemId = absolutize(input.systemId, href);
      }
    else if (!isSubset)
      {
        error("missing SYSTEM or PUBLIC keyword");
      }
    if (ids.systemId != null && !inNotation)
      {
        if (ids.systemId.indexOf('#') != -1)
          error("SYSTEM id has a URI fragment", ids.systemId);
      }
    return ids;
  }

  /**
   * Parse the start of an element.
   * @return the state of the parser afterwards (EMPTY_ELEMENT or CONTENT)
   */
  private int readStartElement()
    throws IOException, XMLStreamException
  {
    // Read element name
    String elementName = readNmtoken(true);
    attrs.clear();
    // Push namespace context
    if (namespaceAware)
      {
        if (elementName.charAt(0) == ':' ||
            elementName.charAt(elementName.length() - 1) == ':')
          error("not a QName", elementName);
        namespaces.addFirst(new LinkedHashMap());
      }
    // Read element content
    boolean white = tryWhitespace();
    mark(1);
    int c = readCh();
    while (c != 0x2f && c != 0x3e) // '/' | '>'
      {
        // Read attribute
        reset();
        if (!white)
          error("need whitespace between attributes");
        readAttribute(elementName);
        white = tryWhitespace();
        mark(1);
        c = readCh();
      }
    // supply defaulted attributes
    if (doctype != null)
      {
        for (Iterator i = doctype.attlistIterator(elementName); i.hasNext(); )
          {
            Map.Entry entry = (Map.Entry) i.next();
            String attName = (String) entry.getKey();
            AttributeDecl decl = (AttributeDecl) entry.getValue();
            if (validating)
              {
                switch (decl.valueType)
                  {
                  case ATTRIBUTE_DEFAULT_REQUIRED:
                    // VC: Required Attribute
                    if (decl.value == null && !attributeSpecified(attName))
                      error("value for " + attName + " attribute is required");
                    break;
                  case ATTRIBUTE_DEFAULT_FIXED:
                    // VC: Fixed Attribute Default
                    for (Iterator j = attrs.iterator(); j.hasNext(); )
                      {
                        Attribute a = (Attribute) j.next();
                        if (attName.equals(a.name) &&
                            !decl.value.equals(a.value))
                          error("value for " + attName + " attribute must be " +
                                decl.value);
                      }
                    break;
                  }
              }
            if (namespaceAware && attName.equals("xmlns"))
              {
                LinkedHashMap ctx =
                  (LinkedHashMap) namespaces.getFirst();
                if (ctx.containsKey(XMLConstants.DEFAULT_NS_PREFIX))
                  continue; // namespace was specified
              }
            else if (namespaceAware && attName.startsWith("xmlns:"))
              {
                LinkedHashMap ctx =
                  (LinkedHashMap) namespaces.getFirst();
                if (ctx.containsKey(attName.substring(6)))
                  continue; // namespace was specified
              }
            else if (attributeSpecified(attName))
              continue;
            if (decl.value == null)
              continue;
            // VC: Standalone Document Declaration
            if (validating && decl.external && xmlStandalone == Boolean.TRUE)
              error("standalone must be 'no' if attributes inherit values " +
                    "from externally declared markup declarations");
            Attribute attr =
              new Attribute(attName, decl.type, false, decl.value);
            if (namespaceAware)
              {
                if (!addNamespace(attr))
                  attrs.add(attr);
              }
            else
              attrs.add(attr);
          }
      }
    if (baseAware)
      {
        String uri = getAttributeValue(XMLConstants.XML_NS_URI, "base");
        String base = getXMLBase();
        bases.addFirst(absolutize(base, uri));
      }
    if (namespaceAware)
      {
        // check prefix bindings
        int ci = elementName.indexOf(':');
        if (ci != -1)
          {
            String prefix = elementName.substring(0, ci);
            String uri = getNamespaceURI(prefix);
            if (uri == null)
              error("unbound element prefix", prefix);
            else if (input.xml11 && "".equals(uri))
              error("XML 1.1 unbound element prefix", prefix);
          }
        for (Iterator i = attrs.iterator(); i.hasNext(); )
          {
            Attribute attr = (Attribute) i.next();
            if (attr.prefix != null &&
                !XMLConstants.XMLNS_ATTRIBUTE.equals(attr.prefix))
              {
                String uri = getNamespaceURI(attr.prefix);
                if (uri == null)
                  error("unbound attribute prefix", attr.prefix);
                else if (input.xml11 && "".equals(uri))
                  error("XML 1.1 unbound attribute prefix", attr.prefix);
              }
          }
      }
    if (validating && doctype != null)
      {
        validateStartElement(elementName);
        currentContentModel = doctype.getElementModel(elementName);
        if (currentContentModel == null)
          error("no element declaration", elementName);
        validationStack.add(new LinkedList());
      }
    // make element name available for read
    buf.setLength(0);
    buf.append(elementName);
    // push element onto stack
    stack.addLast(elementName);
    switch (c)
      {
      case 0x3e: // '>'
        return CONTENT;
      case 0x2f: // '/'
        require('>');
        return EMPTY_ELEMENT;
      }
    return -1; // to satisfy compiler
  }

  /**
   * Indicates whether the specified attribute name was specified for the
   * current element.
   */
  private boolean attributeSpecified(String attName)
  {
    for (Iterator j = attrs.iterator(); j.hasNext(); )
      {
        Attribute a = (Attribute) j.next();
        if (attName.equals(a.name))
          return true;
      }
    return false;
  }

  /**
   * Parse an attribute.
   */
  private void readAttribute(String elementName)
    throws IOException, XMLStreamException
  {
    // Read attribute name
    String attributeName = readNmtoken(true);
    String type = getAttributeType(elementName, attributeName);
    readEq();
    // Read literal
    final int flags = LIT_ATTRIBUTE |  LIT_ENTITY_REF;
    String value = (type == null || "CDATA".equals(type)) ?
      readLiteral(flags, false) : readLiteral(flags | LIT_NORMALIZE, false);
    // add attribute event
    Attribute attr = this.new Attribute(attributeName, type, true, value);
    if (namespaceAware)
      {
        if (attributeName.charAt(0) == ':' ||
            attributeName.charAt(attributeName.length() - 1) == ':')
          error("not a QName", attributeName);
        else if (attributeName.equals("xmlns"))
          {
            LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();
            if (ctx.containsKey(XMLConstants.DEFAULT_NS_PREFIX))
              error("duplicate default namespace");
          }
        else if (attributeName.startsWith("xmlns:"))
          {
            LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();
            if (ctx.containsKey(attributeName.substring(6)))
              error("duplicate namespace", attributeName.substring(6));
          }
        else if (attrs.contains(attr))
          error("duplicate attribute", attributeName);
      }
    else if (attrs.contains(attr))
      error("duplicate attribute", attributeName);
    if (validating && doctype != null)
      {
        // VC: Attribute Value Type
        AttributeDecl decl =
          doctype.getAttributeDecl(elementName, attributeName);
        if (decl == null)
          error("attribute must be declared", attributeName);
        if ("ENUMERATION".equals(decl.type))
          {
            // VC: Enumeration
            if (!decl.values.contains(value))
              error("value does not match enumeration " + decl.enumeration,
                    value);
          }
        else if ("ID".equals(decl.type))
          {
            // VC: ID
            if (!isNmtoken(value, true))
              error("ID values must match the Name production");
            if (ids.contains(value))
              error("Duplicate ID", value);
            ids.add(value);
          }
        else if ("IDREF".equals(decl.type) || "IDREFS".equals(decl.type))
          {
            StringTokenizer st = new StringTokenizer(value);
            while (st.hasMoreTokens())
              {
                String token = st.nextToken();
                // VC: IDREF
                if (!isNmtoken(token, true))
                  error("IDREF values must match the Name production");
                idrefs.add(token);
              }
          }
        else if ("NMTOKEN".equals(decl.type) || "NMTOKENS".equals(decl.type))
          {
            StringTokenizer st = new StringTokenizer(value);
            while (st.hasMoreTokens())
              {
                String token = st.nextToken();
                // VC: Name Token
                if (!isNmtoken(token, false))
                  error("NMTOKEN values must match the Nmtoken production");
              }
          }
        else if ("ENTITY".equals(decl.type))
          {
            // VC: Entity Name
            if (!isNmtoken(value, true))
              error("ENTITY values must match the Name production");
            Object entity = doctype.getEntity(value);
            if (entity == null || !(entity instanceof ExternalIds) ||
                ((ExternalIds) entity).notationName == null)
              error("ENTITY values must match the name of an unparsed " +
                    "entity declared in the DTD");
          }
        else if ("NOTATION".equals(decl.type))
          {
            if (!decl.values.contains(value))
              error("NOTATION values must match a declared notation name",
                    value);
            // VC: Notation Attributes
            ExternalIds notation = doctype.getNotation(value);
            if (notation == null)
              error("NOTATION values must match the name of a notation " +
                    "declared in the DTD", value);
          }
      }
    if (namespaceAware)
      {
        if (!addNamespace(attr))
          attrs.add(attr);
      }
    else
      attrs.add(attr);
  }

  /**
   * Determines whether the specified attribute is a namespace declaration,
   * and adds it to the current namespace context if so. Returns false if
   * the attribute is an ordinary attribute.
   */
  private boolean addNamespace(Attribute attr)
    throws XMLStreamException
  {
    if ("xmlns".equals(attr.name))
      {
        LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();
        if (ctx.get(XMLConstants.DEFAULT_NS_PREFIX) != null)
          error("Duplicate default namespace declaration");
        if (XMLConstants.XML_NS_URI.equals(attr.value))
          error("can't bind XML namespace");
        ctx.put(XMLConstants.DEFAULT_NS_PREFIX, attr.value);
        return true;
      }
    else if ("xmlns".equals(attr.prefix))
      {
        LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();
        if (ctx.get(attr.localName) != null)
          error("Duplicate namespace declaration for prefix",
                attr.localName);
        if (XMLConstants.XML_NS_PREFIX.equals(attr.localName))
          {
            if (!XMLConstants.XML_NS_URI.equals(attr.value))
              error("can't redeclare xml prefix");
            else
              return false; // treat as attribute
          }
        if (XMLConstants.XML_NS_URI.equals(attr.value))
          error("can't bind non-xml prefix to XML namespace");
        if (XMLConstants.XMLNS_ATTRIBUTE.equals(attr.localName))
          error("can't redeclare xmlns prefix");
        if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attr.value))
          error("can't bind non-xmlns prefix to XML Namespace namespace");
        if ("".equals(attr.value) && !input.xml11)
          error("illegal use of 1.1-style prefix unbinding in 1.0 document");
        ctx.put(attr.localName, attr.value);
        return true;
      }
    return false;
  }

  /**
   * Parse a closing tag.
   */
  private void readEndElement()
    throws IOException, XMLStreamException
  {
    // pop element off stack
    String expected = (String) stack.removeLast();
    require(expected);
    skipWhitespace();
    require('>');
    // Make element name available
    buf.setLength(0);
    buf.append(expected);
    if (validating && doctype != null)
      endElementValidationHook();
  }

  /**
   * Validate the end of an element.
   * Called on an end-element or empty element if validating.
   */
  private void endElementValidationHook()
    throws XMLStreamException
  {
    validateEndElement();
    validationStack.removeLast();
    if (stack.isEmpty())
      currentContentModel = null;
    else
      {
        String parent = (String) stack.getLast();
        currentContentModel = doctype.getElementModel(parent);
      }
  }

  /**
   * Parse a comment.
   */
  private void readComment(boolean inDTD)
    throws IOException, XMLStreamException
  {
    boolean saved = expandPE;
    expandPE = false;
    buf.setLength(0);
    readUntil(TEST_END_COMMENT);
    require('>');
    expandPE = saved;
    if (inDTD)
      doctype.addComment(buf.toString());
  }

  /**
   * Parse a processing instruction.
   */
  private void readPI(boolean inDTD)
    throws IOException, XMLStreamException
  {
    boolean saved = expandPE;
    expandPE = false;
    piTarget = readNmtoken(true);
    if (piTarget.indexOf(':') != -1)
      error("illegal character in PI target", new Character(':'));
    if ("xml".equalsIgnoreCase(piTarget))
      error("illegal PI target", piTarget);
    if (tryRead(TEST_END_PI))
      piData = null;
    else
      {
        if (!tryWhitespace())
          error("whitespace required between PI target and data");
        buf.setLength(0);
        readUntil(TEST_END_PI);
        piData = buf.toString();
      }
    expandPE = saved;
    if (inDTD)
      doctype.addPI(piTarget, piData);
  }

  /**
   * Parse an entity reference.
   */
  private void readReference()
    throws IOException, XMLStreamException
  {
    buf.setLength(0);
    String entityName = readNmtoken(true);
    require(';');
    buf.setLength(0);
    buf.append(entityName);
  }

  /**
   * Read an CDATA section.
   */
  private void readCDSect()
    throws IOException, XMLStreamException
  {
    buf.setLength(0);
    readUntil(TEST_END_CDATA);
  }

  /**
   * Read character data.
   * @return the type of text read (CHARACTERS or SPACE)
   */
  private int readCharData(String prefix)
    throws IOException, XMLStreamException
  {
    boolean white = true;
    buf.setLength(0);
    if (prefix != null)
      buf.append(prefix);
    boolean done = false;
    boolean entities = false;
    while (!done)
      {
        // Block read
        mark(tmpBuf.length);
        int len = read(tmpBuf, 0, tmpBuf.length);
        if (len == -1)
          {
            if (inputStack.size() > 1)
              {
                popInput();
                // report end-entity
                done = true;
              }
            else
              throw new EOFException();
          }
        for (int i = 0; i < len && !done; i++)
          {
            int c = tmpBuf[i];
            switch (c)
              {
              case 0x20:
              case 0x09:
              case 0x0a:
              case 0x0d:
                buf.append(Character.toChars(c));
                break; // whitespace
              case 0x26: // '&'
                reset();
                read(tmpBuf, 0, i);
                // character reference?
                mark(3);
                c = readCh(); // &
                c = readCh();
                if (c == 0x23) // '#'
                  {
                    mark(1);
                    c = readCh();
                    boolean hex = (c == 0x78); // 'x'
                    if (!hex)
                      reset();
                    char[] ch = readCharacterRef(hex ? 16 : 10);
                    buf.append(ch, 0, ch.length);
                    for (int j = 0; j < ch.length; j++)
                      {
                        switch (ch[j])
                          {
                          case 0x20:
                          case 0x09:
                          case 0x0a:
                          case 0x0d:
                            break; // whitespace
                          default:
                            white = false;
                          }
                      }
                  }
                else
                  {
                    // entity reference
                    reset();
                    c = readCh(); // &
                    String entityName = readNmtoken(true);
                    require(';');
                    String text =
                      (String) PREDEFINED_ENTITIES.get(entityName);
                    if (text != null)
                      buf.append(text);
                    else
                      {
                        pushInput("", "&" + entityName + ";", false, false);
                        done = true;
                        break;
                      }
                  }
                // continue processing
                i = -1;
                mark(tmpBuf.length);
                len = read(tmpBuf, 0, tmpBuf.length);
                if (len == -1)
                  {
                    if (inputStack.size() > 1)
                      {
                        popInput();
                        done = true;
                      }
                    else
                      throw new EOFException();
                  }
                entities = true;
                break; // end of text sequence
              case 0x3e: // '>'
                int l = buf.length();
                if (l > 1 &&
                    buf.charAt(l - 1) == ']' &&
                    buf.charAt(l - 2) == ']')
                  error("Character data may not contain unescaped ']]>'");
                buf.append(Character.toChars(c));
                break;
              case 0x3c: // '<'
                reset();
                // read i characters
                int count = 0, remaining = i;
                do
                  {
                    int r = read(tmpBuf, 0, remaining);
                    count += r;
                    remaining -= r;
                  }
                while (count < i);
                i = len;
                if (coalescing && tryRead(TEST_CDATA))
                  readUntil(TEST_END_CDATA); // read CDATA section into buf
                else
                  done = true; // end of text sequence
                break;
              default:
                if (input.xml11)
                  {
                    if (!isXML11Char(c) || isXML11RestrictedChar(c))
                      error("illegal XML 1.1 character",
                            "U+" + Integer.toHexString(c));
                  }
                else if (!isChar(c))
                  error("illegal XML character",
                        "U+" + Integer.toHexString(c));
                white = false;
                buf.append(Character.toChars(c));
              }
          }
        // if text buffer >= 2MB, return it as a chunk
        // to avoid excessive memory use
        if (buf.length() >= 2097152)
          done = true;
      }
    if (entities)
      normalizeCRLF(buf);
    return white ? XMLStreamConstants.SPACE : XMLStreamConstants.CHARACTERS;
  }

  /**
   * Expands the specified entity.
   */
  private void expandEntity(String name, boolean inAttr, boolean normalize)
    throws IOException, XMLStreamException
  {
    if (doctype != null)
      {
        Object value = doctype.getEntity(name);
        if (value != null)
          {
            if (xmlStandalone == Boolean.TRUE)
              {
                // VC: Standalone Document Declaration
                if (doctype.isEntityExternal(name))
                  error("reference to external entity in standalone document");
                else if (value instanceof ExternalIds)
                  {
                    ExternalIds ids = (ExternalIds) value;
                    if (ids.notationName != null &&
                        doctype.isNotationExternal(ids.notationName))
                      error("reference to external notation in " +
                            "standalone document");
                  }
              }
            if (value instanceof String)
              {
                String text = (String) value;
                if (inAttr && text.indexOf('<') != -1)
                  error("< in attribute value");
                pushInput(name, text, !inAttr, normalize);
              }
            else if (inAttr)
              error("reference to external entity in attribute value", name);
            else
              pushInput(name, (ExternalIds) value, !inAttr, normalize);
            return;
          }
      }
    error("reference to undeclared entity", name);
  }

  /**
   * Indicates whether the specified entity is unparsed.
   */
  private boolean isUnparsedEntity(String name)
  {
    if (doctype != null)
      {
        Object value = doctype.getEntity(name);
        if (value != null && value instanceof ExternalIds)
          return ((ExternalIds) value).notationName != null;
      }
    return false;
  }

  /**
   * Read an equals sign.
   */
  private void readEq()
    throws IOException, XMLStreamException
  { 
    skipWhitespace();
    require('=');
    skipWhitespace();
  }

  /**
   * Character read for reading literals.
   * @param recognizePEs whether to recognize parameter-entity references
   */
  private int literalReadCh(boolean recognizePEs)
    throws IOException, XMLStreamException
  {
    int c = recognizePEs ? readCh() : read();
    while (c == -1)
      {
        if (inputStack.size() > 1)
          {
            inputStack.removeLast();
            input = (Input) inputStack.getLast();
            // Don't issue end-entity
            c = recognizePEs ? readCh() : read();
          }
        else
          throw new EOFException();
      }
    return c;
  }

  /**
   * Read a string literal.
   */
  private String readLiteral(int flags, boolean recognizePEs)
    throws IOException, XMLStreamException
  {
    boolean saved = expandPE;
    int delim = readCh();
    if (delim != 0x27 && delim != 0x22)
      error("expected '\"' or \"'\"", "U+" + Integer.toHexString(delim));
    literalBuf.setLength(0);
    if ((flags & LIT_DISABLE_PE) != 0)
      expandPE = false;
    boolean entities = false;
    int inputStackSize = inputStack.size();
    do
      {
        int c = literalReadCh(recognizePEs);
        if (c == delim && inputStackSize == inputStack.size())
          break;
        switch (c)
          {
          case 0x0a:
          case 0x0d:
            if ((flags & (LIT_ATTRIBUTE | LIT_PUBID)) != 0)
              c = 0x20; // normalize to space
            break;
          case 0x09:
            if ((flags & LIT_ATTRIBUTE) != 0)
              c = 0x20; // normalize to space
            break;
          case 0x26: // '&'
            mark(2);
            c = readCh();
            if (c == 0x23) // '#'
              {
                if ((flags & LIT_DISABLE_CREF) != 0)
                  {
                    reset();
                    c = 0x26; // '&'
                  }
                else
                  {
                    mark(1);
                    c = readCh();
                    boolean hex = (c == 0x78); // 'x'
                    if (!hex)
                      reset();
                    char[] ref = readCharacterRef(hex ? 16 : 10);
                    for (int i = 0; i < ref.length; i++)
                      literalBuf.append(ref[i]);
                    entities = true;
                    continue;
                  }
              }
            else
              {
                if ((flags & LIT_DISABLE_EREF) != 0)
                  {
                    reset();
                    c = 0x26; // '&'
                  }
                else
                  {
                    reset();
                    String entityName = readNmtoken(true);
                    require(';');
                    String text =
                      (String) PREDEFINED_ENTITIES.get(entityName);
                    if (text != null)
                      literalBuf.append(text);
                    else
                      expandEntity(entityName,
                                   (flags & LIT_ATTRIBUTE) != 0,
                                   true);
                    entities = true;
                    continue;
                  }
              }
            break;
          case 0x3c: // '<'
            if ((flags & LIT_ATTRIBUTE) != 0)
              error("attribute values may not contain '<'");
            break;
          case -1:
            if (inputStack.size() > 1)
              {
                popInput();
                continue;
              }
            throw new EOFException();
          default:
            if ((c < 0x0020 || c > 0xfffd) ||
                (c >= 0xd800 && c < 0xdc00) ||
                (input.xml11 && (c >= 0x007f) &&
                 (c <= 0x009f) && (c != 0x0085)))
              error("illegal character", "U+" + Integer.toHexString(c));
          }
        literalBuf.append(Character.toChars(c));
      }
    while (true);
    expandPE = saved;
    if (entities)
      normalizeCRLF(literalBuf);
    if ((flags & LIT_NORMALIZE) > 0)
      literalBuf = normalize(literalBuf);
    return literalBuf.toString();
  }

  /**
   * Performs attribute-value normalization of the text buffer.
   * This discards leading and trailing whitespace, and replaces sequences
   * of whitespace with a single space.
   */
  private StringBuffer normalize(StringBuffer buf)
  {
    StringBuffer acc = new StringBuffer();
    int len = buf.length();
    int avState = 0;
    for (int i = 0; i < len; i++)
      {
        char c = buf.charAt(i);
        if (c == ' ')
          avState = (avState == 0) ? 0 : 1;
        else
          {
            if (avState == 1)
              acc.append(' ');
            acc.append(c);
            avState = 2;
          }
      }
    return acc;
  }

  /**
   * Replace any CR/LF pairs in the buffer with LF.
   * This may be necessary if combinations of CR or LF were declared as
   * (character) entity references in the input.
   */
  private void normalizeCRLF(StringBuffer buf)
  {
    int len = buf.length() - 1;
    for (int i = 0; i < len; i++)
      {
        char c = buf.charAt(i);
        if (c == '\r' && buf.charAt(i + 1) == '\n')
          {
            buf.deleteCharAt(i--);
            len--;
          }
      }
  }

  /**
   * Parse and expand a parameter entity reference.
   */
  private void expandPEReference()
    throws IOException, XMLStreamException
  {
    String name = readNmtoken(true, new StringBuffer());
    require(';');
    mark(1); // ensure we don't reset to before the semicolon
    if (doctype != null)
      {
        String entityName = "%" + name;
        Object entity = doctype.getEntity(entityName);
        if (entity != null)
          {
            if (xmlStandalone == Boolean.TRUE)
              {
                if (doctype.isEntityExternal(entityName))
                  error("reference to external parameter entity in " +
                        "standalone document");
              }
            if (entity instanceof String)
              {
                pushInput(name, (String) entity, false, input.normalize);
                //pushInput(name, " " + (String) entity + " ");
              }
            else
              {
                //pushInput("", " ");
                pushInput(name, (ExternalIds) entity, false, input.normalize);
                //pushInput("", " ");
              }
          }
        else
          error("reference to undeclared parameter entity", name);
      }
    else
      error("reference to parameter entity without doctype", name);
  }

  /**
   * Parse the digits in a character reference.
   * @param base the base of the digits (10 or 16)
   */
  private char[] readCharacterRef(int base)
    throws IOException, XMLStreamException
  {
    StringBuffer b = new StringBuffer();
    for (int c = readCh(); c != 0x3b && c != -1; c = readCh())
      b.append(Character.toChars(c));
    try
      {
        int ord = Integer.parseInt(b.toString(), base);
        if (input.xml11)
          {
            if (!isXML11Char(ord))
              error("illegal XML 1.1 character reference " +
                    "U+" + Integer.toHexString(ord));
          }
        else
          {
            if ((ord < 0x20 && !(ord == 0x0a || ord == 0x09 || ord == 0x0d))
                || (ord >= 0xd800 && ord <= 0xdfff)
                || ord == 0xfffe || ord == 0xffff
                || ord > 0x0010ffff)
              error("illegal XML character reference " +
                    "U+" + Integer.toHexString(ord));
          }
        return Character.toChars(ord);
      }
    catch (NumberFormatException e)
      {
        error("illegal characters in character reference", b.toString());
        return null;
      }
  }

  /**
   * Parses an NMTOKEN or Name production.
   * @param isName if a Name, otherwise an NMTOKEN
   */
  private String readNmtoken(boolean isName)
    throws IOException, XMLStreamException
  {
    return readNmtoken(isName, nmtokenBuf);
  }
  
  /**
   * Parses an NMTOKEN or Name production using the specified buffer.
   * @param isName if a Name, otherwise an NMTOKEN
   * @param buf the character buffer to use
   */
  private String readNmtoken(boolean isName, StringBuffer buf)
    throws IOException, XMLStreamException
  {
    buf.setLength(0);
    int c = readCh();
    if (isName)
      {
        if (!isNameStartCharacter(c, input.xml11))
          error("not a name start character",
                "U+" + Integer.toHexString(c));
      }
    else
      {
        if (!isNameCharacter(c, input.xml11))
          error("not a name character",
                "U+" + Integer.toHexString(c));
      }
    buf.append(Character.toChars(c));
    do
      {
        mark(1);
        c = readCh();
        switch (c)
          {
          case 0x25: // '%'
          case 0x3c: // '<'
          case 0x3e: // '>'
          case 0x26: // '&'
          case 0x2c: // ','
          case 0x7c: // '|'
          case 0x2a: // '*'
          case 0x2b: // '+'
          case 0x3f: // '?'
          case 0x29: // ')'
          case 0x3d: // '='
          case 0x27: // '\''
          case 0x22: // '"'
          case 0x5b: // '['
          case 0x20: // ' '
          case 0x09: // '\t'
          case 0x0a: // '\n'
          case 0x0d: // '\r'
          case 0x3b: // ';'
          case 0x2f: // '/'
          case -1:
            reset();
            return intern(buf.toString());
          default:
            if (!isNameCharacter(c, input.xml11))
              error("not a name character",
                    "U+" + Integer.toHexString(c));
            else
              buf.append(Character.toChars(c));
          }
      }
    while (true);
  }

  /**
   * Indicates whether the specified Unicode character is an XML 1.1 Char.
   */
  public static boolean isXML11Char(int c)
  {
    return ((c >= 0x0001 && c <= 0xD7FF) ||
            (c >= 0xE000 && c < 0xFFFE) ||
            (c >= 0x10000 && c <= 0x10FFFF));
  }

  /**
   * Indicates whether the specified Unicode character is an XML 1.1
   * RestrictedChar.
   */
  public static boolean isXML11RestrictedChar(int c)
  {
    return ((c >= 0x0001 && c <= 0x0008) ||
            (c >= 0x000B && c <= 0x000C) ||
            (c >= 0x000E && c <= 0x001F) ||
            (c >= 0x007F && c <= 0x0084) ||
            (c >= 0x0086 && c <= 0x009F));
  }

  /**
   * Indicates whether the specified text matches the Name or Nmtoken
   * production.
   */
  private boolean isNmtoken(String text, boolean isName)
  {
    try
      {
        int[] cp = UnicodeReader.toCodePointArray(text);
        if (cp.length == 0)
          return false;
        if (isName)
          {
            if (!isNameStartCharacter(cp[0], input.xml11))
              return false;
          }
        else
          {
            if (!isNameCharacter(cp[0], input.xml11))
              return false;
          }
        for (int i = 1; i < cp.length; i++)
          {
            if (!isNameCharacter(cp[i], input.xml11))
              return false;
          }
        return true;
      }
    catch (IOException e)
      {
        return false;
      }
  }

  /**
   * Indicates whether the specified Unicode character is a Name start
   * character.
   */
  public static boolean isNameStartCharacter(int c, boolean xml11)
  {
    if (xml11)
      return ((c >= 0x0041 && c <= 0x005a) ||
              (c >= 0x0061 && c <= 0x007a) ||
              c == 0x3a |
              c == 0x5f |
              (c >= 0xC0 && c <= 0xD6) ||
              (c >= 0xD8 && c <= 0xF6) ||
              (c >= 0xF8 && c <= 0x2FF) ||
              (c >= 0x370 && c <= 0x37D) ||
              (c >= 0x37F && c <= 0x1FFF) ||
              (c >= 0x200C && c <= 0x200D) ||
              (c >= 0x2070 && c <= 0x218F) ||
              (c >= 0x2C00 && c <= 0x2FEF) ||
              (c >= 0x3001 && c <= 0xD7FF) ||
              (c >= 0xF900 && c <= 0xFDCF) ||
              (c >= 0xFDF0 && c <= 0xFFFD) ||
              (c >= 0x10000 && c <= 0xEFFFF));
    else
      return (c == 0x5f || c == 0x3a || isLetter(c));
  }

  /**
   * Indicates whether the specified Unicode character is a Name non-initial
   * character.
   */
  public static boolean isNameCharacter(int c, boolean xml11)
  {
    if (xml11)
      return ((c >= 0x0041 && c <= 0x005a) ||
              (c >= 0x0061 && c <= 0x007a) ||
              (c >= 0x0030 && c <= 0x0039) ||
              c == 0x3a |
              c == 0x5f |
              c == 0x2d |
              c == 0x2e |
              c == 0xB7 |
              (c >= 0xC0 && c <= 0xD6) ||
              (c >= 0xD8 && c <= 0xF6) ||
              (c >= 0xF8 && c <= 0x2FF) ||
              (c >= 0x300 && c <= 0x37D) ||
              (c >= 0x37F && c <= 0x1FFF) ||
              (c >= 0x200C && c <= 0x200D) ||
              (c >= 0x203F && c <= 0x2040) ||
              (c >= 0x2070 && c <= 0x218F) ||
              (c >= 0x2C00 && c <= 0x2FEF) ||
              (c >= 0x3001 && c <= 0xD7FF) ||
              (c >= 0xF900 && c <= 0xFDCF) ||
              (c >= 0xFDF0 && c <= 0xFFFD) ||
              (c >= 0x10000 && c <= 0xEFFFF));
    else
      return (c == 0x2e || c == 0x2d || c == 0x5f || c == 0x3a ||
              isLetter(c) || isDigit(c) ||
              isCombiningChar(c) || isExtender(c));
  }

  /**
   * Indicates whether the specified Unicode character matches the Letter
   * production.
   */
  public static boolean isLetter(int c)
  {
    if ((c >= 0x0041 && c <= 0x005A) ||
        (c >= 0x0061 && c <= 0x007A) ||
        (c >= 0x00C0 && c <= 0x00D6) ||
        (c >= 0x00D8 && c <= 0x00F6) ||
        (c >= 0x00F8 && c <= 0x00FF) ||
        (c >= 0x0100 && c <= 0x0131) ||
        (c >= 0x0134 && c <= 0x013E) ||
        (c >= 0x0141 && c <= 0x0148) ||
        (c >= 0x014A && c <= 0x017E) ||
        (c >= 0x0180 && c <= 0x01C3) ||
        (c >= 0x01CD && c <= 0x01F0) ||
        (c >= 0x01F4 && c <= 0x01F5) ||
        (c >= 0x01FA && c <= 0x0217) ||
        (c >= 0x0250 && c <= 0x02A8) ||
        (c >= 0x02BB && c <= 0x02C1) ||
        c == 0x0386 ||
        (c >= 0x0388 && c <= 0x038A) ||
        c == 0x038C ||
        (c >= 0x038E && c <= 0x03A1) ||
        (c >= 0x03A3 && c <= 0x03CE) ||
        (c >= 0x03D0 && c <= 0x03D6) ||
        c == 0x03DA ||
      c == 0x03DC ||
        c == 0x03DE ||
        c == 0x03E0 ||
        (c >= 0x03E2 && c <= 0x03F3) ||
        (c >= 0x0401 && c <= 0x040C) ||
        (c >= 0x040E && c <= 0x044F) ||
        (c >= 0x0451 && c <= 0x045C) ||
        (c >= 0x045E && c <= 0x0481) ||
        (c >= 0x0490 && c <= 0x04C4) ||
        (c >= 0x04C7 && c <= 0x04C8) ||
        (c >= 0x04CB && c <= 0x04CC) ||
        (c >= 0x04D0 && c <= 0x04EB) ||
        (c >= 0x04EE && c <= 0x04F5) ||
        (c >= 0x04F8 && c <= 0x04F9) ||
        (c >= 0x0531 && c <= 0x0556) ||
        c == 0x0559 ||
        (c >= 0x0561 && c <= 0x0586) ||
        (c >= 0x05D0 && c <= 0x05EA) ||
        (c >= 0x05F0 && c <= 0x05F2) ||
        (c >= 0x0621 && c <= 0x063A) ||
        (c >= 0x0641 && c <= 0x064A) ||
        (c >= 0x0671 && c <= 0x06B7) ||
        (c >= 0x06BA && c <= 0x06BE) ||
        (c >= 0x06C0 && c <= 0x06CE) ||
        (c >= 0x06D0 && c <= 0x06D3) ||
        c == 0x06D5 ||
        (c >= 0x06E5 && c <= 0x06E6) ||
        (c >= 0x0905 && c <= 0x0939) ||
        c == 0x093D ||
        (c >= 0x0958 && c <= 0x0961) ||
        (c >= 0x0985 && c <= 0x098C) ||
        (c >= 0x098F && c <= 0x0990) ||
        (c >= 0x0993 && c <= 0x09A8) ||
        (c >= 0x09AA && c <= 0x09B0) ||
        c == 0x09B2 ||
        (c >= 0x09B6 && c <= 0x09B9) ||
        (c >= 0x09DC && c <= 0x09DD) ||
        (c >= 0x09DF && c <= 0x09E1) ||
        (c >= 0x09F0 && c <= 0x09F1) ||
        (c >= 0x0A05 && c <= 0x0A0A) ||
        (c >= 0x0A0F && c <= 0x0A10) ||
        (c >= 0x0A13 && c <= 0x0A28) ||
        (c >= 0x0A2A && c <= 0x0A30) ||
        (c >= 0x0A32 && c <= 0x0A33) ||
        (c >= 0x0A35 && c <= 0x0A36) ||
        (c >= 0x0A38 && c <= 0x0A39) ||
        (c >= 0x0A59 && c <= 0x0A5C) ||
        c == 0x0A5E ||
        (c >= 0x0A72 && c <= 0x0A74) ||
        (c >= 0x0A85 && c <= 0x0A8B) ||
        c == 0x0A8D ||
        (c >= 0x0A8F && c <= 0x0A91) ||
        (c >= 0x0A93 && c <= 0x0AA8) ||
        (c >= 0x0AAA && c <= 0x0AB0) ||
        (c >= 0x0AB2 && c <= 0x0AB3) ||
        (c >= 0x0AB5 && c <= 0x0AB9) ||
        c == 0x0ABD ||
        c == 0x0AE0 ||
        (c >= 0x0B05 && c <= 0x0B0C) ||
        (c >= 0x0B0F && c <= 0x0B10) ||
        (c >= 0x0B13 && c <= 0x0B28) ||
        (c >= 0x0B2A && c <= 0x0B30) ||
        (c >= 0x0B32 && c <= 0x0B33) ||
        (c >= 0x0B36 && c <= 0x0B39) ||
        c == 0x0B3D ||
        (c >= 0x0B5C && c <= 0x0B5D) ||
        (c >= 0x0B5F && c <= 0x0B61) ||
        (c >= 0x0B85 && c <= 0x0B8A) ||
        (c >= 0x0B8E && c <= 0x0B90) ||
        (c >= 0x0B92 && c <= 0x0B95) ||
        (c >= 0x0B99 && c <= 0x0B9A) ||
        c == 0x0B9C ||
        (c >= 0x0B9E && c <= 0x0B9F) ||
        (c >= 0x0BA3 && c <= 0x0BA4) ||
        (c >= 0x0BA8 && c <= 0x0BAA) ||
        (c >= 0x0BAE && c <= 0x0BB5) ||
        (c >= 0x0BB7 && c <= 0x0BB9) ||
        (c >= 0x0C05 && c <= 0x0C0C) ||
        (c >= 0x0C0E && c <= 0x0C10) ||
        (c >= 0x0C12 && c <= 0x0C28) ||
        (c >= 0x0C2A && c <= 0x0C33) ||
        (c >= 0x0C35 && c <= 0x0C39) ||
        (c >= 0x0C60 && c <= 0x0C61) ||
        (c >= 0x0C85 && c <= 0x0C8C) ||
        (c >= 0x0C8E && c <= 0x0C90) ||
        (c >= 0x0C92 && c <= 0x0CA8) ||
        (c >= 0x0CAA && c <= 0x0CB3) ||
        (c >= 0x0CB5 && c <= 0x0CB9) ||
        c == 0x0CDE ||
        (c >= 0x0CE0 && c <= 0x0CE1) ||
        (c >= 0x0D05 && c <= 0x0D0C) ||
        (c >= 0x0D0E && c <= 0x0D10) ||
        (c >= 0x0D12 && c <= 0x0D28) ||
        (c >= 0x0D2A && c <= 0x0D39) ||
        (c >= 0x0D60 && c <= 0x0D61) ||
        (c >= 0x0E01 && c <= 0x0E2E) ||
        c == 0x0E30 ||
        (c >= 0x0E32 && c <= 0x0E33) ||
        (c >= 0x0E40 && c <= 0x0E45) ||
        (c >= 0x0E81 && c <= 0x0E82) ||
        c == 0x0E84 ||
        (c >= 0x0E87 && c <= 0x0E88) ||
        c == 0x0E8A ||
        c == 0x0E8D ||
        (c >= 0x0E94 && c <= 0x0E97) ||
        (c >= 0x0E99 && c <= 0x0E9F) ||
        (c >= 0x0EA1 && c <= 0x0EA3) ||
        c == 0x0EA5 ||
        c == 0x0EA7 ||
        (c >= 0x0EAA && c <= 0x0EAB) ||
        (c >= 0x0EAD && c <= 0x0EAE) ||
        c == 0x0EB0 ||
        (c >= 0x0EB2 && c <= 0x0EB3) ||
        c == 0x0EBD ||
        (c >= 0x0EC0 && c <= 0x0EC4) ||
        (c >= 0x0F40 && c <= 0x0F47) ||
        (c >= 0x0F49 && c <= 0x0F69) ||
        (c >= 0x10A0 && c <= 0x10C5) ||
        (c >= 0x10D0 && c <= 0x10F6) ||
        c == 0x1100 ||
        (c >= 0x1102 && c <= 0x1103) ||
        (c >= 0x1105 && c <= 0x1107) ||
        c == 0x1109 ||
        (c >= 0x110B && c <= 0x110C) ||
        (c >= 0x110E && c <= 0x1112) ||
        c == 0x113C ||
        c == 0x113E ||
        c == 0x1140 ||
        c == 0x114C ||
        c == 0x114E ||
        c == 0x1150 ||
        (c >= 0x1154 && c <= 0x1155) ||
        c == 0x1159 ||
        (c >= 0x115F && c <= 0x1161) ||
        c == 0x1163 ||
        c == 0x1165 ||
        c == 0x1167 ||
        c == 0x1169 ||
        (c >= 0x116D && c <= 0x116E) ||
        (c >= 0x1172 && c <= 0x1173) ||
        c == 0x1175 ||
        c == 0x119E ||
        c == 0x11A8 ||
        c == 0x11AB ||
        (c >= 0x11AE && c <= 0x11AF) ||
        (c >= 0x11B7 && c <= 0x11B8) ||
        c == 0x11BA ||
        (c >= 0x11BC && c <= 0x11C2) ||
        c == 0x11EB ||
        c == 0x11F0 ||
        c == 0x11F9 ||
        (c >= 0x1E00 && c <= 0x1E9B) ||
        (c >= 0x1EA0 && c <= 0x1EF9) ||
        (c >= 0x1F00 && c <= 0x1F15) ||
        (c >= 0x1F18 && c <= 0x1F1D) ||
        (c >= 0x1F20 && c <= 0x1F45) ||
        (c >= 0x1F48 && c <= 0x1F4D) ||
        (c >= 0x1F50 && c <= 0x1F57) ||
        c == 0x1F59 ||
        c == 0x1F5B ||
        c == 0x1F5D ||
        (c >= 0x1F5F && c <= 0x1F7D) ||
        (c >= 0x1F80 && c <= 0x1FB4) ||
        (c >= 0x1FB6 && c <= 0x1FBC) ||
        c == 0x1FBE ||
        (c >= 0x1FC2 && c <= 0x1FC4) ||
        (c >= 0x1FC6 && c <= 0x1FCC) ||
        (c >= 0x1FD0 && c <= 0x1FD3) ||
        (c >= 0x1FD6 && c <= 0x1FDB) ||
        (c >= 0x1FE0 && c <= 0x1FEC) ||
        (c >= 0x1FF2 && c <= 0x1FF4) ||
        (c >= 0x1FF6 && c <= 0x1FFC) ||
        c == 0x2126 ||
        (c >= 0x212A && c <= 0x212B) ||
        c == 0x212E ||
        (c >= 0x2180 && c <= 0x2182) ||
        (c >= 0x3041 && c <= 0x3094) ||
        (c >= 0x30A1 && c <= 0x30FA) ||
        (c >= 0x3105 && c <= 0x312C) ||
        (c >= 0xAC00 && c <= 0xD7A3))
        return true; // BaseChar
    if ((c >= 0x4e00 && c <= 0x9fa5) ||
        c == 0x3007 ||
        (c >= 0x3021 && c <= 0x3029))
      return true; // Ideographic
    return false;
  }

  /**
   * Indicates whether the specified Unicode character matches the Digit
   * production.
   */
  public static boolean isDigit(int c)
  {
    return ((c >= 0x0030 && c <= 0x0039) ||
            (c >= 0x0660 && c <= 0x0669) ||
            (c >= 0x06F0 && c <= 0x06F9) ||
            (c >= 0x0966 && c <= 0x096F) ||
            (c >= 0x09E6 && c <= 0x09EF) ||
            (c >= 0x0A66 && c <= 0x0A6F) ||
            (c >= 0x0AE6 && c <= 0x0AEF) ||
            (c >= 0x0B66 && c <= 0x0B6F) ||
            (c >= 0x0BE7 && c <= 0x0BEF) ||
            (c >= 0x0C66 && c <= 0x0C6F) ||
            (c >= 0x0CE6 && c <= 0x0CEF) ||
            (c >= 0x0D66 && c <= 0x0D6F) ||
            (c >= 0x0E50 && c <= 0x0E59) ||
            (c >= 0x0ED0 && c <= 0x0ED9) ||
            (c >= 0x0F20 && c <= 0x0F29));
  }

  /**
   * Indicates whether the specified Unicode character matches the
   * CombiningChar production.
   */
  public static boolean isCombiningChar(int c)
  {
    return ((c >= 0x0300 && c <= 0x0345) ||
            (c >= 0x0360 && c <= 0x0361) ||
            (c >= 0x0483 && c <= 0x0486) ||
            (c >= 0x0591 && c <= 0x05A1) ||
            (c >= 0x05A3 && c <= 0x05B9) ||
            (c >= 0x05BB && c <= 0x05BD) ||
            c == 0x05BF ||
            (c >= 0x05C1 && c <= 0x05C2) ||
            c == 0x05C4 ||
            (c >= 0x064B && c <= 0x0652) ||
            c == 0x0670 ||
            (c >= 0x06D6 && c <= 0x06DC) ||
            (c >= 0x06DD && c <= 0x06DF) ||
            (c >= 0x06E0 && c <= 0x06E4) ||
            (c >= 0x06E7 && c <= 0x06E8) ||
            (c >= 0x06EA && c <= 0x06ED) ||
            (c >= 0x0901 && c <= 0x0903) ||
            c == 0x093C ||
            (c >= 0x093E && c <= 0x094C) ||
            c == 0x094D ||
            (c >= 0x0951 && c <= 0x0954) ||
            (c >= 0x0962 && c <= 0x0963) ||
            (c >= 0x0981 && c <= 0x0983) ||
            c == 0x09BC ||
            c == 0x09BE ||
            c == 0x09BF ||
            (c >= 0x09C0 && c <= 0x09C4) ||
            (c >= 0x09C7 && c <= 0x09C8) ||
            (c >= 0x09CB && c <= 0x09CD) ||
            c == 0x09D7 ||
            (c >= 0x09E2 && c <= 0x09E3) ||
            c == 0x0A02 ||
            c == 0x0A3C ||
            c == 0x0A3E ||
            c == 0x0A3F ||
            (c >= 0x0A40 && c <= 0x0A42) ||
            (c >= 0x0A47 && c <= 0x0A48) ||
            (c >= 0x0A4B && c <= 0x0A4D) ||
            (c >= 0x0A70 && c <= 0x0A71) ||
            (c >= 0x0A81 && c <= 0x0A83) ||
            c == 0x0ABC ||
            (c >= 0x0ABE && c <= 0x0AC5) ||
            (c >= 0x0AC7 && c <= 0x0AC9) ||
            (c >= 0x0ACB && c <= 0x0ACD) ||
            (c >= 0x0B01 && c <= 0x0B03) ||
            c == 0x0B3C ||
            (c >= 0x0B3E && c <= 0x0B43) ||
            (c >= 0x0B47 && c <= 0x0B48) ||
            (c >= 0x0B4B && c <= 0x0B4D) ||
            (c >= 0x0B56 && c <= 0x0B57) ||
            (c >= 0x0B82 && c <= 0x0B83) ||
            (c >= 0x0BBE && c <= 0x0BC2) ||
            (c >= 0x0BC6 && c <= 0x0BC8) ||
            (c >= 0x0BCA && c <= 0x0BCD) ||
            c == 0x0BD7 ||
            (c >= 0x0C01 && c <= 0x0C03) ||
            (c >= 0x0C3E && c <= 0x0C44) ||
            (c >= 0x0C46 && c <= 0x0C48) ||
            (c >= 0x0C4A && c <= 0x0C4D) ||
            (c >= 0x0C55 && c <= 0x0C56) ||
            (c >= 0x0C82 && c <= 0x0C83) ||
            (c >= 0x0CBE && c <= 0x0CC4) ||
            (c >= 0x0CC6 && c <= 0x0CC8) ||
            (c >= 0x0CCA && c <= 0x0CCD) ||
            (c >= 0x0CD5 && c <= 0x0CD6) ||
            (c >= 0x0D02 && c <= 0x0D03) ||
            (c >= 0x0D3E && c <= 0x0D43) ||
            (c >= 0x0D46 && c <= 0x0D48) ||
            (c >= 0x0D4A && c <= 0x0D4D) ||
            c == 0x0D57 ||
            c == 0x0E31 ||
            (c >= 0x0E34 && c <= 0x0E3A) ||
            (c >= 0x0E47 && c <= 0x0E4E) ||
            c == 0x0EB1 ||
            (c >= 0x0EB4 && c <= 0x0EB9) ||
            (c >= 0x0EBB && c <= 0x0EBC) ||
            (c >= 0x0EC8 && c <= 0x0ECD) ||
            (c >= 0x0F18 && c <= 0x0F19) ||
            c == 0x0F35 ||
            c == 0x0F37 ||
            c == 0x0F39 ||
            c == 0x0F3E ||
            c == 0x0F3F ||
            (c >= 0x0F71 && c <= 0x0F84) ||
            (c >= 0x0F86 && c <= 0x0F8B) ||
            (c >= 0x0F90 && c <= 0x0F95) ||
            c == 0x0F97 ||
            (c >= 0x0F99 && c <= 0x0FAD) ||
            (c >= 0x0FB1 && c <= 0x0FB7) ||
            c == 0x0FB9 ||
            (c >= 0x20D0 && c <= 0x20DC) ||
            c == 0x20E1 ||
            (c >= 0x302A && c <= 0x302F) ||
            c == 0x3099 ||
            c == 0x309A);
  }

  /**
   * Indicates whether the specified Unicode character matches the Extender
   * production.
   */
  public static boolean isExtender(int c)
  {
    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));
  }

  /**
   * Indicates whether the specified Unicode character matches the Char
   * production.
   */
  public static boolean isChar(int c)
  {
    return (c >= 0x20 && c < 0xd800) ||
      (c >= 0xe00 && c < 0xfffe) ||
      (c >= 0x10000 && c < 0x110000) ||
      c == 0xa || c == 0x9 || c == 0xd;
  }
  
  /**
   * Interns the specified text or not, depending on the value of
   * stringInterning.
   */
  private String intern(String text)
  {
    return stringInterning ? text.intern() : text;
  }

  /**
   * Report a parsing error.
   */
  private void error(String message)
    throws XMLStreamException
  {
    error(message, null);
  }
  
  /**
   * Report a parsing error.
   */
  private void error(String message, Object info)
    throws XMLStreamException
  {
    if (info != null)
      {
        if (info instanceof String)
          message += ": \"" + ((String) info) + "\"";
        else if (info instanceof Character)
          message += ": '" + ((Character) info) + "'";
      }
    throw new XMLStreamException(message);
  }

  /**
   * Perform validation of a start-element event.
   */
  private void validateStartElement(String elementName)
    throws XMLStreamException
  {
    if (currentContentModel == null)
      {
        // root element
        // VC: Root Element Type
        if (!elementName.equals(doctype.rootName))
          error("root element name must match name in DTD");
        return;
      }
    // VC: Element Valid
    switch (currentContentModel.type)
      {
      case ContentModel.EMPTY:
        error("child element found in empty element", elementName);
        break;
      case ContentModel.ELEMENT:
        LinkedList ctx = (LinkedList) validationStack.getLast();
        ctx.add(elementName);
        break;
      case ContentModel.MIXED:
        MixedContentModel mm = (MixedContentModel) currentContentModel;
        if (!mm.containsName(elementName))
          error("illegal element for content model", elementName);
        break;
      }
  }

  /**
   * Perform validation of an end-element event.
   */
  private void validateEndElement()
    throws XMLStreamException
  {
    if (currentContentModel == null)
      {
        // root element
        // VC: IDREF
        if (!idrefs.containsAll(ids))
          error("IDREF values must match the value of some ID attribute");
        return;
      }
    // VC: Element Valid
    switch (currentContentModel.type)
      {
      case ContentModel.ELEMENT:
        LinkedList ctx = (LinkedList) validationStack.getLast();
        ElementContentModel ecm = (ElementContentModel) currentContentModel;
        validateElementContent(ecm, ctx);
        break;
      }
  }

  /**
   * Perform validation of character data.
   */
  private void validatePCData(String text)
    throws XMLStreamException
  {
    // VC: Element Valid
    switch (currentContentModel.type)
      {
      case ContentModel.EMPTY:
        error("character data found in empty element", text);
        break;
      case ContentModel.ELEMENT:
        boolean white = true;
        int len = text.length();
        for (int i = 0; i < len; i++)
          {
            char c = text.charAt(i);
            if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
              {
                white = false;
                break;
              }
          }
        if (!white)
          error("character data found in element with element content", text);
        else if (xmlStandalone == Boolean.TRUE && currentContentModel.external)
          // VC: Standalone Document Declaration
          error("whitespace in element content of externally declared " +
                "element in standalone document");
        break;
      }
  }

  /**
   * Validates the specified validation context (list of child elements)
   * against the element content model for the current element.
   */
  private void validateElementContent(ElementContentModel model,
                                      LinkedList children)
    throws XMLStreamException
  {
    // Use regular expression
    StringBuffer buf = new StringBuffer();
    for (Iterator i = children.iterator(); i.hasNext(); )
      {
        buf.append((String) i.next());
        buf.append(' ');
      }
    String c = buf.toString();
    String regex = createRegularExpression(model);
    if (!c.matches(regex))
      error("element content "+model.text+" does not match expression "+regex, c);
  }

  /**
   * Creates the regular expression used to validate an element content
   * model.
   */
  private String createRegularExpression(ElementContentModel model)
  {
    if (model.regex == null)
      {
        StringBuffer buf = new StringBuffer();
        buf.append('(');
        for (Iterator i = model.contentParticles.iterator(); i.hasNext(); )
          {
            ContentParticle cp = (ContentParticle) i.next();
            if (cp.content instanceof String)
              {
                buf.append('(');
                buf.append((String) cp.content);
                buf.append(' ');
                buf.append(')');
                if (cp.max == -1)
                  {
                    if (cp.min == 0)
                      buf.append('*');
                    else
                      buf.append('+');
                  }
                else if (cp.min == 0)
                  buf.append('?');
              }
            else
              {
                ElementContentModel ecm = (ElementContentModel) cp.content;
                buf.append(createRegularExpression(ecm));
              }
            if (model.or && i.hasNext())
              buf.append('|');
          }
        buf.append(')');
        if (model.max == -1)
          {
            if (model.min == 0)
              buf.append('*');
            else
              buf.append('+');
          }
        else if (model.min == 0)
          buf.append('?');
        model.regex = buf.toString();
      }
    return model.regex;
  }

  /**
   * Performs validation of a document type declaration event.
   */
  void validateDoctype()
    throws XMLStreamException
  {
    for (Iterator i = doctype.entityIterator(); i.hasNext(); )
      {
        Map.Entry entry = (Map.Entry) i.next();
        Object entity = entry.getValue();
        if (entity instanceof ExternalIds)
          {
            ExternalIds ids = (ExternalIds) entity;
            if (ids.notationName != null)
              {
                // VC: Notation Declared
                ExternalIds notation = doctype.getNotation(ids.notationName);
                if (notation == null)
                  error("Notation name must match the declared name of a " +
                        "notation", ids.notationName);
              }
          }
      }
  }

  /**
   * Simple test harness for reading an XML file.
   * args[0] is the filename of the XML file
   * If args[1] is "-x", enable XInclude processing
   */
  public static void main(String[] args)
    throws Exception
  {
    boolean validating = false;
    boolean namespaceAware = false;
    boolean xIncludeAware = false;
    int pos = 0;
    while (pos < args.length && args[pos].startsWith("-"))
      {
        if ("-x".equals(args[pos]))
          xIncludeAware = true;
        else if ("-v".equals(args[pos]))
          validating = true;
        else if ("-n".equals(args[pos]))
          namespaceAware = true;
        pos++;
      }
    if (pos >= args.length)
      {
        System.out.println("Syntax: XMLParser [-n] [-v] [-x] <file> [<file2> [...]]");
        System.out.println("\t-n: use namespace aware mode");
        System.out.println("\t-v: use validating parser");
        System.out.println("\t-x: use XInclude aware mode");
        System.exit(2);
      }
    while (pos < args.length)
      {
        XMLParser p = new XMLParser(new java.io.FileInputStream(args[pos]),
                                    absolutize(null, args[pos]),
                                    validating, // validating
                                    namespaceAware, // namespaceAware
                                    true, // coalescing,
                                    true, // replaceERefs
                                    true, // externalEntities
                                    true, // supportDTD
                                    true, // baseAware
                                    true, // stringInterning
                                    true, // extendedEventTypes
                                    null,
                                    null);
        XMLStreamReader reader = p;
        if (xIncludeAware)
          reader = new XIncludeFilter(p, args[pos], true, true, true);
        try
          {
            int event;
            //do
            while (reader.hasNext())
              {
                event = reader.next();
                Location loc = reader.getLocation();
                System.out.print(loc.getLineNumber() + ":" + 
                                 loc.getColumnNumber() + " ");
                switch (event)
                  {
                  case XMLStreamConstants.START_DOCUMENT:
                    System.out.println("START_DOCUMENT version=" +
                                       reader.getVersion() +
                                       " encoding=" +
                                       reader.getEncoding());
                    break;
                  case XMLStreamConstants.END_DOCUMENT:
                    System.out.println("END_DOCUMENT");
                    break;
                  case XMLStreamConstants.START_ELEMENT:
                    System.out.println("START_ELEMENT " +
                                       reader.getName());
                    int l = reader.getNamespaceCount();
                    for (int i = 0; i < l; i++)
                      System.out.println("\tnamespace " +
                                         reader.getNamespacePrefix(i) + "='" +
                                         reader.getNamespaceURI(i)+"'");
                    l = reader.getAttributeCount();
                    for (int i = 0; i < l; i++)
                      System.out.println("\tattribute " +
                                         reader.getAttributeName(i) + "='" +
                                         reader.getAttributeValue(i) + "'");
                    break;
                  case XMLStreamConstants.END_ELEMENT:
                    System.out.println("END_ELEMENT " + reader.getName());
                    break;
                  case XMLStreamConstants.CHARACTERS:
                    System.out.println("CHARACTERS '" +
                                       encodeText(reader.getText()) + "'");
                    break;
                  case XMLStreamConstants.CDATA:
                    System.out.println("CDATA '" +
                                       encodeText(reader.getText()) + "'");
                    break;
                  case XMLStreamConstants.SPACE:
                    System.out.println("SPACE '" +
                                       encodeText(reader.getText()) + "'");
                    break;
                  case XMLStreamConstants.DTD:
                    System.out.println("DTD " + reader.getText());
                    break;
                  case XMLStreamConstants.ENTITY_REFERENCE:
                    System.out.println("ENTITY_REFERENCE " + reader.getText());
                    break;
                  case XMLStreamConstants.COMMENT:
                    System.out.println("COMMENT '" +
                                       encodeText(reader.getText()) + "'");
                    break;
                  case XMLStreamConstants.PROCESSING_INSTRUCTION:
                    System.out.println("PROCESSING_INSTRUCTION " +
                                       reader.getPITarget() + " " +
                                       reader.getPIData());
                    break;
                  case START_ENTITY:
                    System.out.println("START_ENTITY " + reader.getText());
                    break;
                  case END_ENTITY:
                    System.out.println("END_ENTITY " + reader.getText());
                    break;
                  default:
                    System.out.println("Unknown event: " + event);
                  }
              }
          }
        catch (XMLStreamException e)
          {
            Location l = reader.getLocation();
            System.out.println("At line "+l.getLineNumber()+
                               ", column "+l.getColumnNumber()+
                               " of "+l.getSystemId());
            throw e;
          }
        pos++;
      }
  }

  /**
   * Escapes control characters in the specified text. For debugging.
   */
  private static String encodeText(String text)
  {
    StringBuffer b = new StringBuffer();
    int len = text.length();
    for (int i = 0; i < len; i++)
      {
        char c = text.charAt(i);
        switch (c)
          {
          case '\t':
            b.append("\\t");
            break;
          case '\n':
            b.append("\\n");
            break;
          case '\r':
            b.append("\\r");
            break;
          default:
            b.append(c);
          }
      }
    return b.toString();
  }

  /**
   * An attribute instance.
   */
  class Attribute
  {

    /**
     * Attribute name.
     */
    final String name;

    /**
     * Attribute type as declared in the DTD, or CDATA otherwise.
     */
    final String type;

    /**
     * Whether the attribute was specified or defaulted.
     */
    final boolean specified;

    /**
     * The attribute value.
     */
    final String value;

    /**
     * The namespace prefix.
     */
    final String prefix;

    /**
     * The namespace local-name.
     */
    final String localName;

    Attribute(String name, String type, boolean specified, String value)
    {
      this.name = name;
      this.type = type;
      this.specified = specified;
      this.value = value;
      int ci = name.indexOf(':');
      if (ci == -1)
        {
          prefix = null;
          localName = intern(name);
        }
      else
        {
          prefix = intern(name.substring(0, ci));
          localName = intern(name.substring(ci + 1));
        }
    }

    public boolean equals(Object other)
    {
      if (other instanceof Attribute)
        {
          Attribute a = (Attribute) other;
          if (namespaceAware)
            {
              if (!a.localName.equals(localName))
                return false;
              String auri = getNamespaceURI(a.prefix);
              String uri = getNamespaceURI(prefix);
              if (uri == null && (auri == null ||
                                  (input.xml11 && "".equals(auri))))
               return true; 
              if (uri != null)
                {
                  if ("".equals(uri) && input.xml11 && "".equals(auri))
                    return true;
                  return uri.equals(auri);
                }
              return false;
            }
          else
            return a.name.equals(name);
        }
      return false;
    }
    
  }

  /**
   * Representation of a DTD.
   */
  class Doctype
  {

    /**
     * Name of the root element.
     */
    final String rootName;

    /**
     * Public ID, if any, of external subset.
     */
    final String publicId;

    /**
     * System ID (URL), if any, of external subset.
     */
    final String systemId;

    /**
     * Map of element names to content models.
     */
    private final LinkedHashMap elements = new LinkedHashMap();

    /**
     * Map of element names to maps of attribute declarations.
     */
    private final LinkedHashMap attlists = new LinkedHashMap();

    /**
     * Map of entity names to entities (String or ExternalIds).
     */
    private final LinkedHashMap entities = new LinkedHashMap();

    /**
     * Map of notation names to ExternalIds.
     */
    private final LinkedHashMap notations = new LinkedHashMap();

    /**
     * Map of anonymous keys to comments.
     */    
    private final LinkedHashMap comments = new LinkedHashMap();

    /**
     * Map of anonymous keys to processing instructions (String[2]
     * containing {target, data}).
     */
    private final LinkedHashMap pis = new LinkedHashMap();

    /**
     * List of keys to all markup entries in the DTD.
     */
    private final LinkedList entries = new LinkedList();

    /**
     * Set of the entities defined in the external subset.
     */
    private final HashSet externalEntities = new HashSet();

    /**
     * Set of the notations defined in the external subset.
     */
    private final HashSet externalNotations = new HashSet();

    /**
     * Counter for making anonymous keys.
     */
    private int anon = 1;

    /**
     * Constructor.
     */
    Doctype(String rootName, String publicId, String systemId)
    {
      this.rootName = rootName;
      this.publicId = publicId;
      this.systemId = systemId;
    }

    /**
     * Adds an element declaration.
     * @param name the element name
     * @param text the content model text
     * @param model the parsed content model
     */
    void addElementDecl(String name, String text, ContentModel model)
    {
      if (elements.containsKey(name))
        return;
      model.text = text;
      model.external = (inputStack.size() != 1);
      elements.put(name, model);
      entries.add("E" + name);
    }

    /**
     * Adds an attribute declaration.
     * @param ename the element name
     * @param aname the attribute name
     * @param decl the attribute declaration details
     */
    void addAttributeDecl(String ename, String aname, AttributeDecl decl)
    {
      LinkedHashMap attlist = (LinkedHashMap) attlists.get(ename);
      if (attlist == null)
        {
          attlist = new LinkedHashMap();
          attlists.put(ename, attlist);
        }
      else if (attlist.containsKey(aname))
        return;
      attlist.put(aname, decl);
      String key = "A" + ename;
      if (!entries.contains(key))
        entries.add(key);
    }

    /**
     * Adds an entity declaration.
     * @param name the entity name
     * @param text the entity replacement text
     * @param inExternalSubset if we are in the exernal subset
     */
    void addEntityDecl(String name, String text, boolean inExternalSubset)
    {
      if (entities.containsKey(name))
        return;
      entities.put(name, text);
      entries.add("e" + name);
      if (inExternalSubset)
        externalEntities.add(name);
    }
    
    /**
     * Adds an entity declaration.
     * @param name the entity name
     * @param ids the external IDs
     * @param inExternalSubset if we are in the exernal subset
     */
    void addEntityDecl(String name, ExternalIds ids, boolean inExternalSubset)
    {
      if (entities.containsKey(name))
        return;
      entities.put(name, ids);
      entries.add("e" + name);
      if (inExternalSubset)
        externalEntities.add(name);
    }

    /**
     * Adds a notation declaration.
     * @param name the notation name
     * @param ids the external IDs
     * @param inExternalSubset if we are in the exernal subset
     */
    void addNotationDecl(String name, ExternalIds ids, boolean inExternalSubset)
    {
      if (notations.containsKey(name))
        return;
      notations.put(name, ids);
      entries.add("n" + name);
      if (inExternalSubset)
        externalNotations.add(name);
    }

    /**
     * Adds a comment.
     */
    void addComment(String text)
    {
      String key = Integer.toString(anon++);
      comments.put(key, text);
      entries.add("c" + key);
    }

    /**
     * Adds a processing instruction.
     */
    void addPI(String target, String data)
    {
      String key = Integer.toString(anon++);
      pis.put(key, new String[] {target, data});
      entries.add("p" + key);
    }

    /**
     * Returns the content model for the specified element.
     * @param name the element name
     */
    ContentModel getElementModel(String name)
    {
      return (ContentModel) elements.get(name);
    }

    /**
     * Returns the attribute definition for the given attribute
     * @param ename the element name
     * @param aname the attribute name
     */
    AttributeDecl getAttributeDecl(String ename, String aname)
    {
      LinkedHashMap attlist = (LinkedHashMap) attlists.get(ename);
      return (attlist == null) ? null : (AttributeDecl) attlist.get(aname);
    }

    /**
     * Indicates whether the specified attribute was declared in the DTD.
     * @param ename the element name
     * @param aname the attribute name
     */
    boolean isAttributeDeclared(String ename, String aname)
    {
      LinkedHashMap attlist = (LinkedHashMap) attlists.get(ename);
      return (attlist == null) ? false : attlist.containsKey(aname);
    }

    /**
     * Returns an iterator over the entries in the attribute list for the
     * given element.
     * @param ename the element name
     */
    Iterator attlistIterator(String ename)
    {
      LinkedHashMap attlist = (LinkedHashMap) attlists.get(ename);
      return (attlist == null) ? Collections.EMPTY_LIST.iterator() :
        attlist.entrySet().iterator();
    }

    /**
     * Returns the entity (String or ExternalIds) for the given entity name.
     */
    Object getEntity(String name)
    {
      return entities.get(name);
    }

    /**
     * Indicates whether the specified entity was declared in the external
     * subset.
     */
    boolean isEntityExternal(String name)
    {
      return externalEntities.contains(name);
    }

    /**
     * Returns an iterator over the entity map entries.
     */
    Iterator entityIterator()
    {
      return entities.entrySet().iterator();
    }

    /**
     * Returns the notation IDs for the given notation name.
     */
    ExternalIds getNotation(String name)
    {
      return (ExternalIds) notations.get(name);
    }

    /**
     * Indicates whether the specified notation was declared in the external
     * subset.
     */
    boolean isNotationExternal(String name)
    {
      return externalNotations.contains(name);
    }

    /**
     * Returns the comment associated with the specified (anonymous) key.
     */
    String getComment(String key)
    {
      return (String) comments.get(key);
    }

    /**
     * Returns the processing instruction associated with the specified
     * (anonymous) key.
     */
    String[] getPI(String key)
    {
      return (String[]) pis.get(key);
    }

    /**
     * Returns an iterator over the keys of the markup entries in this DTD,
     * in the order declared.
     */
    Iterator entryIterator()
    {
      return entries.iterator();
    }
    
  }

  /**
   * Combination of an ExternalID and an optional NDataDecl.
   */
  class ExternalIds
  {

    /**
     * The public ID.
     */
    String publicId;

    /**
     * The system ID.
     */
    String systemId;

    /**
     * The notation name declared with the NDATA keyword.
     */
    String notationName;
  }

  /**
   * A content model.
   */
  abstract class ContentModel
  {
    static final int EMPTY = 0;
    static final int ANY = 1;
    static final int ELEMENT = 2;
    static final int MIXED = 3;
    
    int min;
    int max;
    final int type;
    String text;
    boolean external;

    ContentModel(int type)
    {
      this.type = type;
      min = 1;
      max = 1;
    }
    
  }

  /**
   * The EMPTY content model.
   */
  class EmptyContentModel
    extends ContentModel
  {
    
    EmptyContentModel()
    {
      super(ContentModel.EMPTY);
      min = 0;
      max = 0;
    }
    
  }

  /**
   * The ANY content model.
   */
  class AnyContentModel
    extends ContentModel
  {
    
    AnyContentModel()
    {
      super(ContentModel.ANY);
      min = 0;
      max = -1;
    }
    
  }

  /**
   * An element content model.
   */
  class ElementContentModel
    extends ContentModel
  {

    LinkedList contentParticles;
    boolean or;
    String regex; // regular expression cache
    
    ElementContentModel()
    {
      super(ContentModel.ELEMENT);
      contentParticles = new LinkedList();
    }

    void addContentParticle(ContentParticle cp)
    {
      contentParticles.add(cp);
    }
    
  }

  class ContentParticle
  {

    int min = 1;
    int max = 1;
    Object content; // Name (String) or ElementContentModel
    
  }

  /**
   * A mixed content model.
   */
  class MixedContentModel
    extends ContentModel
  {

    private HashSet names;
    
    MixedContentModel()
    {
      super(ContentModel.MIXED);
      names = new HashSet();
    }

    void addName(String name)
    {
      names.add(name);
    }

    boolean containsName(String name)
    {
      return names.contains(name);
    }
    
  }

  /**
   * An attribute definition.
   */
  class AttributeDecl
  {
    
    /**
     * The attribute type (CDATA, ID, etc).
     */
    final String type;

    /**
     * The default value.
     */
    final String value;

    /**
     * The value type (#FIXED, #IMPLIED, etc).
     */
    final int valueType;

    /**
     * The enumeration text.
     */
    final String enumeration;

    /**
     * The enumeration tokens.
     */
    final HashSet values;

    /**
     * Whether this attribute declaration occurred in the external subset.
     */
    final boolean external;

    AttributeDecl(String type, String value,
                  int valueType, String enumeration,
                  HashSet values, boolean external)
    {
      this.type = type;
      this.value = value;
      this.valueType = valueType;
      this.enumeration = enumeration;
      this.values = values;
      this.external = external;
    }
    
  }

  /**
   * An XML input source.
   */
  static class Input
    implements Location
  {
    
    int line = 1, markLine;
    int column, markColumn;
    int offset, markOffset;
    final String publicId, systemId, name;
    final boolean report; // report start- and end-entity
    final boolean normalize; // normalize CR, etc to LF
    
    InputStream in;
    Reader reader;
    UnicodeReader unicodeReader;
    boolean initialized;
    boolean encodingDetected;
    String inputEncoding;
    boolean xml11;

    Input(InputStream in, Reader reader, String publicId, String systemId,
          String name, String inputEncoding, boolean report,
          boolean normalize)
    {
      if (inputEncoding == null)
        inputEncoding = "UTF-8";
      this.inputEncoding = inputEncoding;
      this.publicId = publicId;
      this.systemId = systemId;
      this.name = name;
      this.report = report;
      this.normalize = normalize;
      if (in != null)
        {
          if (reader != null)
            throw new IllegalStateException("both byte and char streams "+
                                            "specified");
          if (normalize)
            in = new CRLFInputStream(in);
          in = new BufferedInputStream(in);
          this.in = in;
        }
      else
        {
          this.reader = normalize ? new CRLFReader(reader) : reader;
          unicodeReader = new UnicodeReader(this.reader);
        }
      initialized = false;
    }

    // -- Location --
    
    public int getCharacterOffset()
    {
      return offset;
    }
    
    public int getColumnNumber()
    {
      return column;
    }

    public int getLineNumber()
    {
      return line;
    }

    public String getPublicId()
    {
      return publicId;
    }

    public String getSystemId()
    {
      return systemId;
    }

    void init()
      throws IOException
    {
      if (initialized)
        return;
      if (in != null)
        detectEncoding();
      initialized = true;
    }

    void mark(int len)
      throws IOException
    {
      markOffset = offset;
      markLine = line;
      markColumn = column;
      if (unicodeReader != null)
        unicodeReader.mark(len);
      else
        in.mark(len);
    }

    /**
     * Character read.
     */
    int read()
      throws IOException
    {
      offset++;
      int ret = (unicodeReader != null) ? unicodeReader.read() : in.read();
      if (normalize &&
          (ret == 0x0d || (xml11 && (ret == 0x85 || ret == 0x2028))))
        {
          // Normalize CR etc to LF
          ret = 0x0a;
        }
      // Locator handling
      if (ret == 0x0a)
        {
          line++;
          column = 0;
        }
      else
        column++;
      return ret;
    }

    /**
     * Block read.
     */
    int read(int[] b, int off, int len)
      throws IOException
    {
      int ret;
      if (unicodeReader != null)
        {
          ret = unicodeReader.read(b, off, len);
        }
      else
        {
          byte[] b2 = new byte[len];
          ret = in.read(b2, 0, len);
          if (ret != -1)
            {
              String s = new String(b2, 0, ret, inputEncoding);
              int[] c = UnicodeReader.toCodePointArray(s);
              ret = c.length;
              System.arraycopy(c, 0, b, off, ret);
            }
        }
      if (ret != -1)
        {
          // Locator handling
          for (int i = 0; i < ret; i++)
            {
              int c = b[off + i];
              if (normalize &&
                  (c == 0x0d || (xml11 && (c == 0x85 || c == 0x2028))))
                {
                  // Normalize CR etc to LF
                  c = 0x0a;
                  b[off + i] = c;
                }
              if (c == 0x0a)
                {
                  line++;
                  column = 0;
                }
              else
                column++;
            }
        }
      return ret;
    }

    void reset()
      throws IOException
    {
      if (unicodeReader != null)
        unicodeReader.reset();
      else
        in.reset();
      offset = markOffset;
      line = markLine;
      column = markColumn;
    }

    // Detection of input encoding
    
    private static final int[] SIGNATURE_UCS_4_1234 =
      new int[] { 0x00, 0x00, 0x00, 0x3c };
    private static final int[] SIGNATURE_UCS_4_4321 =
      new int[] { 0x3c, 0x00, 0x00, 0x00 };
    private static final int[] SIGNATURE_UCS_4_2143 =
      new int[] { 0x00, 0x00, 0x3c, 0x00 };
    private static final int[] SIGNATURE_UCS_4_3412 =
      new int[] { 0x00, 0x3c, 0x00, 0x00 };
    private static final int[] SIGNATURE_UCS_2_12 =
      new int[] { 0xfe, 0xff };
    private static final int[] SIGNATURE_UCS_2_21 =
      new int[] { 0xff, 0xfe };
    private static final int[] SIGNATURE_UCS_2_12_NOBOM =
      new int[] { 0x00, 0x3c, 0x00, 0x3f };
    private static final int[] SIGNATURE_UCS_2_21_NOBOM =
      new int[] { 0x3c, 0x00, 0x3f, 0x00 };
    private static final int[] SIGNATURE_UTF_8 =
      new int[] { 0x3c, 0x3f, 0x78, 0x6d };
    private static final int[] SIGNATURE_UTF_8_BOM =
      new int[] { 0xef, 0xbb, 0xbf };
    
    /**
     * Detect the input encoding.
     */
    private void detectEncoding()
      throws IOException
    {
      int[] signature = new int[4];
      in.mark(4);
      for (int i = 0; i < 4; i++)
        signature[i] = in.read();
      in.reset();

      // 4-byte encodings
      if (equals(SIGNATURE_UCS_4_1234, signature))
        {
          in.read();
          in.read();
          in.read();
          in.read();
          setInputEncoding("UTF-32BE");
          encodingDetected = true;
        }
      else if (equals(SIGNATURE_UCS_4_4321, signature))
        {
          in.read();
          in.read();
          in.read();
          in.read();
          setInputEncoding("UTF-32LE");
          encodingDetected = true;
        }
      else if (equals(SIGNATURE_UCS_4_2143, signature) ||
               equals(SIGNATURE_UCS_4_3412, signature))
        throw new UnsupportedEncodingException("unsupported UCS-4 byte ordering");
      
      // 2-byte encodings
      else if (equals(SIGNATURE_UCS_2_12, signature))
        {
          in.read();
          in.read();
          setInputEncoding("UTF-16BE");
          encodingDetected = true;
        }
      else if (equals(SIGNATURE_UCS_2_21, signature))
        {
          in.read();
          in.read();
          setInputEncoding("UTF-16LE");
          encodingDetected = true;
        }
      else if (equals(SIGNATURE_UCS_2_12_NOBOM, signature))
        {
          //setInputEncoding("UTF-16BE");
          throw new UnsupportedEncodingException("no byte-order mark for UCS-2 entity");
        }
      else if (equals(SIGNATURE_UCS_2_21_NOBOM, signature))
        {
          //setInputEncoding("UTF-16LE");
          throw new UnsupportedEncodingException("no byte-order mark for UCS-2 entity");
        }
      // ASCII-derived encodings
      else if (equals(SIGNATURE_UTF_8, signature))
        {
          // UTF-8 input encoding implied, TextDecl
        }
      else if (equals(SIGNATURE_UTF_8_BOM, signature))
        {
          in.read();
          in.read();
          in.read();
          setInputEncoding("UTF-8");
          encodingDetected = true;
        }
    }

    private static boolean equals(int[] b1, int[] b2)
    {
      for (int i = 0; i < b1.length; i++)
        {
          if (b1[i] != b2[i])
            return false;
        }
      return true;
    }
    
    void setInputEncoding(String encoding)
      throws IOException
    {
      if (encoding.equals(inputEncoding))
        return;
      if ("UTF-16".equalsIgnoreCase(encoding) &&
          inputEncoding.startsWith("UTF-16"))
        return;
      if (encodingDetected)
        throw new UnsupportedEncodingException("document is not in its " +
                                               "declared encoding " +
                                               inputEncoding +
                                               ": " + encoding);
      inputEncoding = encoding;
      finalizeEncoding();
    }

    void finalizeEncoding()
      throws IOException
    {
      if (reader != null)
        return;
      reader = new BufferedReader(new InputStreamReader(in, inputEncoding));
      unicodeReader = new UnicodeReader(reader);
      mark(1);
    }

  }

}

