/*
 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 */

/*
 * Copyright 2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sun.org.apache.xerces.internal.impl;


import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
import com.sun.org.apache.xerces.internal.util.XMLChar;
import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XMLString;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.xml.internal.stream.Entity;
import com.sun.xml.internal.stream.StaxXMLInputSource;
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
import java.io.EOFException;
import java.io.IOException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.XMLEvent;


/**
 * This class is responsible for scanning XML document structure
 * and content.
 *
 * This class has been modified as per the new design which is more suited to
 * efficiently build pull parser. Lot of improvements have been done and
 * the code has been added to support stax functionality/features.
 *
 * @author Neeraj Bajaj, Sun Microsystems
 * @author K.Venugopal, Sun Microsystems
 * @author Glenn Marcy, IBM
 * @author Andy Clark, IBM
 * @author Arnaud  Le Hors, IBM
 * @author Eric Ye, IBM
 * @author Sunitha Reddy, Sun Microsystems
 *
 * Refer to the table in unit-test javax.xml.stream.XMLStreamReaderTest.SupportDTD for changes
 * related to property SupportDTD.
 * @author Joe Wang, Sun Microsystems
 * @version $Id: XMLDocumentScannerImpl.java,v 1.17 2010-11-01 04:39:41 joehw Exp $
 */
public class XMLDocumentScannerImpl
        extends XMLDocumentFragmentScannerImpl{

    //
    // Constants
    //

    // scanner states

    /** Scanner state: XML declaration. */
    protected static final int SCANNER_STATE_XML_DECL = 42;

    /** Scanner state: prolog. */
    protected static final int SCANNER_STATE_PROLOG = 43;

    /** Scanner state: trailing misc. */
    protected static final int SCANNER_STATE_TRAILING_MISC = 44;

    /** Scanner state: DTD internal declarations. */
    protected static final int SCANNER_STATE_DTD_INTERNAL_DECLS = 45;

    /** Scanner state: open DTD external subset. */
    protected static final int SCANNER_STATE_DTD_EXTERNAL = 46;

    /** Scanner state: DTD external declarations. */
    protected static final int SCANNER_STATE_DTD_EXTERNAL_DECLS = 47;

    /** Scanner state: NO MORE ELEMENTS. */
    protected static final int SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION = 48;

    // feature identifiers

    /** Property identifier document scanner: */
    protected static final String DOCUMENT_SCANNER =
            Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY;

    /** Feature identifier: load external DTD. */
    protected static final String LOAD_EXTERNAL_DTD =
            Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;

    /** Feature identifier: load external DTD. */
    protected static final String DISALLOW_DOCTYPE_DECL_FEATURE =
            Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;

    // property identifiers

    /** Property identifier: DTD scanner. */
    protected static final String DTD_SCANNER =
            Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY;

    // property identifier:  ValidationManager
    protected static final String VALIDATION_MANAGER =
            Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;

    /** property identifier:  NamespaceContext */
    protected static final String NAMESPACE_CONTEXT =
        Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY;

    // recognized features and properties

    /** Recognized features. */
    private static final String[] RECOGNIZED_FEATURES = {
        LOAD_EXTERNAL_DTD,
                DISALLOW_DOCTYPE_DECL_FEATURE,
    };

    /** Feature defaults. */
    private static final Boolean[] FEATURE_DEFAULTS = {
        Boolean.TRUE,
                Boolean.FALSE,
    };

    /** Recognized properties. */
    private static final String[] RECOGNIZED_PROPERTIES = {
        DTD_SCANNER,
                VALIDATION_MANAGER
    };

    /** Property defaults. */
    private static final Object[] PROPERTY_DEFAULTS = {
            null,
                null
    };

    //
    // Data((Boolean)propertyManager.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE)).booleanValue();
    //

    // properties

    /** DTD scanner. */
    protected XMLDTDScanner fDTDScanner = null;

    /** Validation manager . */
    //xxx: fValidationManager code needs to be added yet!
    protected ValidationManager fValidationManager;

    protected XMLStringBuffer fDTDDecl = null;
    protected boolean fReadingDTD = false;
    protected boolean fAddedListener = false;

    // protected data

    // other info

    /** Doctype name. */
    protected String fDoctypeName;

    /** Doctype declaration public identifier. */
    protected String fDoctypePublicId;

    /** Doctype declaration system identifier. */
    protected String fDoctypeSystemId;

    /** Namespace support. */
    protected NamespaceContext fNamespaceContext = new NamespaceSupport();

    // features

    /** Load external DTD. */
    protected boolean fLoadExternalDTD = true;

    // state

    /** Seen doctype declaration. */
    protected boolean fSeenDoctypeDecl;

    protected boolean fScanEndElement;

    //protected int fScannerLastState ;

    // drivers

    /** XML declaration driver. */
    protected Driver fXMLDeclDriver = new XMLDeclDriver();

    /** Prolog driver. */
    protected Driver fPrologDriver = new PrologDriver();

    /** DTD driver. */
    protected Driver fDTDDriver = null ;

    /** Trailing miscellaneous section driver. */
    protected Driver fTrailingMiscDriver = new TrailingMiscDriver();
    protected int fStartPos = 0;
    protected int fEndPos = 0;
    protected boolean fSeenInternalSubset= false;
    // temporary variables

    /** Array of 3 strings. */
    private String[] fStrings = new String[3];

    /** External subset source. */
    private XMLInputSource fExternalSubsetSource = null;

    /** A DTD Description. */
    private final XMLDTDDescription fDTDDescription = new XMLDTDDescription(null, null, null, null, null);

    /** String. */
    private XMLString fString = new XMLString();

    private static final char [] DOCTYPE = {'D','O','C','T','Y','P','E'};
    private static final char [] COMMENTSTRING = {'-','-'};

    //
    // Constructors
    //

    /** Default constructor. */
    public XMLDocumentScannerImpl() {} // <init>()


    //
    // XMLDocumentScanner methods
    //


    /**
     * Sets the input source.
     *
     * @param inputSource The input source.
     *
     * @throws IOException Thrown on i/o error.
     */
    public void setInputSource(XMLInputSource inputSource) throws IOException {
        fEntityManager.setEntityHandler(this);
        //this starts a new entity and sets the current entity to the document entity.
        fEntityManager.startDocumentEntity(inputSource);
        // fDocumentSystemId = fEntityManager.expandSystemId(inputSource.getSystemId());
        setScannerState(XMLEvent.START_DOCUMENT);
    } // setInputSource(XMLInputSource)



    /**return the state of the scanner */
    public int getScannetState(){
        return fScannerState ;
    }




    public void reset(PropertyManager propertyManager) {
        super.reset(propertyManager);
        // other settings
        fDoctypeName = null;
        fDoctypePublicId = null;
        fDoctypeSystemId = null;
        fSeenDoctypeDecl = false;
        fNamespaceContext.reset();
        fSupportDTD = ((Boolean)propertyManager.getProperty(XMLInputFactory.SUPPORT_DTD)).booleanValue();

        // xerces features
        fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue();
        setScannerState(XMLEvent.START_DOCUMENT);
        setDriver(fXMLDeclDriver);
        fSeenInternalSubset = false;
        if(fDTDScanner != null){
            ((XMLDTDScannerImpl)fDTDScanner).reset(propertyManager);
        }
        fEndPos = 0;
        fStartPos = 0;
        if(fDTDDecl != null){
            fDTDDecl.clear();
        }

    }

    /**
     * Resets the component. The component can query the component manager
     * about any features and properties that affect the operation of the
     * component.
     *
     * @param componentManager The component manager.
     *
     * @throws SAXException Thrown by component on initialization error.
     *                      For example, if a feature or property is
     *                      required for the operation of the component, the
     *                      component manager may throw a
     *                      SAXNotRecognizedException or a
     *                      SAXNotSupportedException.
     */
    public void reset(XMLComponentManager componentManager)
    throws XMLConfigurationException {

        super.reset(componentManager);

        // other settings
        fDoctypeName = null;
        fDoctypePublicId = null;
        fDoctypeSystemId = null;
        fSeenDoctypeDecl = false;
        fExternalSubsetSource = null;

        // xerces features
        fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD, true);
        fDisallowDoctype = componentManager.getFeature(DISALLOW_DOCTYPE_DECL_FEATURE, false);

        fNamespaces = componentManager.getFeature(NAMESPACES, true);

        fSeenInternalSubset = false;
        // xerces properties
        fDTDScanner = (XMLDTDScanner)componentManager.getProperty(DTD_SCANNER);

        fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null);

        try {
            fNamespaceContext = (NamespaceContext)componentManager.getProperty(NAMESPACE_CONTEXT);
        }
        catch (XMLConfigurationException e) { }
        if (fNamespaceContext == null) {
            fNamespaceContext = new NamespaceSupport();
        }
        fNamespaceContext.reset();

        fEndPos = 0;
        fStartPos = 0;
        if(fDTDDecl != null)
            fDTDDecl.clear();


        //fEntityScanner.registerListener((XMLBufferListener)componentManager.getProperty(DOCUMENT_SCANNER));

        // setup driver
        setScannerState(SCANNER_STATE_XML_DECL);
        setDriver(fXMLDeclDriver);

    } // reset(XMLComponentManager)


    /**
     * Returns a list of feature identifiers that are recognized by
     * this component. This method may return null if no features
     * are recognized by this component.
     */
    public String[] getRecognizedFeatures() {
        String[] featureIds = super.getRecognizedFeatures();
        int length = featureIds != null ? featureIds.length : 0;
        String[] combinedFeatureIds = new String[length + RECOGNIZED_FEATURES.length];
        if (featureIds != null) {
            System.arraycopy(featureIds, 0, combinedFeatureIds, 0, featureIds.length);
        }
        System.arraycopy(RECOGNIZED_FEATURES, 0, combinedFeatureIds, length, RECOGNIZED_FEATURES.length);
        return combinedFeatureIds;
    } // getRecognizedFeatures():String[]

    /**
     * Sets the state of a feature. This method is called by the component
     * manager any time after reset when a feature changes state.
     * <p>
     * <strong>Note:</strong> Components should silently ignore features
     * that do not affect the operation of the component.
     *
     * @param featureId The feature identifier.
     * @param state     The state of the feature.
     *
     * @throws SAXNotRecognizedException The component should not throw
     *                                   this exception.
     * @throws SAXNotSupportedException The component should not throw
     *                                  this exception.
     */
    public void setFeature(String featureId, boolean state)
    throws XMLConfigurationException {

        super.setFeature(featureId, state);

        // Xerces properties
        if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
            final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();

            if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
                featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
                fLoadExternalDTD = state;
                return;
            }
            else if (suffixLength == Constants.DISALLOW_DOCTYPE_DECL_FEATURE.length() &&
                featureId.endsWith(Constants.DISALLOW_DOCTYPE_DECL_FEATURE)) {
                fDisallowDoctype = state;
                return;
            }
        }

    } // setFeature(String,boolean)

    /**
     * Returns a list of property identifiers that are recognized by
     * this component. This method may return null if no properties
     * are recognized by this component.
     */
    public String[] getRecognizedProperties() {
        String[] propertyIds = super.getRecognizedProperties();
        int length = propertyIds != null ? propertyIds.length : 0;
        String[] combinedPropertyIds = new String[length + RECOGNIZED_PROPERTIES.length];
        if (propertyIds != null) {
            System.arraycopy(propertyIds, 0, combinedPropertyIds, 0, propertyIds.length);
        }
        System.arraycopy(RECOGNIZED_PROPERTIES, 0, combinedPropertyIds, length, RECOGNIZED_PROPERTIES.length);
        return combinedPropertyIds;
    } // getRecognizedProperties():String[]

    /**
     * Sets the value of a property. This method is called by the component
     * manager any time after reset when a property changes value.
     * <p>
     * <strong>Note:</strong> Components should silently ignore properties
     * that do not affect the operation of the component.
     *
     * @param propertyId The property identifier.
     * @param value      The value of the property.
     *
     * @throws SAXNotRecognizedException The component should not throw
     *                                   this exception.
     * @throws SAXNotSupportedException The component should not throw
     *                                  this exception.
     */
    public void setProperty(String propertyId, Object value)
    throws XMLConfigurationException {

        super.setProperty(propertyId, value);

        // Xerces properties
        if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
            final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();

            if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
                propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
                fDTDScanner = (XMLDTDScanner)value;
            }
            if (suffixLength == Constants.NAMESPACE_CONTEXT_PROPERTY.length() &&
                propertyId.endsWith(Constants.NAMESPACE_CONTEXT_PROPERTY)) {
                if (value != null) {
                    fNamespaceContext = (NamespaceContext)value;
                }
            }

            return;
        }

    } // setProperty(String,Object)

    /**
     * Returns the default state for a feature, or null if this
     * component does not want to report a default value for this
     * feature.
     *
     * @param featureId The feature identifier.
     *
     * @since Xerces 2.2.0
     */
    public Boolean getFeatureDefault(String featureId) {

        for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
            if (RECOGNIZED_FEATURES[i].equals(featureId)) {
                return FEATURE_DEFAULTS[i];
            }
        }
        return super.getFeatureDefault(featureId);
    } // getFeatureDefault(String):Boolean

    /**
     * Returns the default state for a property, or null if this
     * component does not want to report a default value for this
     * property.
     *
     * @param propertyId The property identifier.
     *
     * @since Xerces 2.2.0
     */
    public Object getPropertyDefault(String propertyId) {
        for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
            if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
                return PROPERTY_DEFAULTS[i];
            }
        }
        return super.getPropertyDefault(propertyId);
    } // getPropertyDefault(String):Object

    //
    // XMLEntityHandler methods
    //

    /**
     * This method notifies of the start of an entity. The DTD has the
     * pseudo-name of "[dtd]" parameter entity names start with '%'; and
     * general entities are just specified by their name.
     *
     * @param name     The name of the entity.
     * @param identifier The resource identifier.
     * @param encoding The auto-detected IANA encoding name of the entity
     *                 stream. This value will be null in those situations
     *                 where the entity encoding is not auto-detected (e.g.
     *                 internal entities or a document entity that is
     *                 parsed from a java.io.Reader).
     *
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void startEntity(String name,
            XMLResourceIdentifier identifier,
            String encoding, Augmentations augs) throws XNIException {

        super.startEntity(name, identifier, encoding,augs);

        //register current document scanner as a listener for XMLEntityScanner
        fEntityScanner.registerListener(this);

        // prepare to look for a TextDecl if external general entity
        if (!name.equals("[xml]") && fEntityScanner.isExternal()) {
            // Don't do this if we're skipping the entity!
            if (augs == null || !((Boolean) augs.getItem(Constants.ENTITY_SKIPPED)).booleanValue()) {
                setScannerState(SCANNER_STATE_TEXT_DECL);
            }
        }

        // call handler
        /** comment this part.. LOCATOR problem.. */
        if (fDocumentHandler != null && name.equals("[xml]")) {
            fDocumentHandler.startDocument(fEntityScanner, encoding, fNamespaceContext, null);
        }

    } // startEntity(String,identifier,String)


    /**
     * This method notifies the end of an entity. The DTD has the pseudo-name
     * of "[dtd]" parameter entity names start with '%'; and general entities
     * are just specified by their name.
     *
     * @param name The name of the entity.
     *
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void endEntity(String name, Augmentations augs) throws IOException, XNIException {

        super.endEntity(name, augs);

        if(name.equals("[xml]")){
            //if fMarkupDepth has reached 0.
            //and driver is fTrailingMiscDriver (which
            //handles end of document in normal case)
            //set the scanner state of SCANNER_STATE_TERMINATED
            if(fMarkupDepth == 0 && fDriver == fTrailingMiscDriver){
                //set the scanner set to SCANNER_STATE_TERMINATED
                setScannerState(SCANNER_STATE_TERMINATED) ;
            } else{
                //else we have reached the end of document prematurely
                //so throw EOFException.
                throw new java.io.EOFException();
            }

            //this is taken care in wrapper which generates XNI callbacks, There are no next events

            //if (fDocumentHandler != null) {
                //fDocumentHandler.endDocument(null);
            //}
        }
    } // endEntity(String)


    public XMLStringBuffer getDTDDecl(){
        Entity entity = fEntityScanner.getCurrentEntity();
        fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos);
        if(fSeenInternalSubset)
            fDTDDecl.append("]>");
        return fDTDDecl;
    }

    public String getCharacterEncodingScheme(){
        return fDeclaredEncoding;
    }

    /** return the next state on the input
     *
     * @return int
     */

    public int next() throws IOException, XNIException {
        return fDriver.next();
    }

    //getNamespaceContext
    public NamespaceContext getNamespaceContext(){
        return fNamespaceContext ;
    }



    //
    // Protected methods
    //

    // driver factory methods

    /** Creates a content driver. */
    protected Driver createContentDriver() {
        return new ContentDriver();
    } // createContentDriver():Driver

    // scanning methods

    /** Scans a doctype declaration. */
    protected boolean scanDoctypeDecl(boolean supportDTD) throws IOException, XNIException {

        // spaces
        if (!fEntityScanner.skipSpaces()) {
            reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL",
                    null);
        }

        // root element name
        fDoctypeName = fEntityScanner.scanName();
        if (fDoctypeName == null) {
            reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null);
        }

        // external id
        if (fEntityScanner.skipSpaces()) {
            scanExternalID(fStrings, false);
            fDoctypeSystemId = fStrings[0];
            fDoctypePublicId = fStrings[1];
            fEntityScanner.skipSpaces();
        }

        fHasExternalDTD = fDoctypeSystemId != null;

        // Attempt to locate an external subset with an external subset resolver.
        if (supportDTD && !fHasExternalDTD && fExternalSubsetResolver != null) {
            fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null);
            fDTDDescription.setRootName(fDoctypeName);
            fExternalSubsetSource = fExternalSubsetResolver.getExternalSubset(fDTDDescription);
            fHasExternalDTD = fExternalSubsetSource != null;
        }

        // call handler
        if (supportDTD && fDocumentHandler != null) {
            // NOTE: I don't like calling the doctypeDecl callback until
            //       end of the *full* doctype line (including internal
            //       subset) is parsed correctly but SAX2 requires that
            //       it knows the root element name and public and system
            //       identifier for the startDTD call. -Ac
            if (fExternalSubsetSource == null) {
                fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null);
            }
            else {
                fDocumentHandler.doctypeDecl(fDoctypeName, fExternalSubsetSource.getPublicId(), fExternalSubsetSource.getSystemId(), null);
            }
        }

        // is there an internal subset?
        boolean internalSubset = true;
        if (!fEntityScanner.skipChar('[')) {
            internalSubset = false;
            fEntityScanner.skipSpaces();
            if (!fEntityScanner.skipChar('>')) {
                reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
            }
            fMarkupDepth--;
        }
        return internalSubset;

    } // scanDoctypeDecl():boolean

    //
    // Private methods
    //
    /** Set the scanner state after scanning DTD */
    protected void setEndDTDScanState() {
        setScannerState(SCANNER_STATE_PROLOG);
        setDriver(fPrologDriver);
        fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
        fReadingDTD=false;
    }

    /** Returns the scanner state name. */
    protected String getScannerStateName(int state) {

        switch (state) {
            case SCANNER_STATE_XML_DECL: return "SCANNER_STATE_XML_DECL";
            case SCANNER_STATE_PROLOG: return "SCANNER_STATE_PROLOG";
            case SCANNER_STATE_TRAILING_MISC: return "SCANNER_STATE_TRAILING_MISC";
            case SCANNER_STATE_DTD_INTERNAL_DECLS: return "SCANNER_STATE_DTD_INTERNAL_DECLS";
            case SCANNER_STATE_DTD_EXTERNAL: return "SCANNER_STATE_DTD_EXTERNAL";
            case SCANNER_STATE_DTD_EXTERNAL_DECLS: return "SCANNER_STATE_DTD_EXTERNAL_DECLS";
        }
        return super.getScannerStateName(state);

    } // getScannerStateName(int):String

    //
    // Classes
    //

    /**
     * Driver to handle XMLDecl scanning.
     *
     * This class has been modified as per the new design which is more suited to
     * efficiently build pull parser. Lots of performance improvements have been done and
     * the code has been added to support stax functionality/features.
     *
     * @author Neeraj Bajaj, Sun Microsystems.
     *
     * @author Andy Clark, IBM
     */
    protected final class XMLDeclDriver
            implements Driver {

        //
        // Driver methods
        //


        public int next() throws IOException, XNIException {
            if(DEBUG_NEXT){
                System.out.println("NOW IN XMLDeclDriver");
            }

            // next driver is prolog regardless of whether there
            // is an XMLDecl in this document
            setScannerState(SCANNER_STATE_PROLOG);
            setDriver(fPrologDriver);

            //System.out.println("fEntityScanner = " + fEntityScanner);
            // scan XMLDecl
            try {
                if (fEntityScanner.skipString(xmlDecl)) {
                    fMarkupDepth++;
                    // NOTE: special case where document starts with a PI
                    //       whose name starts with "xml" (e.g. "xmlfoo")
                    if (XMLChar.isName(fEntityScanner.peekChar())) {
                        fStringBuffer.clear();
                        fStringBuffer.append("xml");
                        while (XMLChar.isName(fEntityScanner.peekChar())) {
                            fStringBuffer.append((char)fEntityScanner.scanChar());
                        }
                        String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
                        //this function should fill the data.. and set the fEvent object to this event.
                        fContentBuffer.clear() ;
                        scanPIData(target, fContentBuffer);
                        //REVISIT:where else we can set this value to 'true'
                        fEntityManager.fCurrentEntity.mayReadChunks = true;
                        //return PI event since PI was encountered
                        return XMLEvent.PROCESSING_INSTRUCTION ;
                    }
                    // standard XML declaration
                    else {
                        scanXMLDeclOrTextDecl(false);
                        //REVISIT:where else we can set this value to 'true'
                        fEntityManager.fCurrentEntity.mayReadChunks = true;
                        return XMLEvent.START_DOCUMENT;
                    }
                } else{
                    //REVISIT:where else we can set this value to 'true'
                    fEntityManager.fCurrentEntity.mayReadChunks = true;
                    //In both case return the START_DOCUMENT. ony difference is that first block will
                    //cosume the XML declaration if any.
                    return XMLEvent.START_DOCUMENT;
                }


                //START_OF_THE_DOCUMENT


            }

            // premature end of file
            catch (EOFException e) {
                reportFatalError("PrematureEOF", null);
                return -1;
                //throw e;
            }

        }
    } // class XMLDeclDriver

    /**
     * Driver to handle prolog scanning.
     *
     * @author Andy Clark, IBM
     */
    protected final class PrologDriver
            implements Driver {

        /**
         * Drives the parser to the next state/event on the input. Parser is guaranteed
         * to stop at the next state/event.
         *
         * Internally XML document is divided into several states. Each state represents
         * a sections of XML document. When this functions returns normally, it has read
         * the section of XML document and returns the state corresponding to section of
         * document which has been read. For optimizations, a particular driver
         * can read ahead of the section of document (state returned) just read and
         * can maintain a different internal state.
         *
         * @return state representing the section of document just read.
         *
         * @throws IOException  Thrown on i/o error.
         * @throws XNIException Thrown on parse error.
         */

        public int next() throws IOException, XNIException {
            //System.out.println("here in next");

            if(DEBUG_NEXT){
                System.out.println("NOW IN PrologDriver");
            }
            try {
                do {
                    switch (fScannerState) {
                        case SCANNER_STATE_PROLOG: {
                            fEntityScanner.skipSpaces();
                            if (fEntityScanner.skipChar('<')) {
                                setScannerState(SCANNER_STATE_START_OF_MARKUP);
                            } else if (fEntityScanner.skipChar('&')) {
                                setScannerState(SCANNER_STATE_REFERENCE);
                            } else {
                                setScannerState(SCANNER_STATE_CONTENT);
                            }
                            break;
                        }

                        case SCANNER_STATE_START_OF_MARKUP: {
                            fMarkupDepth++;

                            if (fEntityScanner.skipChar('?')) {
                                setScannerState(SCANNER_STATE_PI);
                            } else if (fEntityScanner.skipChar('!')) {
                                if (fEntityScanner.skipChar('-')) {
                                    if (!fEntityScanner.skipChar('-')) {
                                        reportFatalError("InvalidCommentStart",
                                                null);
                                    }
                                    setScannerState(SCANNER_STATE_COMMENT);
                                } else if (fEntityScanner.skipString(DOCTYPE)) {
                                    setScannerState(SCANNER_STATE_DOCTYPE);
                                    Entity entity = fEntityScanner.getCurrentEntity();
                                    if(entity instanceof Entity.ScannedEntity){
                                        fStartPos=((Entity.ScannedEntity)entity).position;
                                    }
                                    fReadingDTD=true;
                                    if(fDTDDecl == null)
                                        fDTDDecl = new XMLStringBuffer();
                                    fDTDDecl.append("<!DOCTYPE");

                                } else {
                                    reportFatalError("MarkupNotRecognizedInProlog",
                                            null);
                                }
                            } else if (XMLChar.isNameStart(fEntityScanner.peekChar())) {
                                setScannerState(SCANNER_STATE_ROOT_ELEMENT);
                                setDriver(fContentDriver);
                                //from now onwards this would be handled by fContentDriver,in the same next() call
                                return fContentDriver.next();

                            } else {
                                reportFatalError("MarkupNotRecognizedInProlog",
                                        null);
                            }
                            break;
                        }
                    }
                } while (fScannerState == SCANNER_STATE_PROLOG || fScannerState == SCANNER_STATE_START_OF_MARKUP );

                switch(fScannerState){
                    /**
                    //this part is handled by FragmentContentHandler
                    case SCANNER_STATE_ROOT_ELEMENT: {
                        //we have read '<' and beginning of reading the start element tag
                        setScannerState(SCANNER_STATE_START_ELEMENT_TAG);
                        setDriver(fContentDriver);
                        //from now onwards this would be handled by fContentDriver,in the same next() call
                        return fContentDriver.next();
                    }
                     */
                    case SCANNER_STATE_COMMENT: {
                        //this function fills the data..
                        scanComment();
                        setScannerState(SCANNER_STATE_PROLOG);
                        return XMLEvent.COMMENT;
                        //setScannerState(SCANNER_STATE_PROLOG);
                        //break;
                    }
                    case SCANNER_STATE_PI: {
                        fContentBuffer.clear() ;
                        scanPI(fContentBuffer);
                        setScannerState(SCANNER_STATE_PROLOG);
                        return XMLEvent.PROCESSING_INSTRUCTION;
                    }

                    case SCANNER_STATE_DOCTYPE: {
                        if (fDisallowDoctype) {
                            reportFatalError("DoctypeNotAllowed", null);
                        }

                        if (fSeenDoctypeDecl) {
                            reportFatalError("AlreadySeenDoctype", null);
                        }
                        fSeenDoctypeDecl = true;

                        // scanDoctypeDecl() sends XNI doctypeDecl event that
                        // in SAX is converted to startDTD() event.
                        if (scanDoctypeDecl(fSupportDTD)) {
                            //allow parsing of entity decls to continue in order to stay well-formed
                            setScannerState(SCANNER_STATE_DTD_INTERNAL_DECLS);
                            fSeenInternalSubset = true;
                            if(fDTDDriver == null){
                                fDTDDriver = new DTDDriver();
                            }
                            setDriver(fContentDriver);
                            //always return DTD event, the event however, will not contain any entities
                            return fDTDDriver.next();
                        }

                        if(fSeenDoctypeDecl){
                            Entity entity = fEntityScanner.getCurrentEntity();
                            if(entity instanceof Entity.ScannedEntity){
                                fEndPos = ((Entity.ScannedEntity)entity).position;
                            }
                            fReadingDTD = false;
                        }

                        // handle external subset
                        if (fDoctypeSystemId != null) {
                            if (((fValidation || fLoadExternalDTD)
                                && (fValidationManager == null || !fValidationManager.isCachedDTD()))) {
                                if (fSupportDTD) {
                                    setScannerState(SCANNER_STATE_DTD_EXTERNAL);
                                } else {
                                    setScannerState(SCANNER_STATE_PROLOG);
                                }

                                setDriver(fContentDriver);
                                if(fDTDDriver == null) {
                                    fDTDDriver = new DTDDriver();
                                }

                                return fDTDDriver.next();
                            }
                        }
                        else if (fExternalSubsetSource != null) {
                            if (((fValidation || fLoadExternalDTD)
                                && (fValidationManager == null || !fValidationManager.isCachedDTD()))) {
                                // This handles the case of a DOCTYPE that had neither an internal subset or an external subset.
                                fDTDScanner.setInputSource(fExternalSubsetSource);
                                fExternalSubsetSource = null;
                            if (fSupportDTD)
                                setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
                            else
                                setScannerState(SCANNER_STATE_PROLOG);
                            setDriver(fContentDriver);
                            if(fDTDDriver == null)
                                fDTDDriver = new DTDDriver();
                            return fDTDDriver.next();
                            }
                        }

                        // Send endDTD() call if:
                        // a) systemId is null or if an external subset resolver could not locate an external subset.
                        // b) "load-external-dtd" and validation are false
                        // c) DTD grammar is cached

                        // in XNI this results in 3 events:  doctypeDecl, startDTD, endDTD
                        // in SAX this results in 2 events: startDTD, endDTD
                        if (fDTDScanner != null) {
                            fDTDScanner.setInputSource(null);
                        }
                        setScannerState(SCANNER_STATE_PROLOG);
                        return XMLEvent.DTD;
                    }

                    case SCANNER_STATE_CONTENT: {
                        reportFatalError("ContentIllegalInProlog", null);
                        fEntityScanner.scanChar();
                    }
                    case SCANNER_STATE_REFERENCE: {
                        reportFatalError("ReferenceIllegalInProlog", null);
                    }

                    /**
                     * if (complete) {
                     * if (fEntityScanner.scanChar() != '<') {
                     * reportFatalError("RootElementRequired", null);
                     * }
                     * setScannerState(SCANNER_STATE_ROOT_ELEMENT);
                     * setDriver(fContentDriver);
                     * }
                     */
                }
            }
            // premature end of file
            catch (EOFException e) {
                reportFatalError("PrematureEOF", null);
                //xxx  what should be returned here.... ???
                return -1 ;
                //throw e;
            }
            //xxx  what should be returned here.... ???
            return -1;

        }


    } // class PrologDriver

    /**
     * Driver to handle the internal and external DTD subsets.
     *
     * @author Andy Clark, IBM
     */
    protected final class DTDDriver
            implements Driver {

        //
        // Driver methods
        //

        public int next() throws IOException, XNIException{
            // throw new XNIException("DTD Parsing is currently not supported");
            if(DEBUG_NEXT){
                System.out.println("Now in DTD Driver");
            }

            dispatch(true);

            if(DEBUG_NEXT){
                System.out.println("After calling dispatch(true) -- At this point whole DTD is read.");
            }

            //xxx: remove this hack and align this with reusing DTD components
            //currently this routine will only be executed from Stax
            if(fPropertyManager != null){
                dtdGrammarUtil =  new DTDGrammarUtil(((XMLDTDScannerImpl)fDTDScanner).getGrammar(),fSymbolTable, fNamespaceContext);
            }

            return XMLEvent.DTD ;
        }

        /**
         * Dispatch an XML "event".
         *
         * @param complete True if this driver is intended to scan
         *                 and dispatch as much as possible.
         *
         * @return True if there is more to dispatch either from this
         *          or a another driver.
         *
         * @throws IOException  Thrown on i/o error.
         * @throws XNIException Thrown on parse error.
         */
        public boolean dispatch(boolean complete)
        throws IOException, XNIException {
            fEntityManager.setEntityHandler(null);
            try {
                boolean again;
                XMLResourceIdentifierImpl resourceIdentifier = new XMLResourceIdentifierImpl();
                if( fDTDScanner == null){

                    if (fEntityManager.getEntityScanner() instanceof XML11EntityScanner){
                        fDTDScanner = new XML11DTDScannerImpl();
                    } else

                    fDTDScanner = new XMLDTDScannerImpl();

                    ((XMLDTDScannerImpl)fDTDScanner).reset(fPropertyManager);
                }

                fDTDScanner.setLimitAnalyzer(fLimitAnalyzer);
                do {
                    again = false;
                    switch (fScannerState) {
                        case SCANNER_STATE_DTD_INTERNAL_DECLS: {
                            boolean moreToScan = false;
                            if (!fDTDScanner.skipDTD(fSupportDTD)) {
                            // REVISIT: Should there be a feature for
                            //          the "complete" parameter?
                            boolean completeDTD = true;

                                moreToScan = fDTDScanner.scanDTDInternalSubset(completeDTD, fStandalone, fHasExternalDTD && fLoadExternalDTD);
                            }
                            Entity entity = fEntityScanner.getCurrentEntity();
                            if(entity instanceof Entity.ScannedEntity){
                                fEndPos=((Entity.ScannedEntity)entity).position;
                            }
                            fReadingDTD=false;
                            if (!moreToScan) {
                                // end doctype declaration
                                if (!fEntityScanner.skipChar(']')) {
                                    reportFatalError("EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET",
                                            null);
                                }
                                fEntityScanner.skipSpaces();
                                if (!fEntityScanner.skipChar('>')) {
                                    reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
                                }
                                fMarkupDepth--;

                                if (!fSupportDTD) {
                                    //simply reset the entity store without having to mess around
                                    //with the DTD Scanner code
                                    fEntityStore = fEntityManager.getEntityStore();
                                    fEntityStore.reset();
                                } else {
                                    // scan external subset next unless we are ignoring DTDs
                                    if (fDoctypeSystemId != null && (fValidation || fLoadExternalDTD)) {
                                        setScannerState(SCANNER_STATE_DTD_EXTERNAL);
                                        break;
                                    }
                                }

                                setEndDTDScanState();
                                return true;

                            }
                            break;
                        }
                        case SCANNER_STATE_DTD_EXTERNAL: {
                            /**
                            fDTDDescription.setValues(fDoctypePublicId, fDoctypeSystemId, null, null);
                            fDTDDescription.setRootName(fDoctypeName);
                            XMLInputSource xmlInputSource =
                                fEntityManager.resolveEntity(fDTDDescription);
                            fDTDScanner.setInputSource(xmlInputSource);
                            setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
                            again = true;
                            break;
                             */

                            resourceIdentifier.setValues(fDoctypePublicId, fDoctypeSystemId, null, null);
                            XMLInputSource xmlInputSource = null ;
                            StaxXMLInputSource staxInputSource =  fEntityManager.resolveEntityAsPerStax(resourceIdentifier);

                            // Check access permission. If the source is resolved by a resolver, the check is skipped.
                            if (!staxInputSource.hasResolver()) {
                                String accessError = checkAccess(fDoctypeSystemId, fAccessExternalDTD);
                                if (accessError != null) {
                                    reportFatalError("AccessExternalDTD", new Object[]{ SecuritySupport.sanitizePath(fDoctypeSystemId), accessError });
                                }
                            }
                            xmlInputSource = staxInputSource.getXMLInputSource();
                            fDTDScanner.setInputSource(xmlInputSource);
                            if (fEntityScanner.fCurrentEntity != null) {
                                setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
                            } else {
                                setScannerState(SCANNER_STATE_PROLOG);
                            }
                            again = true;
                            break;
                        }
                        case SCANNER_STATE_DTD_EXTERNAL_DECLS: {
                            // REVISIT: Should there be a feature for
                            //          the "complete" parameter?
                            boolean completeDTD = true;
                            boolean moreToScan = fDTDScanner.scanDTDExternalSubset(completeDTD);
                            if (!moreToScan) {
                                setEndDTDScanState();
                                return true;
                            }
                            break;
                        }
                        case SCANNER_STATE_PROLOG : {
                            // skip entity decls
                            setEndDTDScanState();
                            return true;
                        }
                        default: {
                            throw new XNIException("DTDDriver#dispatch: scanner state="+fScannerState+" ("+getScannerStateName(fScannerState)+')');
                        }
                    }
                } while (complete || again);
            }

            // premature end of file
            catch (EOFException e) {
                e.printStackTrace();
                reportFatalError("PrematureEOF", null);
                return false;
                //throw e;
            }

            // cleanup
            finally {
                fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
            }

            return true;

        }

        // dispatch(boolean):boolean

    } // class DTDDriver

    /**
     * Driver to handle content scanning.
     *
     * @author Andy Clark, IBM
     * @author Eric Ye, IBM
     */
    protected class ContentDriver
            extends FragmentContentDriver {

        //
        // Protected methods
        //

        // hooks

        // NOTE: These hook methods are added so that the full document
        //       scanner can share the majority of code with this class.

        /**
         * Scan for DOCTYPE hook. This method is a hook for subclasses
         * to add code to handle scanning for a the "DOCTYPE" string
         * after the string "<!" has been scanned.
         *
         * @return True if the "DOCTYPE" was scanned; false if "DOCTYPE"
         *          was not scanned.
         */
        protected boolean scanForDoctypeHook()
        throws IOException, XNIException {

            if (fEntityScanner.skipString(DOCTYPE)) {
                setScannerState(SCANNER_STATE_DOCTYPE);
                //                fEntityScanner.markStartOfDTD();
                return true;
            }
            return false;

        } // scanForDoctypeHook():boolean

        /**
         * Element depth iz zero. This methos is a hook for subclasses
         * to add code to handle when the element depth hits zero. When
         * scanning a document fragment, an element depth of zero is
         * normal. However, when scanning a full XML document, the
         * scanner must handle the trailing miscellanous section of
         * the document after the end of the document's root element.
         *
         * @return True if the caller should stop and return true which
         *          allows the scanner to switch to a new scanning
         *          driver. A return value of false indicates that
         *          the content driver should continue as normal.
         */
        protected boolean elementDepthIsZeroHook()
        throws IOException, XNIException {

            setScannerState(SCANNER_STATE_TRAILING_MISC);
            setDriver(fTrailingMiscDriver);
            return true;

        } // elementDepthIsZeroHook():boolean

        /**
         * Scan for root element hook. This method is a hook for
         * subclasses to add code that handles scanning for the root
         * element. When scanning a document fragment, there is no
         * "root" element. However, when scanning a full XML document,
         * the scanner must handle the root element specially.
         *
         * @return True if the caller should stop and return true which
         *          allows the scanner to switch to a new scanning
         *          driver. A return value of false indicates that
         *          the content driver should continue as normal.
         */
        protected boolean scanRootElementHook()
        throws IOException, XNIException {

            if (scanStartElement()) {
                setScannerState(SCANNER_STATE_TRAILING_MISC);
                setDriver(fTrailingMiscDriver);
                return true;
            }
            return false;

        } // scanRootElementHook():boolean

        /**
         * End of file hook. This method is a hook for subclasses to
         * add code that handles the end of file. The end of file in
         * a document fragment is OK if the markup depth is zero.
         * However, when scanning a full XML document, an end of file
         * is always premature.
         */
        protected void endOfFileHook(EOFException e)
        throws IOException, XNIException {

            reportFatalError("PrematureEOF", null);
            // in case continue-after-fatal-error set, should not do this...
            //throw e;

        } // endOfFileHook()

        protected void resolveExternalSubsetAndRead()
        throws IOException, XNIException {

            fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null);
            fDTDDescription.setRootName(fElementQName.rawname);
            XMLInputSource src = fExternalSubsetResolver.getExternalSubset(fDTDDescription);

            if (src != null) {
                fDoctypeName = fElementQName.rawname;
                fDoctypePublicId = src.getPublicId();
                fDoctypeSystemId = src.getSystemId();
                // call document handler
                if (fDocumentHandler != null) {
                    // This inserts a doctypeDecl event into the stream though no
                    // DOCTYPE existed in the instance document.
                    fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null);
                }
                try {
                    fDTDScanner.setInputSource(src);
                    while (fDTDScanner.scanDTDExternalSubset(true));
                } finally {
                    fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
                }
            }
        } // resolveExternalSubsetAndRead()



    } // class ContentDriver

    /**
     * Driver to handle trailing miscellaneous section scanning.
     *
     * @author Andy Clark, IBM
     * @author Eric Ye, IBM
     */
    protected final class TrailingMiscDriver
            implements Driver {

        //
        // Driver methods
        //
        public int next() throws IOException, XNIException{
            //this could for cases like <foo/>
            //look at scanRootElementHook
            if(fEmptyElement){
                fEmptyElement = false;
                return XMLEvent.END_ELEMENT;
            }

            try {
                if(fScannerState == SCANNER_STATE_TERMINATED){
                    return XMLEvent.END_DOCUMENT ;}
                do {
                    switch (fScannerState) {
                        case SCANNER_STATE_TRAILING_MISC: {

                            fEntityScanner.skipSpaces();
                            //we should have reached the end of the document in
                            //most cases.
                            if(fScannerState == SCANNER_STATE_TERMINATED ){
                                return XMLEvent.END_DOCUMENT ;
                            }
                            if (fEntityScanner.skipChar('<')) {
                                setScannerState(SCANNER_STATE_START_OF_MARKUP);
                            } else {
                                setScannerState(SCANNER_STATE_CONTENT);
                            }
                            break;
                        }
                        case SCANNER_STATE_START_OF_MARKUP: {
                            fMarkupDepth++;
                            if (fEntityScanner.skipChar('?')) {
                                setScannerState(SCANNER_STATE_PI);
                            } else if (fEntityScanner.skipChar('!')) {
                                setScannerState(SCANNER_STATE_COMMENT);
                            } else if (fEntityScanner.skipChar('/')) {
                                reportFatalError("MarkupNotRecognizedInMisc",
                                        null);
                            } else if (XMLChar.isNameStart(fEntityScanner.peekChar())) {
                                reportFatalError("MarkupNotRecognizedInMisc",
                                        null);
                                scanStartElement();
                                setScannerState(SCANNER_STATE_CONTENT);
                            } else {
                                reportFatalError("MarkupNotRecognizedInMisc",
                                        null);
                            }
                            break;
                        }
                    }
                }while(fScannerState == SCANNER_STATE_START_OF_MARKUP || fScannerState == SCANNER_STATE_TRAILING_MISC);
                if(DEBUG_NEXT){
                    System.out.println("State set by deciding while loop [TrailingMiscellaneous] is = " + getScannerStateName(fScannerState));
                }
                switch (fScannerState){
                    case SCANNER_STATE_PI: {
                        fContentBuffer.clear();
                        scanPI(fContentBuffer);
                        setScannerState(SCANNER_STATE_TRAILING_MISC);
                        return XMLEvent.PROCESSING_INSTRUCTION ;
                    }
                    case SCANNER_STATE_COMMENT: {
                        if (!fEntityScanner.skipString(COMMENTSTRING)) {
                            reportFatalError("InvalidCommentStart", null);
                        }
                        scanComment();
                        setScannerState(SCANNER_STATE_TRAILING_MISC);
                        return XMLEvent.COMMENT;
                    }
                    case SCANNER_STATE_CONTENT: {
                        int ch = fEntityScanner.peekChar();
                        if (ch == -1) {
                            setScannerState(SCANNER_STATE_TERMINATED);
                            return XMLEvent.END_DOCUMENT ;
                        } else{
                            reportFatalError("ContentIllegalInTrailingMisc",
                                    null);
                            fEntityScanner.scanChar();
                            setScannerState(SCANNER_STATE_TRAILING_MISC);
                            return XMLEvent.CHARACTERS;
                        }

                    }
                    case SCANNER_STATE_REFERENCE: {
                        reportFatalError("ReferenceIllegalInTrailingMisc",
                                null);
                        setScannerState(SCANNER_STATE_TRAILING_MISC);
                        return XMLEvent.ENTITY_REFERENCE ;
                    }
                    case SCANNER_STATE_TERMINATED: {
                        //there can't be any element after SCANNER_STATE_TERMINATED or when the parser
                        //has reached the end of document
                        setScannerState(SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION);
                        //xxx what to do when the scanner has reached the terminating state.
                        return XMLEvent.END_DOCUMENT ;
                    }
                    case SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION:{
                        throw new java.util.NoSuchElementException("No more events to be parsed");
                    }
                    default: throw new XNIException("Scanner State " + fScannerState + " not Recognized ");
                }//switch

            } catch (EOFException e) {
                // NOTE: This is the only place we're allowed to reach
                //       the real end of the document stream. Unless the
                //       end of file was reached prematurely.
                if (fMarkupDepth != 0) {
                    reportFatalError("PrematureEOF", null);
                    return -1;
                    //throw e;
                }
                //System.out.println("EOFException thrown") ;
                setScannerState(SCANNER_STATE_TERMINATED);
            }

            return XMLEvent.END_DOCUMENT;

        }//next

    } // class TrailingMiscDriver

    /**
     * Implements XMLBufferListener interface.
     */


    /**
     * receives callbacks from {@link XMLEntityReader } when buffer
     * is being changed.
     * @param refreshPosition
     */
    public void refresh(int refreshPosition){
        super.refresh(refreshPosition);
        if(fReadingDTD){
            Entity entity = fEntityScanner.getCurrentEntity();
            if(entity instanceof Entity.ScannedEntity){
                fEndPos=((Entity.ScannedEntity)entity).position;
            }
            fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos);
            fStartPos = refreshPosition;
        }
    }

} // class XMLDocumentScannerImpl
