/* 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 gnu.java.lang.CPStringBuilder;

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;

  /**
   * 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;
          }
      }
    systemId = canonicalize(systemId);
    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;
          }
      }
    systemId = canonicalize(systemId);
    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");
    CPStringBuilder elementText = new CPStringBuilder();
    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(':');
        String localName = (ci == -1) ? qName : qName.substring(ci + 1);
        if (stringInterning)
          localName = localName.intern();
        return localName;
      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);
        if (stringInterning)
          localName = localName.intern();
        String prefix = (ci == -1) ?
          (namespaceAware ? XMLConstants.DEFAULT_NS_PREFIX : null) :
          qName.substring(0, ci);
        if (stringInterning && prefix != null)
          prefix = prefix.intern();
        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(':');
        String prefix = (ci == -1) ?
          (namespaceAware ? XMLConstants.DEFAULT_NS_PREFIX : null) :
          qName.substring(0, ci);
        if (stringInterning && prefix != null)
          prefix = prefix.intern();
        return prefix;
      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
  {
    return (event != XMLStreamConstants.END_DOCUMENT && event != -1);
  }

  public int next()
    throws XMLStreamException
  {
    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 = canonicalize(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;
  }

  /**
   * Returns a canonicalized version of the specified URL.
   * This is largely to work around a problem with the specification of
   * file URLs.
   */
  static String canonicalize(String url)
  {
    if (url == null)
      return null;
    if (url.startsWith("file:") && !url.startsWith("file://"))
      url = "file://" + url.substring(5);
    return url;
  }

  /**
   * "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)
  {
    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 += "/";
      }
    // We can't use java.net.URL here to do the parsing, as it searches for
    // a protocol handler. A protocol handler may not be registered for the
    // URL scheme here. Do it manually.
    //
    // Set aside scheme and host portion of base URL
    String basePrefix = null;
    ci = base.indexOf(':');
    if (ci > 1 && isURLScheme(base.substring(0, ci)))
      {
          if (base.length() > (ci + 3)  &&
              base.charAt(ci + 1) == '/' &&
              base.charAt(ci + 2) == '/')
            {
              int si = base.indexOf('/', ci + 3);
              if (si == -1)
                base = null;
              else
                {
                  basePrefix = base.substring(0, si);
                  base = base.substring(si);
                }
            }
          else
            base = null;
      }
    if (base == null) // unknown or malformed base URL, use href
      return href;
    if (href.startsWith("/")) // absolute href pathname
      return (basePrefix == null) ? href : basePrefix + href;
    // relative href pathname
    if (!base.endsWith("/"))
      {
        int lsi = base.lastIndexOf('/');
        if (lsi == -1)
          base = "/";
        else
          base = base.substring(0, lsi + 1);
      }
    while (href.startsWith("../") || href.startsWith("./"))
      {
        if (href.startsWith("../"))
          {
            // strip last path component from base
            int lsi = base.lastIndexOf('/', base.length() - 2);
            if (lsi > -1)
              base = base.substring(0, lsi + 1);
            href = href.substring(3); // strip ../ prefix
          }
        else
          {
            href = href.substring(2); // strip ./ prefix
          }
      }
    return (basePrefix == null) ? base + href : basePrefix + base + href;
  }

  /**
   * 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;
        CPStringBuilder acc = new CPStringBuilder();
        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(CPStringBuilder 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(CPStringBuilder 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();
    CPStringBuilder acc = new CPStringBuilder();
    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(CPStringBuilder 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, CPStringBuilder 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(CPStringBuilder 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
  {
    CPStringBuilder b = new CPStringBuilder();
    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
    CPStringBuilder buf = new CPStringBuilder();
    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)
      {
        CPStringBuilder buf = new CPStringBuilder();
        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)
  {
    CPStringBuilder b = new CPStringBuilder();
    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;
    }

    public String toString()
    {
      CPStringBuilder buf = new CPStringBuilder(getClass().getName());
      buf.append('[');
      buf.append("name=");
      buf.append(name);
      if (value != null)
        {
          buf.append(",value=");
          buf.append(value);
        }
      if (type != null)
        {
          buf.append(",type=");
          buf.append(type);
        }
      if (specified)
        buf.append(",specified");
      buf.append(']');
      return buf.toString();
    }

  }

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

  }

}
