Package org.apache.xerces.validators.common

Source Code of org.apache.xerces.validators.common.XMLValidator$Resolver

/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999,2000 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment: 
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
*    nor may "Apache" appear in their name, without prior written
*    permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.apache.org.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.xerces.validators.common;

import org.apache.xerces.framework.XMLAttrList;
import org.apache.xerces.framework.XMLContentSpec;
import org.apache.xerces.framework.XMLDocumentHandler;
import org.apache.xerces.framework.XMLDocumentScanner;
import org.apache.xerces.framework.XMLErrorReporter;
import org.apache.xerces.readers.DefaultEntityHandler;
import org.apache.xerces.readers.XMLEntityHandler;
import org.apache.xerces.utils.ChunkyCharArray;
import org.apache.xerces.utils.Hash2intTable;
import org.apache.xerces.utils.NamespacesScope;
import org.apache.xerces.utils.QName;
import org.apache.xerces.utils.StringPool;
import org.apache.xerces.utils.XMLCharacterProperties;
import org.apache.xerces.utils.XMLMessages;
import org.apache.xerces.utils.ImplementationMessages;

import org.apache.xerces.parsers.DOMParser;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.xml.sax.InputSource;
import org.xml.sax.EntityResolver;
import org.xml.sax.Locator;
import org.xml.sax.helpers.LocatorImpl;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.IOException;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.xerces.validators.dtd.DTDGrammar;

import org.apache.xerces.validators.schema.EquivClassComparator;
import org.apache.xerces.validators.schema.SchemaGrammar;
import org.apache.xerces.validators.schema.SchemaMessageProvider;
import org.apache.xerces.validators.schema.SchemaSymbols;
import org.apache.xerces.validators.schema.TraverseSchema;

import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
import org.apache.xerces.validators.datatype.DatatypeValidator;
import org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
import org.apache.xerces.validators.datatype.StateMessageDatatype;
import org.apache.xerces.validators.datatype.IDREFDatatypeValidator;
import org.apache.xerces.validators.datatype.IDDatatypeValidator;
import org.apache.xerces.validators.datatype.ENTITYDatatypeValidator;

/**
* This class is the super all-in-one validator used by the parser.
*
* @version $Id: XMLValidator.java,v 1.77 2000/08/31 00:41:57 jeffreyr Exp $
*/
public final class XMLValidator
implements DefaultEntityHandler.EventHandler,
XMLEntityHandler.CharDataHandler,
XMLDocumentScanner.EventHandler,
NamespacesScope.NamespacesHandler {

    //
    // Constants
    //

    // debugging

    private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
    private static final boolean DEBUG_PRINT_ATTRIBUTES = false;
    private static final boolean DEBUG_PRINT_CONTENT = false;
    private static final boolean DEBUG_SCHEMA_VALIDATION = false;
    private static final boolean DEBUG_ELEMENT_CHILDREN = false;

    // Chunk size constants

    private static final int CHUNK_SHIFT = 8;           // 2^8 = 256
    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT));   // 2^10 = 1k

    private Hashtable fIdDefs = null;


    private  StateMessageDatatype fStoreIDRef = new StateMessageDatatype() {
        private Hashtable fIdDefs;
        public Object getDatatypeObject(){
            return(Object) fIdDefs;
        }
        public int    getDatatypeState(){
            return IDREFDatatypeValidator.IDREF_STORE;
        }
        public void setDatatypeObject( Object data ){
            fIdDefs = (Hashtable) data;
        }
    };

    private StateMessageDatatype fResetID = new StateMessageDatatype() {
        public Object getDatatypeObject(){
            return(Object) null;
        }
        public int    getDatatypeState(){
            return IDDatatypeValidator.ID_CLEAR;
        }
        public void setDatatypeObject( Object data ){
        }
    };


    private StateMessageDatatype fResetIDRef = new StateMessageDatatype() {
        public Object getDatatypeObject(){
            return(Object) null;
        }
        public int    getDatatypeState(){
            return IDREFDatatypeValidator.IDREF_CLEAR;
        }
        public void setDatatypeObject( Object data ){
        }
    };

    private  StateMessageDatatype fValidateIDRef = new StateMessageDatatype() {
        public Object getDatatypeObject(){
            return(Object) null;
        }
        public int    getDatatypeState(){
            return IDREFDatatypeValidator.IDREF_VALIDATE;
        }
        public void setDatatypeObject( Object data ){
        }
    };


    private  StateMessageDatatype fValidateENTITYMsg = new StateMessageDatatype() {
        private  Object  packagedMessage = null;
        public Object getDatatypeObject(){
            return packagedMessage;
        }
        public int    getDatatypeState(){
            return ENTITYDatatypeValidator.ENTITY_INITIALIZE;//No state
        }
        public void setDatatypeObject( Object data ){
            packagedMessage = data;// Set Entity Handler
        }
    };

    /*
    private  StateMessageDatatype fValidateNOTATIONMsg = new StateMessageDatatype() {
        private  Object  packagedMessage = null;
        public Object getDatatypeObject(){
            return packagedMessage;
        }
        public int    getDatatypeState(){
            return NOTATIONDatatypeValidator.ENTITY_INITIALIZE;//No state
        }
        public void setDatatypeObject( Object data ){
            packagedMessage = data;// Set Entity Handler
        }
    };
    */





    //
    // Data
    //

    // REVISIT: The data should be regrouped and re-organized so that
    //          it's easier to find a meaningful field.

    // debugging

//    private static boolean DEBUG = false;

    // other

    // attribute validators

    private AttributeValidator fAttValidatorNOTATION = new AttValidatorNOTATION();
    private AttributeValidator fAttValidatorENUMERATION = new AttValidatorENUMERATION();
    private AttributeValidator fAttValidatorDATATYPE = null;

    // Package access for use by AttributeValidator classes.

    StringPool fStringPool = null;
    boolean fValidating = false;
    boolean fInElementContent = false;
    int fStandaloneReader = -1;


    // settings

    private boolean fValidationEnabled = false;
    private boolean fDynamicValidation = false;
    private boolean fSchemaValidation = true;
    private boolean fValidationEnabledByDynamic = false;
    private boolean fDynamicDisabledByValidation = false;
    private boolean fWarningOnDuplicateAttDef = false;
    private boolean fWarningOnUndeclaredElements = false;
    private boolean fLoadDTDGrammar = true;

    // declarations

    private int fDeclaration[];
    private XMLErrorReporter fErrorReporter = null;
    private DefaultEntityHandler fEntityHandler = null;
    private QName fCurrentElement = new QName();

    private ContentLeafNameTypeVector[] fContentLeafStack = new ContentLeafNameTypeVector[8];
    private int[] fValidationFlagStack = new int[8];

    private int[] fScopeStack = new int[8];
    private int[] fGrammarNameSpaceIndexStack = new int[8];

    private int[] fElementEntityStack = new int[8];
    private int[] fElementIndexStack = new int[8];
    private int[] fContentSpecTypeStack = new int[8];

    private static final int sizeQNameParts      = 8;
    private QName[] fElementQNamePartsStack      = new QName[sizeQNameParts];

    private QName[] fElementChildren = new QName[32];
    private int fElementChildrenLength = 0;
    private int[] fElementChildrenOffsetStack = new int[32];
    private int fElementDepth = -1;

    private boolean fNamespacesEnabled = false;
    private NamespacesScope fNamespacesScope = null;
    private int fNamespacesPrefix = -1;
    private QName fRootElement = new QName();
    private int fAttrListHandle = -1;
    private int fCurrentElementEntity = -1;
    private int fCurrentElementIndex = -1;
    private int fCurrentContentSpecType = -1;
    private boolean fSeenDoctypeDecl = false;

    private final int TOP_LEVEL_SCOPE = -1;
    private int fCurrentScope = TOP_LEVEL_SCOPE;
    private int fCurrentSchemaURI = -1;
    private int fEmptyURI = - 1;
    private int fXsiPrefix = - 1;
    private int fXsiURI = -2;
    private int fXsiTypeAttValue = -1;
    private DatatypeValidator fXsiTypeValidator = null;

    private Grammar fGrammar = null;
    private int fGrammarNameSpaceIndex = -1;
    private GrammarResolver fGrammarResolver = null;

    // state and stuff

    private boolean fScanningDTD = false;
    private XMLDocumentScanner fDocumentScanner = null;
    private boolean fCalledStartDocument = false;
    private XMLDocumentHandler fDocumentHandler = null;
    private XMLDocumentHandler.DTDHandler fDTDHandler = null;
    private boolean fSeenRootElement = false;
    private XMLAttrList fAttrList = null;
    private int fXMLLang = -1;
    private LocatorImpl fAttrNameLocator = null;
    private boolean fCheckedForSchema = false;
    private boolean fDeclsAreExternal = false;
    private StringPool.CharArrayRange fCurrentElementCharArrayRange = null;
    private char[] fCharRefData = null;
    private boolean fSendCharDataAsCharArray = false;
    private boolean fBufferDatatype = false;
    private StringBuffer fDatatypeBuffer = new StringBuffer();

    private QName fTempQName = new QName();
    private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
    private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
    private XMLElementDecl fTempElementDecl = new XMLElementDecl();

    private boolean fGrammarIsDTDGrammar = false;
    private boolean fGrammarIsSchemaGrammar = false;

    private boolean fNeedValidationOff = false;

    // symbols

    private int fEMPTYSymbol = -1;
    private int fANYSymbol = -1;
    private int fMIXEDSymbol = -1;
    private int fCHILDRENSymbol = -1;
    private int fCDATASymbol = -1;
    private int fIDSymbol = -1;
    private int fIDREFSymbol = -1;
    private int fIDREFSSymbol = -1;
    private int fENTITYSymbol = -1;
    private int fENTITIESSymbol = -1;
    private int fNMTOKENSymbol = -1;
    private int fNMTOKENSSymbol = -1;
    private int fNOTATIONSymbol = -1;
    private int fENUMERATIONSymbol = -1;
    private int fREQUIREDSymbol = -1;
    private int fFIXEDSymbol = -1;
    private int fDATATYPESymbol = -1;
    private int fEpsilonIndex = -1;


    //Datatype Registry

    private DatatypeValidatorFactoryImpl fDataTypeReg =
    DatatypeValidatorFactoryImpl.getDatatypeRegistry();

    private DatatypeValidator     fValID   = this.fDataTypeReg.getDatatypeValidator("ID" );
    private DatatypeValidator fValIDRef    = this.fDataTypeReg.getDatatypeValidator("IDREF" );
    private DatatypeValidator fValIDRefs   = this.fDataTypeReg.getDatatypeValidator("IDREFS" );
    private DatatypeValidator fValENTITY   = this.fDataTypeReg.getDatatypeValidator("ENTITY" );
    private DatatypeValidator fValENTITIES = this.fDataTypeReg.getDatatypeValidator("ENTITIES" );
    private DatatypeValidator fValNMTOKEN  = this.fDataTypeReg.getDatatypeValidator("NMTOKEN");
    private DatatypeValidator fValNMTOKENS = this.fDataTypeReg.getDatatypeValidator("NMTOKENS");
    private DatatypeValidator fValNOTATION = this.fDataTypeReg.getDatatypeValidator("NOTATION" );


    //
    // Constructors
    //

    /** Constructs an XML validator. */
    public XMLValidator(StringPool stringPool,
                        XMLErrorReporter errorReporter,
                        DefaultEntityHandler entityHandler,
                        XMLDocumentScanner documentScanner) {

        // keep references
        fStringPool = stringPool;
        fErrorReporter = errorReporter;
        fEntityHandler = entityHandler;
        fDocumentScanner = documentScanner;

        fEmptyURI = fStringPool.addSymbol("");
        fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
        // initialize
        fAttrList = new XMLAttrList(fStringPool);
        entityHandler.setEventHandler(this);
        entityHandler.setCharDataHandler(this);
        fDocumentScanner.setEventHandler(this);

        for (int i = 0; i < sizeQNameParts; i++) {
            fElementQNamePartsStack[i] = new QName();
        }
        init();

    } // <init>(StringPool,XMLErrorReporter,DefaultEntityHandler,XMLDocumentScanner)

    public void setGrammarResolver(GrammarResolver grammarResolver){
        fGrammarResolver = grammarResolver;
    }

    //
    // Public methods
    //

    // initialization

    /** Set char data processing preference and handlers. */
    public void initHandlers(boolean sendCharDataAsCharArray,
                             XMLDocumentHandler docHandler,
                             XMLDocumentHandler.DTDHandler dtdHandler) {

        fSendCharDataAsCharArray = sendCharDataAsCharArray;
        fEntityHandler.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
        fDocumentHandler = docHandler;
        fDTDHandler = dtdHandler;

    } // initHandlers(boolean,XMLDocumentHandler,XMLDocumentHandler.DTDHandler)

    /** Reset or copy. */
    public void resetOrCopy(StringPool stringPool) throws Exception {
        fAttrList = new XMLAttrList(stringPool);
        resetCommon(stringPool);
    }

    /** Reset. */
    public void reset(StringPool stringPool) throws Exception {
        fAttrList.reset(stringPool);
        resetCommon(stringPool);
    }


    // settings

    /**
     * Turning on validation/dynamic turns on validation if it is off, and
     * this is remembered.  Turning off validation DISABLES validation/dynamic
     * if it is on.  Turning off validation/dynamic DOES NOT turn off
     * validation if it was explicitly turned on, only if it was turned on
     * BECAUSE OF the call to turn validation/dynamic on.  Turning on
     * validation will REENABLE and turn validation/dynamic back on if it
     * was disabled by a call that turned off validation while
     * validation/dynamic was enabled.
     */
    public void setValidationEnabled(boolean flag) throws Exception {
        fValidationEnabled = flag;
        fValidationEnabledByDynamic = false;
        if (fValidationEnabled) {
            if (fDynamicDisabledByValidation) {
                fDynamicValidation = true;
                fDynamicDisabledByValidation = false;
            }
        } else if (fDynamicValidation) {
            fDynamicValidation = false;
            fDynamicDisabledByValidation = true;
        }
        fValidating = fValidationEnabled;
    }

    /** Returns true if validation is enabled. */
    public boolean getValidationEnabled() {
        return fValidationEnabled;
    }

    /** Sets whether Schema support is on/off. */
    public void setSchemaValidationEnabled(boolean flag) {
        fSchemaValidation = flag;
    }

    /** Returns true if Schema support is on. */
    public boolean getSchemaValidationEnabled() {
        return fSchemaValidation;
    }

    /** Sets whether validation is dynamic. */
    public void setDynamicValidationEnabled(boolean flag) throws Exception {
        fDynamicValidation = flag;
        fDynamicDisabledByValidation = false;
        if (!fDynamicValidation) {
            if (fValidationEnabledByDynamic) {
                fValidationEnabled = false;
                fValidationEnabledByDynamic = false;
            }
        } else if (!fValidationEnabled) {
            fValidationEnabled = true;
            fValidationEnabledByDynamic = true;
        }
        fValidating = fValidationEnabled;
    }

    /** Returns true if validation is dynamic. */
    public boolean getDynamicValidationEnabled() {
        return fDynamicValidation;
    }

    /** Sets fLoadDTDGrammar when validation is off **/
    public void setLoadDTDGrammar(boolean loadDG){
        if (fValidating) {
            fLoadDTDGrammar = true;
        } else {
            fLoadDTDGrammar = loadDG;
        }
    }

    /** Returns fLoadDTDGrammar **/
    public boolean getLoadDTDGrammar() {
        return fLoadDTDGrammar;
    }

    /** Sets whether namespaces are enabled. */
    public void setNamespacesEnabled(boolean flag) {
        fNamespacesEnabled = flag;
    }

    /** Returns true if namespaces are enabled. */
    public boolean getNamespacesEnabled() {
        return fNamespacesEnabled;
    }

    /** Sets whether duplicate attribute definitions signal a warning. */
    public void setWarningOnDuplicateAttDef(boolean flag) {
        fWarningOnDuplicateAttDef = flag;
    }

    /** Returns true if duplicate attribute definitions signal a warning. */
    public boolean getWarningOnDuplicateAttDef() {
        return fWarningOnDuplicateAttDef;
    }

    /** Sets whether undeclared elements signal a warning. */
    public void setWarningOnUndeclaredElements(boolean flag) {
        fWarningOnUndeclaredElements = flag;
    }

    /** Returns true if undeclared elements signal a warning. */
    public boolean getWarningOnUndeclaredElements() {
        return fWarningOnUndeclaredElements;
    }

    //
    // DefaultEntityHandler.EventHandler methods
    //

    /** Start entity reference. */
    public void startEntityReference(int entityName, int entityType, int entityContext) throws Exception {
        fDocumentHandler.startEntityReference(entityName, entityType, entityContext);
    }

    /** End entity reference. */
    public void endEntityReference(int entityName, int entityType, int entityContext) throws Exception {
        fDocumentHandler.endEntityReference(entityName, entityType, entityContext);
    }

    /** Send end of input notification. */
    public void sendEndOfInputNotifications(int entityName, boolean moreToFollow) throws Exception {
        fDocumentScanner.endOfInput(entityName, moreToFollow);
        /***
        if (fScanningDTD) {
            fDTDImporter.sendEndOfInputNotifications(entityName, moreToFollow);
        }
        /***/
    }

    /** Send reader change notifications. */
    public void sendReaderChangeNotifications(XMLEntityHandler.EntityReader reader, int readerId) throws Exception {
        fDocumentScanner.readerChange(reader, readerId);
        /***
        if (fScanningDTD) {
            fDTDImporter.sendReaderChangeNotifications(reader, readerId);
        }
        /***/
    }

    /** External entity standalone check. */
    public boolean externalEntityStandaloneCheck() {
        return(fStandaloneReader != -1 && fValidating);
    }

    /** Return true if validating. */
    public boolean getValidating() {
        return fValidating;
    }

    //
    // XMLEntityHandler.CharDataHandler methods
    //

    /** Process characters. */
    public void processCharacters(char[] chars, int offset, int length) throws Exception {
        if (fValidating) {
            if (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
                charDataInContent();
            }
            if (fBufferDatatype) {
                fDatatypeBuffer.append(chars, offset, length);
            }
        }
        fDocumentHandler.characters(chars, offset, length);
    }

    /** Process characters. */
    public void processCharacters(int data) throws Exception {
        if (fValidating) {
            if (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
                charDataInContent();
            }
            if (fBufferDatatype) {
                fDatatypeBuffer.append(fStringPool.toString(data));
            }
        }
        fDocumentHandler.characters(data);
    }

    /** Process whitespace. */
    public void processWhitespace(char[] chars, int offset, int length)
    throws Exception {

        if (fInElementContent) {
            if (fStandaloneReader != -1 && fValidating && getElementDeclIsExternal(fCurrentElementIndex)) {
                reportRecoverableXMLError(XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE,
                                          XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
            }
            fDocumentHandler.ignorableWhitespace(chars, offset, length);
        } else {
            if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
                charDataInContent();
            }
            fDocumentHandler.characters(chars, offset, length);
        }

    } // processWhitespace(char[],int,int)

    /** Process whitespace. */
    public void processWhitespace(int data) throws Exception {

        if (fInElementContent) {
            if (fStandaloneReader != -1 && fValidating && getElementDeclIsExternal(fCurrentElementIndex)) {
                reportRecoverableXMLError(XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE,
                                          XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
            }
            fDocumentHandler.ignorableWhitespace(data);
        } else {
            if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
                charDataInContent();
            }
            fDocumentHandler.characters(data);
        }

    } // processWhitespace(int)

    //
    // XMLDocumentScanner.EventHandler methods
    //

    /** Scans element type. */
    public void scanElementType(XMLEntityHandler.EntityReader entityReader,
                                char fastchar, QName element) throws Exception {

        if (!fNamespacesEnabled) {
            element.clear();
            element.localpart = entityReader.scanName(fastchar);
            element.rawname = element.localpart;
        } else {
            entityReader.scanQName(fastchar, element);
            if (entityReader.lookingAtChar(':', false)) {
                fErrorReporter.reportError(fErrorReporter.getLocator(),
                                           XMLMessages.XML_DOMAIN,
                                           XMLMessages.MSG_TWO_COLONS_IN_QNAME,
                                           XMLMessages.P5_INVALID_CHARACTER,
                                           null,
                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
                entityReader.skipPastNmtoken(' ');
            }
        }

    } // scanElementType(XMLEntityHandler.EntityReader,char,QName)

    /** Scans expected element type. */
    public boolean scanExpectedElementType(XMLEntityHandler.EntityReader entityReader,
                                           char fastchar, QName element)
    throws Exception {

        if (fCurrentElementCharArrayRange == null) {
            fCurrentElementCharArrayRange = fStringPool.createCharArrayRange();
        }
        fStringPool.getCharArrayRange(fCurrentElement.rawname, fCurrentElementCharArrayRange);
        return entityReader.scanExpectedName(fastchar, fCurrentElementCharArrayRange);

    } // scanExpectedElementType(XMLEntityHandler.EntityReader,char,QName)

    /** Scans attribute name. */
    public void scanAttributeName(XMLEntityHandler.EntityReader entityReader,
                                  QName element, QName attribute)
    throws Exception {

        if (!fSeenRootElement) {
            fSeenRootElement = true;
            rootElementSpecified(element);
            fStringPool.resetShuffleCount();
        }

        if (!fNamespacesEnabled) {
            attribute.clear();
            attribute.localpart = entityReader.scanName('=');
            attribute.rawname = attribute.localpart;
        } else {
            entityReader.scanQName('=', attribute);
            if (entityReader.lookingAtChar(':', false)) {
                fErrorReporter.reportError(fErrorReporter.getLocator(),
                                           XMLMessages.XML_DOMAIN,
                                           XMLMessages.MSG_TWO_COLONS_IN_QNAME,
                                           XMLMessages.P5_INVALID_CHARACTER,
                                           null,
                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
                entityReader.skipPastNmtoken(' ');
            }
        }

    } // scanAttributeName(XMLEntityHandler.EntityReader,QName,QName)

    /** Call start document. */
    public void callStartDocument() throws Exception {

        if (!fCalledStartDocument) {
            fDocumentHandler.startDocument();
            fCalledStartDocument = true;
        }
    }

    /** Call end document. */
    public void callEndDocument() throws Exception {

        if (fCalledStartDocument) {
            fDocumentHandler.endDocument();
        }
    }

    /** Call XML declaration. */
    public void callXMLDecl(int version, int encoding, int standalone) throws Exception {
        fDocumentHandler.xmlDecl(version, encoding, standalone);
    }
    public void callStandaloneIsYes() throws Exception {
        // standalone = "yes". said XMLDocumentScanner.
        fStandaloneReader = fEntityHandler.getReaderId() ;

    }



    /** Call text declaration. */
    public void callTextDecl(int version, int encoding) throws Exception {
        fDocumentHandler.textDecl(version, encoding);
    }

    /**
     * Signal the scanning of an element name in a start element tag.
     *
     * @param element Element name scanned.
     */
    public void element(QName element) throws Exception {
        fAttrListHandle = -1;
    }
    /**
     * Signal the scanning of an attribute associated to the previous
     * start element tag.
     *
     * @param element Element name scanned.
     * @param attrName Attribute name scanned.
     * @param attrValue The string pool index of the attribute value.
     */
    public boolean attribute(QName element, QName attrName, int attrValue) throws Exception {
        if (fAttrListHandle == -1) {
            fAttrListHandle = fAttrList.startAttrList();
        }

        // if fAttrList.addAttr returns -1, indicates duplicate att in start tag of an element.
        // specified: true, search : true
        return fAttrList.addAttr(attrName, attrValue, fCDATASymbol, true, true) == -1;
    }

    /** Call start element. */
    public void callStartElement(QName element) throws Exception {

        if ( DEBUG_SCHEMA_VALIDATION )
            System.out.println("\n=======StartElement : " + fStringPool.toString(element.localpart));


        //
        // Check after all specified attrs are scanned
        // (1) report error for REQUIRED attrs that are missing (V_TAGc)
        // (2) add default attrs (FIXED and NOT_FIXED)
        //

        if (!fSeenRootElement) {
            fSeenRootElement = true;
            rootElementSpecified(element);
            fStringPool.resetShuffleCount();
        }

        if (fGrammar != null && fGrammarIsDTDGrammar) {
            fAttrListHandle = addDTDDefaultAttributes(element, fAttrList, fAttrListHandle, fValidating, fStandaloneReader != -1);
        }

        fCheckedForSchema = true;
        if (fNamespacesEnabled) {
            bindNamespacesToElementAndAttributes(element, fAttrList);
        }

        validateElementAndAttributes(element, fAttrList);
        if (fAttrListHandle != -1) {
            fAttrList.endAttrList();
        }

        fDocumentHandler.startElement(element, fAttrList, fAttrListHandle);
        fAttrListHandle = -1;

        //before we increment the element depth, add this element's QName to its enclosing element 's children list
        fElementDepth++;
        //if (fElementDepth >= 0) {
        if (fValidating) {
            // push current length onto stack
            if (fElementChildrenOffsetStack.length < fElementDepth) {
                int newarray[] = new int[fElementChildrenOffsetStack.length * 2];
                System.arraycopy(fElementChildrenOffsetStack, 0, newarray, 0, fElementChildrenOffsetStack.length);
                fElementChildrenOffsetStack = newarray;
            }
            fElementChildrenOffsetStack[fElementDepth] = fElementChildrenLength;

            // add this element to children
            if (fElementChildren.length <= fElementChildrenLength) {
                QName[] newarray = new QName[fElementChildrenLength * 2];
                System.arraycopy(fElementChildren, 0, newarray, 0, fElementChildren.length);
                fElementChildren = newarray;
            }
            QName qname = fElementChildren[fElementChildrenLength];
            if (qname == null) {
                for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
                    fElementChildren[i] = new QName();
                }
                qname = fElementChildren[fElementChildrenLength];
            }
            qname.setValues(element);
            fElementChildrenLength++;

            if (DEBUG_ELEMENT_CHILDREN) {
                printChildren();
                printStack();
            }
        }

        // One more level of depth
        //fElementDepth++;

        ensureStackCapacity(fElementDepth);
        fCurrentElement.setValues(element);
        fCurrentElementEntity = fEntityHandler.getReaderId();

        fElementQNamePartsStack[fElementDepth].setValues(fCurrentElement);

        fElementEntityStack[fElementDepth] = fCurrentElementEntity;
        fElementIndexStack[fElementDepth] = fCurrentElementIndex;
        fContentSpecTypeStack[fElementDepth] = fCurrentContentSpecType;

        if (fNeedValidationOff) {
            fValidating = false;
            fNeedValidationOff = false;
        }

        if (fValidating && fGrammarIsSchemaGrammar) {
            pushContentLeafStack();
        }

        fValidationFlagStack[fElementDepth] = fValidating ? 0 : -1;

        fScopeStack[fElementDepth] = fCurrentScope;
        fGrammarNameSpaceIndexStack[fElementDepth] = fGrammarNameSpaceIndex;

    } // callStartElement(QName)

    private void pushContentLeafStack() throws Exception {
        int contentType = getContentSpecType(fCurrentElementIndex);
        if ( contentType == XMLElementDecl.TYPE_CHILDREN) {
            XMLContentModel cm = getElementContentModel(fCurrentElementIndex);
            ContentLeafNameTypeVector cv = cm.getContentLeafNameTypeVector();
            if (cm != null) {
                fContentLeafStack[fElementDepth] = cv;
            }
        }
    }

    private void ensureStackCapacity ( int newElementDepth) {

        if (newElementDepth == fElementQNamePartsStack.length ) {
            int[] newStack = new int[newElementDepth * 2];
            System.arraycopy(fScopeStack, 0, newStack, 0, newElementDepth);
            fScopeStack = newStack;

            newStack = new int[newElementDepth * 2];
            System.arraycopy(fGrammarNameSpaceIndexStack, 0, newStack, 0, newElementDepth);
            fGrammarNameSpaceIndexStack = newStack;

            QName[] newStackOfQueue = new QName[newElementDepth * 2];
            System.arraycopy(this.fElementQNamePartsStack, 0, newStackOfQueue, 0, newElementDepth );
            fElementQNamePartsStack      = newStackOfQueue;

            QName qname = fElementQNamePartsStack[newElementDepth];
            if (qname == null) {
                for (int i = newElementDepth; i < fElementQNamePartsStack.length; i++) {
                    fElementQNamePartsStack[i] = new QName();
                }
            }

            newStack = new int[newElementDepth * 2];
            System.arraycopy(fElementEntityStack, 0, newStack, 0, newElementDepth);
            fElementEntityStack = newStack;

            newStack = new int[newElementDepth * 2];
            System.arraycopy(fElementIndexStack, 0, newStack, 0, newElementDepth);
            fElementIndexStack = newStack;

            newStack = new int[newElementDepth * 2];
            System.arraycopy(fContentSpecTypeStack, 0, newStack, 0, newElementDepth);
            fContentSpecTypeStack = newStack;

            newStack = new int[newElementDepth * 2];
            System.arraycopy(fValidationFlagStack, 0, newStack, 0, newElementDepth);
            fValidationFlagStack = newStack;

            ContentLeafNameTypeVector[] newStackV = new ContentLeafNameTypeVector[newElementDepth * 2];
            System.arraycopy(fContentLeafStack, 0, newStackV, 0, newElementDepth);
            fContentLeafStack = newStackV;
        }
    }

    /** Call end element. */
    public void callEndElement(int readerId) throws Exception {
        if ( DEBUG_SCHEMA_VALIDATION )
            System.out.println("=======EndElement : " + fStringPool.toString(fCurrentElement.localpart)+"\n");

        int prefixIndex = fCurrentElement.prefix;
        int elementType = fCurrentElement.rawname;

        if (fCurrentElementEntity != readerId) {
            fErrorReporter.reportError(fErrorReporter.getLocator(),
                                       XMLMessages.XML_DOMAIN,
                                       XMLMessages.MSG_ELEMENT_ENTITY_MISMATCH,
                                       XMLMessages.P78_NOT_WELLFORMED,
                                       new Object[] { fStringPool.toString(elementType)},
                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
        }

        fElementDepth--;
        if (fValidating) {
            int elementIndex = fCurrentElementIndex;
            if (elementIndex != -1 && fCurrentContentSpecType != -1) {
                QName children[] = fElementChildren;
                int childrenOffset = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
                int childrenLength = fElementChildrenLength - childrenOffset;
                if (DEBUG_ELEMENT_CHILDREN) {
                    System.out.println("endElement("+fStringPool.toString(fCurrentElement.rawname)+')');
                    System.out.println("fCurrentContentSpecType : " + fCurrentContentSpecType );
                    System.out.print("offset: ");
                    System.out.print(childrenOffset);
                    System.out.print(", length: ");
                    System.out.print(childrenLength);
                    System.out.println();
                    printChildren();
                    printStack();
                }
                int result = checkContent(elementIndex,
                                          children, childrenOffset, childrenLength);

                if ( DEBUG_SCHEMA_VALIDATION )
                    System.out.println("!!!!!!!!In XMLValidator, the return value from checkContent : " + result);

                if (result != -1) {
                    int majorCode = result != childrenLength ? XMLMessages.MSG_CONTENT_INVALID : XMLMessages.MSG_CONTENT_INCOMPLETE;
                    fGrammar.getElementDecl(elementIndex, fTempElementDecl);
                    if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
                        reportRecoverableXMLError(majorCode,
                                                  0,
                                                  fStringPool.toString(elementType),
                                                  "EMPTY");
                    } else
                        reportRecoverableXMLError(majorCode,
                                                  0,
                                                  fStringPool.toString(elementType),
                                                  XMLContentSpec.toString(fGrammar, fStringPool, fTempElementDecl.contentSpecIndex));
                }
            }
            fElementChildrenLength = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
        }
        fDocumentHandler.endElement(fCurrentElement);
        if (fNamespacesEnabled) {
            fNamespacesScope.decreaseDepth();
        }

        // now pop this element off the top of the element stack
        //if (fElementDepth-- < 0) {
        if (fElementDepth < -1) {
            throw new RuntimeException("FWK008 Element stack underflow");
        }
        if (fElementDepth < 0) {
            fCurrentElement.clear();
            fCurrentElementEntity = -1;
            fCurrentElementIndex = -1;
            fCurrentContentSpecType = -1;
            fInElementContent = false;
            //
            // Check after document is fully parsed
            // (1) check that there was an element with a matching id for every
            //   IDREF and IDREFS attr (V_IDREF0)
            //
            if (fValidating ) {
                try {
                    this.fValIDRef.validate( null, this.fValidateIDRef );  
                    this.fValIDRefs.validate( null, this.fValidateIDRef );
                } catch ( InvalidDatatypeValueException ex ) {
                    reportRecoverableXMLError( ex.getMajorCode(), ex.getMinorCode(),
                                               ex.getMessage() );


                }
            }
           
            try {//Reset datatypes state
               this.fValID.validate( null, this.fResetID );
               this.fValIDRef.validate(null, this.fResetIDRef );
               this.fValIDRefs.validate(null, this.fResetIDRef );
            } catch ( InvalidDatatypeValueException ex ) {
                System.err.println("Error re-Initializing: ID,IDRef,IDRefs pools" );
            }
            return;
        }


        //restore enclosing element to all the "current" variables
        // REVISIT: Validation. This information needs to be stored.
        fCurrentElement.prefix = -1;


        if (fNamespacesEnabled) { //If Namespace enable then localName != rawName
            fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].localpart;
        } else {//REVISIT - jeffreyr - This is so we still do old behavior when namespace is off
            fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].rawname;
        }
        fCurrentElement.rawname      = fElementQNamePartsStack[fElementDepth].rawname;
        fCurrentElement.uri          = fElementQNamePartsStack[fElementDepth].uri;
        fCurrentElement.prefix       = fElementQNamePartsStack[fElementDepth].prefix;


        fCurrentElementEntity = fElementEntityStack[fElementDepth];
        fCurrentElementIndex = fElementIndexStack[fElementDepth];
        fCurrentContentSpecType = fContentSpecTypeStack[fElementDepth];

        fValidating = fValidationFlagStack[fElementDepth] == 0 ? true : false;

        fCurrentScope = fScopeStack[fElementDepth]

        //if ( DEBUG_SCHEMA_VALIDATION ) {

/****
System.out.println("+++++ currentElement : " + fStringPool.toString(elementType)+
                   "\n fCurrentElementIndex : " + fCurrentElementIndex +
                   "\n fCurrentScope : " + fCurrentScope +
                   "\n fCurrentContentSpecType : " + fCurrentContentSpecType +
                   "\n++++++++++++++++++++++++++++++++++++++++++++++++" );
/****/
        //}

        // if enclosing element's Schema is different, need to switch "context"
        if ( fGrammarNameSpaceIndex != fGrammarNameSpaceIndexStack[fElementDepth] ) {
            fGrammarNameSpaceIndex = fGrammarNameSpaceIndexStack[fElementDepth];
            if ( fValidating && fGrammarIsSchemaGrammar )
                if ( !switchGrammar(fGrammarNameSpaceIndex) ) {
                    reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR,
                                              "Grammar with uri : " + fStringPool.toString(fGrammarNameSpaceIndex)
                                              + " , can not found");
                }
        }

        if (fValidating) {
            fBufferDatatype = false;
        }
        fInElementContent = (fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN);

    } // callEndElement(int)

    /** Call start CDATA section. */
    public void callStartCDATA() throws Exception {
        fDocumentHandler.startCDATA();
    }

    /** Call end CDATA section. */
    public void callEndCDATA() throws Exception {
        fDocumentHandler.endCDATA();
    }

    /** Call characters. */
    public void callCharacters(int ch) throws Exception {

        if (fCharRefData == null) {
            fCharRefData = new char[2];
        }
        int count = (ch < 0x10000) ? 1 : 2;
        if (count == 1) {
            fCharRefData[0] = (char)ch;
        } else {
            fCharRefData[0] = (char)(((ch-0x00010000)>>10)+0xd800);
            fCharRefData[1] = (char)(((ch-0x00010000)&0x3ff)+0xdc00);
        }
        if (fValidating && (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY)) {
            charDataInContent();
        }
        if (fSendCharDataAsCharArray) {
            fDocumentHandler.characters(fCharRefData, 0, count);
        } else {
            int index = fStringPool.addString(new String(fCharRefData, 0, count));
            fDocumentHandler.characters(index);
        }

    } // callCharacters(int)

    /** Call processing instruction. */
    public void callProcessingInstruction(int target, int data) throws Exception {
        fDocumentHandler.processingInstruction(target, data);
    }

    /** Call comment. */
    public void callComment(int comment) throws Exception {
        fDocumentHandler.comment(comment);
    }

    //
    // NamespacesScope.NamespacesHandler methods
    //

    /** Start a new namespace declaration scope. */
    public void startNamespaceDeclScope(int prefix, int uri) throws Exception {
        fDocumentHandler.startNamespaceDeclScope(prefix, uri);
    }

    /** End a namespace declaration scope. */
    public void endNamespaceDeclScope(int prefix) throws Exception {
        fDocumentHandler.endNamespaceDeclScope(prefix);
    }

    // attributes


    // other

    /** Sets the root element. */
    public void setRootElementType(QName rootElement) {
        fRootElement.setValues(rootElement);
    }

    /**
     * Returns true if the element declaration is external.
     * <p>
     * <strong>Note:</strong> This method is primarilly useful for
     * DTDs with internal and external subsets.
     */
    private boolean getElementDeclIsExternal(int elementIndex) {
        /*if (elementIndex < 0 || elementIndex >= fElementCount) {
            return false;
        }
        int chunk = elementIndex >> CHUNK_SHIFT;
        int index = elementIndex & CHUNK_MASK;
        return (fElementDeclIsExternal[chunk][index] != 0);
        */

        if (fGrammarIsDTDGrammar ) {
            return((DTDGrammar) fGrammar).getElementDeclIsExternal(elementIndex);
        }
        return false;
    }

    /** Returns the content spec type for an element index. */
    public int getContentSpecType(int elementIndex) {

        int contentSpecType = -1;
        if ( elementIndex > -1) {
            if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
                contentSpecType = fTempElementDecl.type;
            }
        }
        return contentSpecType;
    }

    /** Returns the content spec handle for an element index. */
    public int getContentSpecHandle(int elementIndex) {
        int contentSpecHandle = -1;
        if ( elementIndex > -1) {
            if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
                contentSpecHandle = fTempElementDecl.contentSpecIndex;
            }
        }
        return contentSpecHandle;
    }

    //
    // Protected methods
    //

    // error reporting

    /** Report a recoverable xml error. */
    protected void reportRecoverableXMLError(int majorCode, int minorCode)
    throws Exception {

        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                   XMLMessages.XML_DOMAIN,
                                   majorCode,
                                   minorCode,
                                   null,
                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);

    } // reportRecoverableXMLError(int,int)

    /** Report a recoverable xml error. */
    protected void reportRecoverableXMLError(int majorCode, int minorCode,
                                             int stringIndex1)
    throws Exception {

        Object[] args = { fStringPool.toString(stringIndex1)};
        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                   XMLMessages.XML_DOMAIN,
                                   majorCode,
                                   minorCode,
                                   args,
                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);

    } // reportRecoverableXMLError(int,int,int)

    /** Report a recoverable xml error. */
    protected void reportRecoverableXMLError(int majorCode, int minorCode,
                                             String string1) throws Exception {

        Object[] args = { string1};
        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                   XMLMessages.XML_DOMAIN,
                                   majorCode,
                                   minorCode,
                                   args,
                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);

    } // reportRecoverableXMLError(int,int,String)

    /** Report a recoverable xml error. */
    protected void reportRecoverableXMLError(int majorCode, int minorCode,
                                             int stringIndex1, int stringIndex2)
    throws Exception {

        Object[] args = { fStringPool.toString(stringIndex1), fStringPool.toString(stringIndex2)};
        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                   XMLMessages.XML_DOMAIN,
                                   majorCode,
                                   minorCode,
                                   args,
                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);

    } // reportRecoverableXMLError(int,int,int,int)

    /** Report a recoverable xml error. */
    protected void reportRecoverableXMLError(int majorCode, int minorCode,
                                             String string1, String string2)
    throws Exception {

        Object[] args = { string1, string2};
        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                   XMLMessages.XML_DOMAIN,
                                   majorCode,
                                   minorCode,
                                   args,
                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);

    } // reportRecoverableXMLError(int,int,String,String)

    /** Report a recoverable xml error. */
    protected void reportRecoverableXMLError(int majorCode, int minorCode,
                                             String string1, String string2,
                                             String string3) throws Exception {

        Object[] args = { string1, string2, string3};
        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                   XMLMessages.XML_DOMAIN,
                                   majorCode,
                                   minorCode,
                                   args,
                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);

    } // reportRecoverableXMLError(int,int,String,String,String)

    // content spec

    /**
     * Returns information about which elements can be placed at a particular point
     * in the passed element's content model.
     * <p>
     * Note that the incoming content model to test must be valid at least up to
     * the insertion point. If not, then -1 will be returned and the info object
     * will not have been filled in.
     * <p>
     * If, on return, the info.isValidEOC flag is set, then the 'insert after'
     * elemement is a valid end of content, i.e. nothing needs to be inserted
     * after it to make the parent element's content model valid.
     *
     * @param elementIndex The index within the <code>ElementDeclPool</code> of the
     *                     element which is being querying.
     * @param fullyValid Only return elements that can be inserted and still
     *                   maintain the validity of subsequent elements past the
     *                   insertion point (if any).  If the insertion point is at
     *                   the end, and this is true, then only elements that can
     *                   be legal final states will be returned.
     * @param info An object that contains the required input data for the method,
     *             and which will contain the output information if successful.
     *
     * @return The value -1 if fully valid, else the 0 based index of the child
     *         that first failed before the insertion point. If the value
     *         returned is equal to the number of children, then the specified
     *         children are valid but additional content is required to reach a
     *         valid ending state.
     *
     * @exception Exception Thrown on error.
     *
     * @see InsertableElementsInfo
     */
    protected int whatCanGoHere(int elementIndex, boolean fullyValid,
                                InsertableElementsInfo info) throws Exception {

        //
        //  Do some basic sanity checking on the info packet. First, make sure
        //  that insertAt is not greater than the child count. It can be equal,
        //  which means to get appendable elements, but not greater. Or, if
        //  the current children array is null, that's bad too.
        //
        //  Since the current children array must have a blank spot for where
        //  the insert is going to be, the child count must always be at least
        //  one.
        //
        //  Make sure that the child count is not larger than the current children
        //  array. It can be equal, which means get appendable elements, but not
        //  greater.
        //
        if (info.insertAt > info.childCount || info.curChildren == null || 
            info.childCount < 1 || info.childCount > info.curChildren.length) {
            fErrorReporter.reportError(fErrorReporter.getLocator(),
                                       ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
                                       ImplementationMessages.VAL_WCGHI,
                                       0,
                                       null,
                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
        }

        int retVal = 0;
        try {
            // Get the content model for this element
            final XMLContentModel cmElem = getElementContentModel(elementIndex);

            // And delegate this call to it
            retVal = cmElem.whatCanGoHere(fullyValid, info);
        } catch (CMException excToCatch) {
            // REVISIT - Translate caught error to the protected error handler interface
            int majorCode = excToCatch.getErrorCode();
            fErrorReporter.reportError(fErrorReporter.getLocator(),
                                       ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
                                       majorCode,
                                       0,
                                       null,
                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
            throw excToCatch;
        }
        return retVal;

    } // whatCanGoHere(int,boolean,InsertableElementsInfo):int

    // attribute information

    /** Protected for use by AttributeValidator classes. */
    protected boolean getAttDefIsExternal(QName element, QName attribute) {
        int attDefIndex = getAttDef(element, attribute);
        if (fGrammarIsDTDGrammar ) {
            return((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attDefIndex);
        }
        return false;
    }



    //
    // Private methods
    //

    // other

    /** Returns true if using a standalone reader. */
    private boolean usingStandaloneReader() {
        return fStandaloneReader == -1 || fEntityHandler.getReaderId() == fStandaloneReader;
    }

    /** Returns a locator implementation. */
    private LocatorImpl getLocatorImpl(LocatorImpl fillin) {

        Locator here = fErrorReporter.getLocator();
        if (fillin == null)
            return new LocatorImpl(here);
        fillin.setPublicId(here.getPublicId());
        fillin.setSystemId(here.getSystemId());
        fillin.setLineNumber(here.getLineNumber());
        fillin.setColumnNumber(here.getColumnNumber());
        return fillin;

    } // getLocatorImpl(LocatorImpl):LocatorImpl


    // initialization

    /** Reset pool. */
    private void poolReset() {
        try {
            //System.out.println("We reset" );
            this.fValID.validate( null, this.fResetID );
            this.fValIDRef.validate(null, this.fResetIDRef );
            this.fValIDRefs.validate(null, this.fResetIDRef );
        } catch ( InvalidDatatypeValueException ex ) {
            System.err.println("Error re-Initializing: ID,IDRef,IDRefs pools" );
        }
    } // poolReset()

    /** Reset common. */
    private void resetCommon(StringPool stringPool) throws Exception {

        fStringPool = stringPool;
        fValidating = fValidationEnabled;
        fValidationEnabledByDynamic = false;
        fDynamicDisabledByValidation = false;
        poolReset();
        fCalledStartDocument = false;
        fStandaloneReader = -1;
        fElementChildrenLength = 0;
        fElementDepth = -1;
        fSeenRootElement = false;
        fSeenDoctypeDecl = false;
        fNamespacesScope = null;
        fNamespacesPrefix = -1;
        fRootElement.clear();
        fAttrListHandle = -1;
        fCheckedForSchema = false;

        fCurrentScope = TOP_LEVEL_SCOPE;
        fCurrentSchemaURI = -1;
        fEmptyURI = - 1;
        fXsiPrefix = - 1;
        fXsiTypeValidator = null;

        fGrammar = null;
        fGrammarNameSpaceIndex = -1;
        //fGrammarResolver = null;
        if (fGrammarResolver != null) {
            fGrammarResolver.clearGrammarResolver();
        }
        fGrammarIsDTDGrammar = false;
        fGrammarIsSchemaGrammar = false;


        init();

    } // resetCommon(StringPool)

    /** Initialize. */
    private void init() {

        fEmptyURI = fStringPool.addSymbol("");
        fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);


        fEMPTYSymbol = fStringPool.addSymbol("EMPTY");
        fANYSymbol = fStringPool.addSymbol("ANY");
        fMIXEDSymbol = fStringPool.addSymbol("MIXED");
        fCHILDRENSymbol = fStringPool.addSymbol("CHILDREN");

        fCDATASymbol = fStringPool.addSymbol("CDATA");
        fIDSymbol = fStringPool.addSymbol("ID");
        fIDREFSymbol = fStringPool.addSymbol("IDREF");
        fIDREFSSymbol = fStringPool.addSymbol("IDREFS");
        fENTITYSymbol = fStringPool.addSymbol("ENTITY");
        fENTITIESSymbol = fStringPool.addSymbol("ENTITIES");
        fNMTOKENSymbol = fStringPool.addSymbol("NMTOKEN");
        fNMTOKENSSymbol = fStringPool.addSymbol("NMTOKENS");
        fNOTATIONSymbol = fStringPool.addSymbol("NOTATION");
        fENUMERATIONSymbol = fStringPool.addSymbol("ENUMERATION");
        fREQUIREDSymbol = fStringPool.addSymbol("#REQUIRED");
        fFIXEDSymbol = fStringPool.addSymbol("#FIXED");
        fDATATYPESymbol = fStringPool.addSymbol("<<datatype>>");
        fEpsilonIndex = fStringPool.addSymbol("<<CMNODE_EPSILON>>");
        fXMLLang = fStringPool.addSymbol("xml:lang");

        try {//Initialize ENTITIES and ENTITY Validators
            Object[] packageArgsEntityVal = { (Object) this.fEntityHandler,
                (Object) this.fStringPool};
            fValidateENTITYMsg.setDatatypeObject( (Object ) packageArgsEntityVal);
            fValENTITIES.validate( null, fValidateENTITYMsg );
            fValENTITY.validate( null, fValidateENTITYMsg );
        } catch ( InvalidDatatypeValueException ex ) {
            System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
        }


    } // init()

    // other

    // default attribute

    /** addDefaultAttributes. */
    private int addDefaultAttributes(int elementIndex, XMLAttrList attrList, int attrIndex, boolean validationEnabled, boolean standalone) throws Exception {

        //System.out.println("XMLValidator#addDefaultAttributes");
        //System.out.print("  ");
        //fGrammar.printAttributes(elementIndex);

        //
        // Check after all specified attrs are scanned
        // (1) report error for REQUIRED attrs that are missing (V_TAGc)
        // (2) check that FIXED attrs have matching value (V_TAGd)
        // (3) add default attrs (FIXED and NOT_FIXED)
        //
        fGrammar.getElementDecl(elementIndex,fTempElementDecl);

        int elementNameIndex = fTempElementDecl.name.localpart;
        int attlistIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
        int firstCheck = attrIndex;
        int lastCheck = -1;
        while (attlistIndex != -1) {
            //int adChunk = attlistIndex >> CHUNK_SHIFT;
            //int adIndex = attlistIndex & CHUNK_MASK;
            fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);

            // TO DO: For ericye Debug only
            /***
            if (fTempAttDecl != null) {
                XMLElementDecl element = new XMLElementDecl();
                fGrammar.getElementDecl(elementIndex, element);
                System.out.println("element: "+fStringPool.toString(element.name.localpart));
                System.out.println("attlistIndex " + attlistIndex + "\n"+
                    "attName : '"+fStringPool.toString(fTempAttDecl.name.localpart) + "'\n"
                                   + "attType : "+fTempAttDecl.type + "\n"
                                   + "attDefaultType : "+fTempAttDecl.defaultType + "\n"
                                   + "attDefaultValue : '"+fTempAttDecl.defaultValue + "'\n"
                                   + attrList.getLength() +"\n"
                                   );
            }
            /***/

            int attPrefix = fTempAttDecl.name.prefix;
            int attName = fTempAttDecl.name.localpart;
            int attType = attributeTypeName(fTempAttDecl);
            int attDefType =fTempAttDecl.defaultType;
            int attValue = -1 ;
            if (fTempAttDecl.defaultValue != null ) {
                attValue = fStringPool.addSymbol(fTempAttDecl.defaultValue);
            }

            boolean specified = false;
            boolean required = attDefType == XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;

            if (firstCheck != -1) {
                boolean cdata = attType == fCDATASymbol;
                if (!cdata || required || attValue != -1) {
                    int i = attrList.getFirstAttr(firstCheck);
                    while (i != -1 && (lastCheck == -1 || i <= lastCheck)) {

                        if ( (fGrammarIsDTDGrammar && (attrList.getAttrName(i) == fTempAttDecl.name.rawname)) ||
                             fStringPool.equalNames(attrList.getAttrLocalpart(i), attName)
                                && fStringPool.equalNames(attrList.getAttrURI(i), fTempAttDecl.name.uri) ) ) {

                            if (validationEnabled && attDefType == XMLAttributeDecl.DEFAULT_TYPE_FIXED) {
                                int alistValue = attrList.getAttValue(i);
                                if (alistValue != attValue &&
                                    !fStringPool.toString(alistValue).equals(fStringPool.toString(attValue))) {
                                    Object[] args = { fStringPool.toString(elementNameIndex),
                                        fStringPool.toString(attName),
                                        fStringPool.toString(alistValue),
                                        fStringPool.toString(attValue)};
                                    fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                               XMLMessages.XML_DOMAIN,
                                                               XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
                                                               XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
                                                               args,
                                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                                }
                            }
                            specified = true;
                            break;
                        }
                        i = attrList.getNextAttr(i);
                    }
                }
            }

            if (!specified) {
                if (required) {
                    if (validationEnabled) {
                        Object[] args = { fStringPool.toString(elementNameIndex),
                            fStringPool.toString(attName)};
                        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                   XMLMessages.XML_DOMAIN,
                                                   XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
                                                   XMLMessages.VC_REQUIRED_ATTRIBUTE,
                                                   args,
                                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                    }
                } else if (attValue != -1) {
                    if (validationEnabled && standalone )
                        if ( fGrammarIsDTDGrammar
                             && ((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attlistIndex) ) {

                            Object[] args = { fStringPool.toString(elementNameIndex),
                                fStringPool.toString(attName)};
                            fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                       XMLMessages.XML_DOMAIN,
                                                       XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
                                                       XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                       args,
                                                       XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                        }
                    if (attType == fIDREFSymbol) {
                        this.fValIDRef.validate( fStringPool.toString(attValue), this.fStoreIDRef );
                    } else if (attType == fIDREFSSymbol) {
                        this.fValIDRefs.validate( fStringPool.toString(attValue), this.fStoreIDRef );
                    }
                    if (attrIndex == -1) {
                        attrIndex = attrList.startAttrList();
                    }
                    // REVISIT: Validation. What should the prefix be?
                    fTempQName.setValues(attPrefix, attName, attName, fTempAttDecl.name.uri);
                    int newAttr = attrList.addAttr(fTempQName,
                                                   attValue, attType,
                                                   false, false);
                    if (lastCheck == -1) {
                        lastCheck = newAttr;
                    }
                }
            }
            attlistIndex = fGrammar.getNextAttributeDeclIndex(attlistIndex);
        }
        return attrIndex;

    } // addDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int

    /** addDTDDefaultAttributes. */
    private int addDTDDefaultAttributes(QName element, XMLAttrList attrList, int attrIndex, boolean validationEnabled, boolean standalone) throws Exception {


        //
        // Check after all specified attrs are scanned
        // (1) report error for REQUIRED attrs that are missing (V_TAGc)
        // (2) check that FIXED attrs have matching value (V_TAGd)
        // (3) add default attrs (FIXED and NOT_FIXED)
        //

        int elementIndex = fGrammar.getElementDeclIndex(element, -1);

        if (elementIndex == -1) {
            return attrIndex;
        }

        fGrammar.getElementDecl(elementIndex,fTempElementDecl);


        int elementNameIndex = fTempElementDecl.name.rawname;
        int attlistIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
        int firstCheck = attrIndex;
        int lastCheck = -1;
        while (attlistIndex != -1) {

            fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);

            // TO DO: For ericye Debug only
            /***
            if (fTempAttDecl != null) {
                XMLElementDecl element = new XMLElementDecl();
                fGrammar.getElementDecl(elementIndex, element);
                System.out.println("element: "+fStringPool.toString(element.name.localpart));
                System.out.println("attlistIndex " + attlistIndex + "\n"+
                    "attName : '"+fStringPool.toString(fTempAttDecl.name.localpart) + "'\n"
                                   + "attType : "+fTempAttDecl.type + "\n"
                                   + "attDefaultType : "+fTempAttDecl.defaultType + "\n"
                                   + "attDefaultValue : '"+fTempAttDecl.defaultValue + "'\n"
                                   + attrList.getLength() +"\n"
                                   );
            }
            /***/

            int attPrefix = fTempAttDecl.name.prefix;
            int attName = fTempAttDecl.name.rawname;
            int attLocalpart = fTempAttDecl.name.localpart;
            int attType = attributeTypeName(fTempAttDecl);
            int attDefType =fTempAttDecl.defaultType;
            int attValue = -1 ;
            if (fTempAttDecl.defaultValue != null ) {
                attValue = fStringPool.addSymbol(fTempAttDecl.defaultValue);
            }
            boolean specified = false;
            boolean required = attDefType == XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;


            /****
            if (fValidating && fGrammar != null && fGrammarIsDTDGrammar && attValue != -1) {
                normalizeAttValue(null, fTempAttDecl.name,
                                  attValue,attType,fTempAttDecl.list,
                                  fTempAttDecl.enumeration);
            }
            /****/

            if (firstCheck != -1) {
                boolean cdata = attType == fCDATASymbol;
                if (!cdata || required || attValue != -1) {
                    int i = attrList.getFirstAttr(firstCheck);
                    while (i != -1 && (lastCheck == -1 || i <= lastCheck)) {

                        if ( attrList.getAttrName(i) == fTempAttDecl.name.rawname ) {

                            if (validationEnabled && attDefType == XMLAttributeDecl.DEFAULT_TYPE_FIXED) {
                                int alistValue = attrList.getAttValue(i);
                                if (alistValue != attValue &&
                                    !fStringPool.toString(alistValue).equals(fStringPool.toString(attValue))) {
                                    Object[] args = { fStringPool.toString(elementNameIndex),
                                        fStringPool.toString(attName),
                                        fStringPool.toString(alistValue),
                                        fStringPool.toString(attValue)};
                                    fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                               XMLMessages.XML_DOMAIN,
                                                               XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
                                                               XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
                                                               args,
                                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                                }
                            }
                            specified = true;
                            break;
                        }
                        i = attrList.getNextAttr(i);
                    }
                }
            }

            if (!specified) {
                if (required) {
                    if (validationEnabled) {
                        Object[] args = { fStringPool.toString(elementNameIndex),
                            fStringPool.toString(attName)};
                        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                   XMLMessages.XML_DOMAIN,
                                                   XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
                                                   XMLMessages.VC_REQUIRED_ATTRIBUTE,
                                                   args,
                                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                    }
                } else if (attValue != -1) {
                    if (validationEnabled && standalone )
                        if ( fGrammarIsDTDGrammar
                             && ((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attlistIndex) ) {

                            Object[] args = { fStringPool.toString(elementNameIndex),
                                fStringPool.toString(attName)};
                            fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                       XMLMessages.XML_DOMAIN,
                                                       XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
                                                       XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                       args,
                                                       XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                        }
                    if (attType == fIDREFSymbol) {
                        this.fValIDRef.validate( fStringPool.toString(attValue), this.fStoreIDRef );
                    } else if (attType == fIDREFSSymbol) {
                        this.fValIDRefs.validate( fStringPool.toString(attValue), this.fStoreIDRef );
                    }
                    if (attrIndex == -1) {
                        attrIndex = attrList.startAttrList();
                    }

                    fTempQName.setValues(attPrefix, attLocalpart, attName, fTempAttDecl.name.uri);
                    int newAttr = attrList.addAttr(fTempQName,
                                                   attValue, attType,
                                                   false, false);
                    if (lastCheck == -1) {
                        lastCheck = newAttr;
                    }
                }
            }
            attlistIndex = fGrammar.getNextAttributeDeclIndex(attlistIndex);
        }
        return attrIndex;

    } // addDTDDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int

    // content models

    /** Queries the content model for the specified element index. */
    private XMLContentModel getElementContentModel(int elementIndex) throws CMException {
        XMLContentModel contentModel = null;
        if ( elementIndex > -1) {
            if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
                contentModel = fGrammar.getElementContentModel(elementIndex);
            }
        }
        //return fGrammar.getElementContentModel(elementIndex);
        return contentModel;
    }



    // query attribute information

    /** Returns an attribute definition for an element type. */
    // this is only used by DTD validation.
    private int getAttDef(QName element, QName attribute) {
        if (fGrammar != null) {
            int scope = fCurrentScope;
            if (element.uri > -1) {
                scope = TOP_LEVEL_SCOPE;
            }
            int elementIndex = fGrammar.getElementDeclIndex(element,scope);
            if (elementIndex == -1) {
                return -1;
            }
            int attDefIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
            while (attDefIndex != -1) {
                fGrammar.getAttributeDecl(attDefIndex, fTempAttributeDecl);
                if (fTempAttributeDecl.name.localpart == attribute.localpart &&
                    fTempAttributeDecl.name.uri == attribute.uri ) {
                    return attDefIndex;
                }
                attDefIndex = fGrammar.getNextAttributeDeclIndex(attDefIndex);
            }
        }
        return -1;

    } // getAttDef(QName,QName)

    /** Returns an attribute definition for an element type. */
    private int getAttDefByElementIndex(int elementIndex, QName attribute) {
        if (fGrammar != null && elementIndex > -1) {
            if (elementIndex == -1) {
                return -1;
            }
            int attDefIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
            while (attDefIndex != -1) {
                fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl);

                if (fGrammarIsDTDGrammar) {
                    if (fTempAttDecl.name.rawname == attribute.rawname )
                        return attDefIndex;
                } else
                    if (fTempAttDecl.name.localpart == attribute.localpart &&
                        fTempAttDecl.name.uri == attribute.uri ) {
                    return attDefIndex;
                }

                if (fGrammarIsSchemaGrammar) {
                    if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY) {
                        return attDefIndex;
                    } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
                        if (attribute.uri == -1) {
                            return attDefIndex;
                        }
                    } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
                        if (attribute.uri != fTempAttDecl.name.uri) {
                            return attDefIndex;
                        }
                    } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LIST) {
                        if (fStringPool.stringInList(fTempAttDecl.enumeration, attribute.uri)) {
                            return attDefIndex;
                        }
                    }
                }

                attDefIndex = fGrammar.getNextAttributeDeclIndex(attDefIndex);
            }
        }
        return -1;

    } // getAttDef(QName,QName)

    // validation

    /** Root element specified. */
    private void rootElementSpecified(QName rootElement) throws Exception {

        // this is what it used to be
        //if  (fDynamicValidation && !fSeenDoctypeDecl) {
        //fValidating = false;
        //}


        if ( fLoadDTDGrammar )
            // initialize the grammar to be the default one,
            // it definitely should be a DTD Grammar at this case;
            if (fGrammar == null) {

                fGrammar = fGrammarResolver.getGrammar("");

                //TO DO, for ericye debug only
                if (fGrammar == null && DEBUG_SCHEMA_VALIDATION) {
                    System.out.println("Oops! no grammar is found for validation");
                }

                if (fDynamicValidation && fGrammar==null) {
                    fValidating = false;
                }

                if (fGrammar != null) {
                    if (fGrammar instanceof DTDGrammar) {
                        fGrammarIsDTDGrammar = true;
                        fGrammarIsSchemaGrammar = false;
                    } else if ( fGrammar instanceof SchemaGrammar ) {
                        fGrammarIsSchemaGrammar = true;
                        fGrammarIsDTDGrammar = false;
                    }

                    fGrammarNameSpaceIndex = fEmptyURI;
                }
            }

        if (fValidating) {
            if ( fGrammarIsDTDGrammar &&
                 ((DTDGrammar) fGrammar).getRootElementQName(fRootElement) ) {

                String root1 = fStringPool.toString(fRootElement.rawname);
                String root2 = fStringPool.toString(rootElement.rawname);
                if (!root1.equals(root2)) {
                    reportRecoverableXMLError(XMLMessages.MSG_ROOT_ELEMENT_TYPE,
                                              XMLMessages.VC_ROOT_ELEMENT_TYPE,
                                              fRootElement.rawname,
                                              rootElement.rawname);
                }
            }
        }

        if (fNamespacesEnabled) {
            if (fNamespacesScope == null) {
                fNamespacesScope = new NamespacesScope(this);
                fNamespacesPrefix = fStringPool.addSymbol("xmlns");
                fNamespacesScope.setNamespaceForPrefix(fNamespacesPrefix, -1);
                int xmlSymbol = fStringPool.addSymbol("xml");
                int xmlNamespace = fStringPool.addSymbol("http://www.w3.org/XML/1998/namespace");
                fNamespacesScope.setNamespaceForPrefix(xmlSymbol, xmlNamespace);
            }
        }

    } // rootElementSpecified(QName)

    /** Switchs to correct validating symbol tables when Schema changes.*/

    private boolean switchGrammar(int newGrammarNameSpaceIndex) throws Exception {
        Grammar tempGrammar = fGrammarResolver.getGrammar(fStringPool.toString(newGrammarNameSpaceIndex));
        if (tempGrammar == null) {
            // This is a case where namespaces is on with a DTD grammar.
            tempGrammar = fGrammarResolver.getGrammar("");
        }
        if (tempGrammar == null) {
            return false;
        } else {
            fGrammar = tempGrammar;
            if (fGrammar instanceof DTDGrammar) {
                fGrammarIsDTDGrammar = true;
                fGrammarIsSchemaGrammar = false;
            } else if ( fGrammar instanceof SchemaGrammar ) {
                fGrammarIsSchemaGrammar = true;
                fGrammarIsDTDGrammar = false;
            }

            return true;
        }
    }

    /** Binds namespaces to the element and attributes. */
    private void bindNamespacesToElementAndAttributes(QName element,
                                                      XMLAttrList attrList)
    throws Exception {

        fNamespacesScope.increaseDepth();

        //Vector schemaCandidateURIs = null;
        Hashtable locationUriPairs = null;

        if (fAttrListHandle != -1) {
            int index = attrList.getFirstAttr(fAttrListHandle);
            while (index != -1) {
                int attName = attrList.getAttrName(index);
                int attPrefix = attrList.getAttrPrefix(index);
                if (fStringPool.equalNames(attName, fXMLLang)) {
                    /***
                    // NOTE: This check is done in the validateElementsAndAttributes
                    //       method.
                    fDocumentScanner.checkXMLLangAttributeValue(attrList.getAttValue(index));
                    /***/
                } else if (fStringPool.equalNames(attName, fNamespacesPrefix)) {
                    int uri = fStringPool.addSymbol(attrList.getAttValue(index));
                    fNamespacesScope.setNamespaceForPrefix(StringPool.EMPTY_STRING, uri);
                } else {
                    if (attPrefix == fNamespacesPrefix) {
                        int nsPrefix = attrList.getAttrLocalpart(index);
                        int uri = fStringPool.addSymbol(attrList.getAttValue(index));
                        fNamespacesScope.setNamespaceForPrefix(nsPrefix, uri);

                        if (fValidating && fSchemaValidation) {
                            boolean seeXsi = false;
                            String attrValue = fStringPool.toString(attrList.getAttValue(index));

                            if (attrValue.equals(SchemaSymbols.URI_XSI)) {
                                fXsiPrefix = nsPrefix;
                                seeXsi = true;
                            }

                            if (!seeXsi) {
                                /***
                                if (schemaCandidateURIs == null) {
                                    schemaCandidateURIs = new Vector();
                                }
                                schemaCandidateURIs.addElement( fStringPool.toString(uri) );
                                /***/
                            }
                        }
                    }
                }
                index = attrList.getNextAttr(index);
            }
            // if validating, walk through the list again to deal with "xsi:...."
            if (fValidating && fSchemaValidation) {
                fXsiTypeAttValue = -1;
                index = attrList.getFirstAttr(fAttrListHandle);
                while (index != -1) {

                    int attName = attrList.getAttrName(index);
                    int attPrefix = attrList.getAttrPrefix(index);

                    if (fStringPool.equalNames(attName, fNamespacesPrefix)) {
                        // REVISIT
                    } else {
                        if ( DEBUG_SCHEMA_VALIDATION ) {
                            System.out.println("deal with XSI");
                            System.out.println("before find XSI: "+fStringPool.toString(attPrefix)
                                               +","+fStringPool.toString(fXsiPrefix) );
                        }
                        if ( fXsiPrefix != -1 && attPrefix == fXsiPrefix ) {

                            if (DEBUG_SCHEMA_VALIDATION) {
                                System.out.println("find XSI: "+fStringPool.toString(attPrefix)
                                                   +","+fStringPool.toString(attName) );
                            }


                            int localpart = attrList.getAttrLocalpart(index);
                            if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_SCHEMALOCACTION)) {
                                if (locationUriPairs == null) {
                                    locationUriPairs = new Hashtable();
                                }
                                parseSchemaLocation(fStringPool.toString(attrList.getAttValue(index)), locationUriPairs);
                            } else if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_NONAMESPACESCHEMALOCACTION)) {
                                if (locationUriPairs == null) {
                                    locationUriPairs = new Hashtable();
                                }
                                locationUriPairs.put(fStringPool.toString(attrList.getAttValue(index)), "");
                                if (fNamespacesScope != null) {
                                    //bind prefix "" to URI "" in this case
                                    fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
                                                                            fStringPool.addSymbol(""));
                                }
                            } else if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_TYPE)) {
                                fXsiTypeAttValue = attrList.getAttValue(index);
                            }
                            // REVISIT: should we break here?
                            //break;
                        }
                    }
                    index = attrList.getNextAttr(index);
                }

                // try to resolve all the grammars here
                if (locationUriPairs != null) {
                    Enumeration locations = locationUriPairs.keys();

                    while (locations.hasMoreElements()) {
                        String loc = (String) locations.nextElement();
                        String uri = (String) locationUriPairs.get(loc);
                        resolveSchemaGrammar( loc, uri);
                        //schemaCandidateURIs.removeElement(uri);
                    }
                }

                //TO DO: This should be a feature that can be turned on or off
                /*****
                for (int i=0; i< schemaCandidateURIs.size(); i++) {
               
                    String uri = (String) schemaCandidateURIs.elementAt(i);
                    resolveSchemaGrammar(uri);
                }
                /*****/

            }

        }

        // bind element to URI
        int prefix = element.prefix != -1 ? element.prefix : 0;
        int uri    = fNamespacesScope.getNamespaceForPrefix(prefix);
        if (element.prefix != -1 || uri != -1) {
            element.uri = uri;
            if (element.uri == -1) {
                Object[] args = { fStringPool.toString(element.prefix)};
                fErrorReporter.reportError(fErrorReporter.getLocator(),
                                           XMLMessages.XMLNS_DOMAIN,
                                           XMLMessages.MSG_PREFIX_DECLARED,
                                           XMLMessages.NC_PREFIX_DECLARED,
                                           args,
                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
            }
        }


        if (fAttrListHandle != -1) {
            int index = attrList.getFirstAttr(fAttrListHandle);
            while (index != -1) {
                int attName = attrList.getAttrName(index);
                if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
                    int attPrefix = attrList.getAttrPrefix(index);
                    if (attPrefix != fNamespacesPrefix) {
                        if (attPrefix != -1 ) {
                            int attrUri = fNamespacesScope.getNamespaceForPrefix(attPrefix);
                            if (attrUri == -1) {
                                Object[] args = { fStringPool.toString(attPrefix)};
                                fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                           XMLMessages.XMLNS_DOMAIN,
                                                           XMLMessages.MSG_PREFIX_DECLARED,
                                                           XMLMessages.NC_PREFIX_DECLARED,
                                                           args,
                                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                            }
                            attrList.setAttrURI(index, attrUri);
                        }
                    }
                }
                index = attrList.getNextAttr(index);
            }
        }

    } // bindNamespacesToElementAndAttributes(QName,XMLAttrList)

    void parseSchemaLocation(String schemaLocationStr, Hashtable locationUriPairs){
        if (locationUriPairs != null) {
            StringTokenizer tokenizer = new StringTokenizer(schemaLocationStr, " \n\t\r", false);
            int tokenTotal = tokenizer.countTokens();
            if (tokenTotal % 2 != 0 ) {
                // TO DO: report warning - malformed schemaLocation string
            } else {
                while (tokenizer.hasMoreTokens()) {
                    String uri = tokenizer.nextToken();
                    String location = tokenizer.nextToken();

                    locationUriPairs.put(location, uri);
                }
            }
        } else {
            // TO DO: should report internal error here
        }

    }// parseSchemaLocaltion(String, Hashtable)
    private void resolveSchemaGrammar( String loc, String uri) throws Exception {

        SchemaGrammar grammar = (SchemaGrammar) fGrammarResolver.getGrammar(uri);

        if (grammar == null) {
            DOMParser parser = new DOMParser();
            parser.setEntityResolver( new Resolver(fEntityHandler) );
            parser.setErrorHandlernew ErrorHandler() );

            try {
                parser.setFeature("http://xml.org/sax/features/validation", false);
                parser.setFeature("http://xml.org/sax/features/namespaces", true);
                parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
            } catch org.xml.sax.SAXNotRecognizedException e ) {
                e.printStackTrace();
            } catch ( org.xml.sax.SAXNotSupportedException e ) {
                e.printStackTrace();
            }

            // expand it before passing it to the parser
            InputSource source = null;
            EntityResolver currentER = parser.getEntityResolver();
            if (currentER != null) {
                source = currentER.resolveEntity("", loc);
            }
            if (source == null) {
                loc = fEntityHandler.expandSystemId(loc);
                source = new InputSource(loc);
            }
            try {
                parser.parse( source );
            } catch ( IOException e ) {
                e.printStackTrace();
            } catch ( SAXException e ) {
                //System.out.println("loc = "+loc);
                //e.printStackTrace();
                reportRecoverableXMLError( XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
                                           XMLMessages.SCHEMA_GENERIC_ERROR, e.getMessage() );
            }

            Document     document   = parser.getDocument(); //Our Grammar

            TraverseSchema tst = null;
            try {
                if (DEBUG_SCHEMA_VALIDATION) {
                    System.out.println("I am geting the Schema Document");
                }

                Element root   = document.getDocumentElement();// This is what we pass to TraverserSchema
                if (root == null) {
                    reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, "Can't get back Schema document's root element :" + loc);
                } else {
                    if (uri == null || !uri.equals(root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE)) ) {
                        reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, "Schema in " + loc + " has a different target namespace " +
                                                  "from the one specified in the instance document :" + uri);
                    }
                    grammar = new SchemaGrammar();
                    grammar.setGrammarDocument(document);
                    tst = new TraverseSchema( root, fStringPool, (SchemaGrammar)grammar, fGrammarResolver, fErrorReporter, source.getSystemId());
                    fGrammarResolver.putGrammar(document.getDocumentElement().getAttribute("targetNamespace"), grammar);
                }
            } catch (Exception e) {
                e.printStackTrace(System.err);
            }
        }

    }

    private void resolveSchemaGrammar(String uri) throws Exception{

        resolveSchemaGrammar(uri, uri);

    }

    static class Resolver implements EntityResolver {

        //
        // Constants
        //

        private static final String SYSTEM[] = {
            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/structures.dtd",
            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd",
            "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/versionInfo.ent",
        };
        private static final String PATH[] = {
            "structures.dtd",
            "datatypes.dtd",
            "versionInfo.ent",
        };

        //
        // Data
        //

        private DefaultEntityHandler fEntityHandler;

        //
        // Constructors
        //

        public Resolver(DefaultEntityHandler handler) {
            fEntityHandler = handler;
        }

        //
        // EntityResolver methods
        //

        public InputSource resolveEntity(String publicId, String systemId)
        throws IOException, SAXException {

            // looking for the schema DTDs?
            for (int i = 0; i < SYSTEM.length; i++) {
                if (systemId.equals(SYSTEM[i])) {
                    InputSource source = new InputSource(getClass().getResourceAsStream(PATH[i]));
                    source.setPublicId(publicId);
                    source.setSystemId(systemId);
                    return source;
                }
            }

            // first try to resolve using user's entity resolver
            EntityResolver resolver = fEntityHandler.getEntityResolver();
            if (resolver != null) {
                InputSource source = resolver.resolveEntity(publicId, systemId);
                if (source != null) {
                    return source;
                }
            }

            // use default resolution
            return new InputSource(fEntityHandler.expandSystemId(systemId));

        } // resolveEntity(String,String):InputSource

    } // class Resolver

    static class ErrorHandler implements org.xml.sax.ErrorHandler {

        /** Warning. */
        public void warning(SAXParseException ex) {
            System.err.println("[Warning] "+
                               getLocationString(ex)+": "+
                               ex.getMessage());
        }

        /** Error. */
        public void error(SAXParseException ex) {
            System.err.println("[Error] "+
                               getLocationString(ex)+": "+
                               ex.getMessage());
        }

        /** Fatal error. */
        public void fatalError(SAXParseException ex)  {
            System.err.println("[Fatal Error] "+
                               getLocationString(ex)+": "+
                               ex.getMessage());
            //throw ex;
        }

        //
        // Private methods
        //

        /** Returns a string of the location. */
        private String getLocationString(SAXParseException ex) {
            StringBuffer str = new StringBuffer();

            String systemId_ = ex.getSystemId();
            if (systemId_ != null) {
                int index = systemId_.lastIndexOf('/');
                if (index != -1)
                    systemId_ = systemId_.substring(index + 1);
                str.append(systemId_);
            }
            str.append(':');
            str.append(ex.getLineNumber());
            str.append(':');
            str.append(ex.getColumnNumber());

            return str.toString();

        } // getLocationString(SAXParseException):String
    }

    private int attributeTypeName(XMLAttributeDecl attrDecl) {
        switch (attrDecl.type) {
        case XMLAttributeDecl.TYPE_ENTITY: {
                return attrDecl.list ? fENTITIESSymbol : fENTITYSymbol;
            }
        case XMLAttributeDecl.TYPE_ENUMERATION: {
                String enumeration = fStringPool.stringListAsString(attrDecl.enumeration);
                return fStringPool.addString(enumeration);
            }
        case XMLAttributeDecl.TYPE_ID: {
                return fIDSymbol;
            }
        case XMLAttributeDecl.TYPE_IDREF: {
                return attrDecl.list ? fIDREFSSymbol : fIDREFSymbol;
            }
        case XMLAttributeDecl.TYPE_NMTOKEN: {
                return attrDecl.list ? fNMTOKENSSymbol : fNMTOKENSSymbol;
            }
        case XMLAttributeDecl.TYPE_NOTATION: {
                return fNOTATIONSymbol;
            }
        }
        return fCDATASymbol;
    }

    /** Validates element and attributes. */
    private void validateElementAndAttributes(QName element,
                                              XMLAttrList attrList)
        throws Exception {

        if ((fElementDepth >= 0 && fValidationFlagStack[fElementDepth] != 0 )||
            (fGrammar == null && !fValidating && !fNamespacesEnabled) ) {
            fCurrentElementIndex = -1;
            fCurrentContentSpecType = -1;
            fInElementContent = false;
            if (fAttrListHandle != -1) {
                fAttrList.endAttrList();
                int index = fAttrList.getFirstAttr(fAttrListHandle);
                while (index != -1) {
                    if (fStringPool.equalNames(fAttrList.getAttrName(index), fXMLLang)) {
                        fDocumentScanner.checkXMLLangAttributeValue(fAttrList.getAttValue(index));
                        break;
                    }
                    index = fAttrList.getNextAttr(index);
                }
            }
            return;
        }

        int elementIndex = -1;
        int contentSpecType = -1;

        boolean skipThisOne = false;
        boolean laxThisOne = false;

        if ( fGrammarIsSchemaGrammar && fContentLeafStack[fElementDepth] != null ) {
            ContentLeafNameTypeVector cv = fContentLeafStack[fElementDepth];

            QName[] fElemMap = cv.leafNames;
            for (int i=0; i<cv.leafCount; i++) {
                int type = cv.leafTypes[i;
                //System.out.println("******* see a ANY_OTHER_SKIP, "+type+","+element+","+fElemMap[i]+"\n*******");

                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
                    if (fElemMap[i].uri==element.uri
                        && fElemMap[i].localpart == element.localpart)
                        break;
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
                    int uri = fElemMap[i].uri;
                    if (uri == -1 || uri == element.uri) {
                        break;
                    }
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
                    if (element.uri == -1) {
                        break;
                    }
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
                    if (fElemMap[i].uri != element.uri) {
                        break;
                    }
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_SKIP) {
                    int uri = fElemMap[i].uri;
                    if (uri == -1 || uri == element.uri) {
                        skipThisOne = true;
                        break;
                    }
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_SKIP) {
                    if (element.uri == -1) {
                        skipThisOne = true;
                        break;
                    }
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP) {
                    if (fElemMap[i].uri != element.uri) {
                        skipThisOne = true;
                        break;
                    }
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LAX) {
                    int uri = fElemMap[i].uri;
                    if (uri == -1 || uri == element.uri) {
                        laxThisOne = true;
                        break;
                    }
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_LAX) {
                    if (element.uri == -1) {
                        laxThisOne = true;
                        break;
                    }
                } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX) {
                    if (fElemMap[i].uri != element.uri) {
                        laxThisOne = true;
                        break;
                    }
                }

            }

        }

        if (skipThisOne) {
            fNeedValidationOff = true;
        } else {

            //REVISIT: is this the right place to check on if the Schema has changed?

            if ( fNamespacesEnabled && fValidating && element.uri != fGrammarNameSpaceIndex && element.uri != -) {
                fGrammarNameSpaceIndex = element.uri;

                boolean success = switchGrammar(fGrammarNameSpaceIndex);

                if (!success && !laxThisOne) {
                    reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR,
                                              "Grammar with uri : " + fStringPool.toString(fGrammarNameSpaceIndex)
                                              + " , can not found");
                }
            }


            if ( fGrammar != null ) {
                if (DEBUG_SCHEMA_VALIDATION) {
                    System.out.println("*******Lookup element: uri: " + fStringPool.toString(element.uri)+
                                       "localpart: '" + fStringPool.toString(element.localpart)
                                       +"' and scope : " + fCurrentScope+"\n");
                }

                elementIndex = fGrammar.getElementDeclIndex(element,fCurrentScope);

                if (elementIndex == -1 ) {
                    elementIndex = fGrammar.getElementDeclIndex(element, TOP_LEVEL_SCOPE);
                }

                if (elementIndex == -1) {
                    // if validating based on a Schema, try to resolve the element again by look it up in its ancestor types
                    if (fGrammarIsSchemaGrammar && fCurrentElementIndex != -1) {
                        TraverseSchema.ComplexTypeInfo baseTypeInfo = null;
                        baseTypeInfo = ((SchemaGrammar)fGrammar).getElementComplexTypeInfo(fCurrentElementIndex);
                        //TO DO:
                        //      should check if baseTypeInfo is from the same Schema.
                        while (baseTypeInfo != null) {
                            elementIndex = fGrammar.getElementDeclIndex(element, baseTypeInfo.scopeDefined);
                            if (elementIndex > -1 ) {
                                break;
                            }
                            baseTypeInfo = baseTypeInfo.baseComplexTypeInfo;
                        }
                    }
                    //if still can't resolve it, try TOP_LEVEL_SCOPE AGAIN
                    /****
                    if ( element.uri == -1 && elementIndex == -1
                    && fNamespacesScope != null
                    && fNamespacesScope.getNamespaceForPrefix(StringPool.EMPTY_STRING) != -1 ) {
                    elementIndex = fGrammar.getElementDeclIndex(element.localpart, TOP_LEVEL_SCOPE);
                    // REVISIT:
                    // this is a hack to handle the situation where namespace prefix "" is bound to nothing, and there
                    // is a "noNamespaceSchemaLocation" specified, and element
                    element.uri = StringPool.EMPTY_STRING;
                    }
                    /****/

                    /****/
                    if (elementIndex == -1) {
                        if (laxThisOne) {
                            fNeedValidationOff = true;
                        } else
                            if (DEBUG_SCHEMA_VALIDATION)
                            System.out.println("!!! can not find elementDecl in the grammar, " +
                                               " the element localpart: " + element.localpart +
                                               "["+fStringPool.toString(element.localpart) +"]" +
                                               " the element uri: " + element.uri +
                                               "["+fStringPool.toString(element.uri) +"]" +
                                               " and the current enclosing scope: " + fCurrentScope );
                    }
                    /****/
                }

                if (DEBUG_SCHEMA_VALIDATION) {
                    fGrammar.getElementDecl(elementIndex, fTempElementDecl);
                    System.out.println("elementIndex: " + elementIndex+" \n and itsName : '"
                                       + fStringPool.toString(fTempElementDecl.name.localpart)
                                       +"' \n its ContentType:" + fTempElementDecl.type
                                       +"\n its ContentSpecIndex : " + fTempElementDecl.contentSpecIndex +"\n"+
                                       " and the current enclosing scope: " + fCurrentScope);
                }
            }

            contentSpecType =  getContentSpecType(elementIndex);

            if (fGrammarIsSchemaGrammar && elementIndex != -1) {

                // handle "xsi:type" right here
                if (fXsiTypeAttValue > -1) {
                    String xsiType = fStringPool.toString(fXsiTypeAttValue);
                    int colonP = xsiType.indexOf(":");
                    String prefix = "";
                    String localpart = xsiType;
                    if (colonP > -1) {
                        prefix = xsiType.substring(0,colonP);
                        localpart = xsiType.substring(colonP+1);
                    }

                    String uri = "";
                    int uriIndex = -1;
                    if (fNamespacesScope != null) {
                        uriIndex = fNamespacesScope.getNamespaceForPrefix(fStringPool.addSymbol(prefix));
                        if (uriIndex > -1) {
                            uri = fStringPool.toString(uriIndex);
                            if (uriIndex != fGrammarNameSpaceIndex) {
                                fGrammarNameSpaceIndex = fCurrentSchemaURI = uriIndex;
                                boolean success = switchGrammar(fCurrentSchemaURI);
                                if (!success && !fNeedValidationOff) {
                                    reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
                                                              XMLMessages.SCHEMA_GENERIC_ERROR,
                                                              "Grammar with uri : "
                                                              + fStringPool.toString(fCurrentSchemaURI)
                                                              + " , can not found");
                                }
                            }
                        }
                    }


                    Hashtable complexRegistry = ((SchemaGrammar)fGrammar).getComplexTypeRegistry();
                    DatatypeValidatorFactoryImpl dataTypeReg = ((SchemaGrammar)fGrammar).getDatatypeRegistry();
                    if (complexRegistry==null || dataTypeReg == null) {
                        reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
                                                  XMLMessages.SCHEMA_GENERIC_ERROR,
                                                  fErrorReporter.getLocator().getSystemId()
                                                  +" line"+fErrorReporter.getLocator().getLineNumber()
                                                  +", canot resolve xsi:type = " + xsiType+"  ---2");
                    } else {
                        TraverseSchema.ComplexTypeInfo typeInfo =
                        (TraverseSchema.ComplexTypeInfo) complexRegistry.get(uri+","+localpart);
                        //TO DO:
                        //      here need to check if this substitution is legal based on the current active grammar,
                        //      this should be easy, cause we already saved final, block and base type information in
                        //      the SchemaGrammar.

                        if (typeInfo==null) {
                            if (uri.length() == 0 || uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) ) {
                                fXsiTypeValidator = dataTypeReg.getDatatypeValidator(localpart);
                            } else
                                fXsiTypeValidator = dataTypeReg.getDatatypeValidator(uri+","+localpart);
                            if ( fXsiTypeValidator == null )
                                reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
                                                          XMLMessages.SCHEMA_GENERIC_ERROR,
                                                          "unresolved type : "+uri+","+localpart
                                                          +" found  in xsi:type handling");
                        } else
                            elementIndex = typeInfo.templateElementIndex;
                    }

                    fXsiTypeAttValue = -1;
                }

                //Change the current scope to be the one defined by this element.
                fCurrentScope = ((SchemaGrammar) fGrammar).getElementDefinedScope(elementIndex);

                //       here need to check if we need to switch Grammar by asking SchemaGrammar whether
                //       this element actually is of a type in another Schema.
                String anotherSchemaURI = ((SchemaGrammar)fGrammar).getElementFromAnotherSchemaURI(elementIndex);
                if (anotherSchemaURI != null) {
                    //before switch Grammar, set the elementIndex to be the template elementIndex of its type
                    if (contentSpecType != -1
                        && contentSpecType != XMLElementDecl.TYPE_SIMPLE
                        && contentSpecType != XMLElementDecl.TYPE_EMPTY ) {
                        TraverseSchema.ComplexTypeInfo typeInfo = ((SchemaGrammar) fGrammar).getElementComplexTypeInfo(elementIndex);
                        if (typeInfo != null) {
                            elementIndex = typeInfo.templateElementIndex;
                        }

                    }

                    // now switch the grammar
                    fGrammarNameSpaceIndex = fCurrentSchemaURI = fStringPool.addSymbol(anotherSchemaURI);
                    boolean success = switchGrammar(fCurrentSchemaURI);
                    if (!success && !fNeedValidationOff) {
                        reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
                                                  XMLMessages.SCHEMA_GENERIC_ERROR,
                                                  "Grammar with uri : "
                                                  + fStringPool.toString(fCurrentSchemaURI)
                                                  + " , can not found");
                    }
                }

            }

            if (contentSpecType == -1 && fValidating && !fNeedValidationOff ) {
                reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
                                          XMLMessages.VC_ELEMENT_VALID,
                                          element.rawname);
            }
            if (fGrammar != null && fGrammarIsSchemaGrammar && elementIndex != -1) {
                fAttrListHandle = addDefaultAttributes(elementIndex, attrList, fAttrListHandle, fValidating, fStandaloneReader != -1);
            }
            if (fAttrListHandle != -1) {
                fAttrList.endAttrList();
            }

            if (DEBUG_PRINT_ATTRIBUTES) {
                String elementStr = fStringPool.toString(element.rawname);
                System.out.print("startElement: <" + elementStr);
                if (fAttrListHandle != -1) {
                    int index = attrList.getFirstAttr(fAttrListHandle);
                    while (index != -1) {
                        System.out.print(" " + fStringPool.toString(attrList.getAttrName(index)) + "=\"" +
                                         fStringPool.toString(attrList.getAttValue(index)) + "\"");
                        index = attrList.getNextAttr(index);
                    }
                }
                System.out.println(">");
            }
            // REVISIT: Validation. Do we need to recheck for the xml:lang
            //          attribute? It was already checked above -- perhaps
            //          this is to check values that are defaulted in? If
            //          so, this check could move to the attribute decl
            //          callback so we can check the default value before
            //          it is used.
            if (fAttrListHandle != -1 && !fNeedValidationOff ) {
                int index = fAttrList.getFirstAttr(fAttrListHandle);
                while (index != -1) {
                    int attrNameIndex = attrList.getAttrName(index);

                    if (fStringPool.equalNames(attrNameIndex, fXMLLang)) {
                        fDocumentScanner.checkXMLLangAttributeValue(attrList.getAttValue(index));
                        // break;
                    }
                    // here, we validate every "user-defined" attributes
                    int _xmlns = fStringPool.addSymbol("xmlns");

                    if (attrNameIndex != _xmlns && attrList.getAttrPrefix(index) != _xmlns)
                        if (fGrammar != null) {
                            fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
                            fTempQName.setValues(attrList.getAttrPrefix(index),
                                                 attrList.getAttrLocalpart(index),
                                                 attrList.getAttrName(index),
                                                 attrList.getAttrURI(index) );
                            int attDefIndex = getAttDefByElementIndex(elementIndex, fTempQName);

                            if (fTempQName.uri != fXsiURI)
                                if (attDefIndex == -1 ) {
                                    if (fValidating) {
                                        // REVISIT - cache the elem/attr tuple so that we only give
                                        //  this error once for each unique occurrence
                                        Object[] args = { fStringPool.toString(element.rawname),
                                            fStringPool.toString(attrList.getAttrName(index))};

                                        /*****/
                                        fErrorReporter.reportError(fAttrNameLocator,
                                                                   XMLMessages.XML_DOMAIN,
                                                                   XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
                                                                   XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
                                                                   args,
                                                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);  
                                        /******/
                                    }
                                } else {

                                    fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl);

                                    int attributeType = attributeTypeName(fTempAttDecl);
                                    attrList.setAttType(index, attributeType);

                                    if (fValidating) {

                                        if (fGrammarIsDTDGrammar &&
                                            (fTempAttDecl.type == XMLAttributeDecl.TYPE_ENTITY ||
                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_ENUMERATION ||
                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_ID ||
                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_IDREF ||
                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_NMTOKEN ||
                                             fTempAttDecl.type == XMLAttributeDecl.TYPE_NOTATION)
                                           ) {
                                            validateDTDattribute(element, attrList.getAttValue(index), fTempAttDecl);
                                        }

                                        // check to see if this attribute matched an attribute wildcard
                                        else if ( fGrammarIsSchemaGrammar &&
                                                  (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY
                                                   ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LIST
                                                   ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LOCAL
                                                   ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER) ) {

                                            if (fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_SKIP) {
                                                // attribute should just be bypassed,
                                            } else if ( fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_STRICT
                                                        || fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_LAX) {

                                                boolean reportError = false;
                                                boolean processContentStrict =
                                                fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_STRICT;

                                                if (fTempQName.uri == -1) {
                                                    if (processContentStrict) {
                                                        reportError = true;
                                                    }
                                                } else {
                                                    Grammar aGrammar =
                                                    fGrammarResolver.getGrammar(fStringPool.toString(fTempQName.uri));

                                                    if (aGrammar == null || !(aGrammar instanceof SchemaGrammar) ) {
                                                        if (processContentStrict) {
                                                            reportError = true;
                                                        }
                                                    } else {
                                                        SchemaGrammar sGrammar = (SchemaGrammar) aGrammar;
                                                        Hashtable attRegistry = sGrammar.getAttirubteDeclRegistry();
                                                        if (attRegistry == null) {
                                                            if (processContentStrict) {
                                                                reportError = true;
                                                            }
                                                        } else {
                                                            XMLAttributeDecl attDecl = (XMLAttributeDecl) attRegistry.get(fStringPool.toString(fTempQName.localpart));
                                                            if (attDecl == null) {
                                                                if (processContentStrict) {
                                                                    reportError = true;
                                                                }
                                                            } else {
                                                                DatatypeValidator attDV = attDecl.datatypeValidator;
                                                                if (attDV == null) {
                                                                    if (processContentStrict) {
                                                                        reportError = true;
                                                                    }
                                                                } else {
                                                                    try {
                                                                        String  unTrimValue = fStringPool.toString(attrList.getAttValue(index));
                                                                        String  value       = unTrimValue.trim();
                                                                        if (attDecl.type == XMLAttributeDecl.TYPE_ID ) {
                                                                            this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
                                                                        }
                                                                        if (attDecl.type == XMLAttributeDecl.TYPE_IDREF ) {
                                                                            attDV.validate(value, this.fStoreIDRef );
                                                                        } else
                                                                            attDV.validate(unTrimValue, null );
                                                                    } catch (InvalidDatatypeValueException idve) {
                                                                        fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                                                                   SchemaMessageProvider.SCHEMA_DOMAIN,
                                                                                                   SchemaMessageProvider.DatatypeError,
                                                                                                   SchemaMessageProvider.MSG_NONE,
                                                                                                   new Object [] { idve.getMessage()},
                                                                                                   XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                                if (reportError) {
                                                    Object[] args = { fStringPool.toString(element.rawname),
                                                        "ANY---"+fStringPool.toString(attrList.getAttrName(index))};

                                                    fErrorReporter.reportError(fAttrNameLocator,   
                                                                               XMLMessages.XML_DOMAIN,
                                                                               XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
                                                                               XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
                                                                               args,
                                                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);

                                                }
                                            }
                                        } else if (fTempAttDecl.datatypeValidator == null) {
                                            Object[] args = { fStringPool.toString(element.rawname),
                                                fStringPool.toString(attrList.getAttrName(index))};

                                            System.out.println("[Error] Datatypevalidator for attribute " + fStringPool.toString(attrList.getAttrName(index))
                                                               + " not found in element type " + fStringPool.toString(element.rawname));
                                            //REVISIT : is this the right message?
                                            /****/
                                            fErrorReporter.reportError(fAttrNameLocator,   
                                                                       XMLMessages.XML_DOMAIN,
                                                                       XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
                                                                       XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
                                                                       args,
                                                                       XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);  
                                            /****/
                                        } else {
                                            try {
                                                String  unTrimValue = fStringPool.toString(attrList.getAttValue(index));
                                                String  value       = unTrimValue.trim();
                                                if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ID ) {
                                                    this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
                                                } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_IDREF ) {
                                                    fTempAttDecl.datatypeValidator.validate(value, this.fStoreIDRef );
                                                } else {
                                                    fTempAttDecl.datatypeValidator.validate(unTrimValue, null );
                                                }

                                            } catch (InvalidDatatypeValueException idve) {
                                                fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                                           SchemaMessageProvider.SCHEMA_DOMAIN,
                                                                           SchemaMessageProvider.DatatypeError,
                                                                           SchemaMessageProvider.MSG_NONE,
                                                                           new Object [] { idve.getMessage()},
                                                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                                            }
                                        }
                                    } // end of if (fValidating)


                                } // end of if (attDefIndex == -1) else

                        }// end of if (fGrammar != null)
                    index = fAttrList.getNextAttr(index);
                }
            }
        }
        if (fAttrListHandle != -1) {
            int index = attrList.getFirstAttr(fAttrListHandle);
            while (index != -1) {
                int attName = attrList.getAttrName(index);
                if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
                    int attPrefix = attrList.getAttrPrefix(index);
                    if (attPrefix != fNamespacesPrefix) {
                        if (attPrefix != -1) {
                            int uri = fNamespacesScope.getNamespaceForPrefix(attPrefix);
                            if (uri == -1) {
                                Object[] args = { fStringPool.toString(attPrefix)};
                                fErrorReporter.reportError(fErrorReporter.getLocator(),
                                                           XMLMessages.XMLNS_DOMAIN,
                                                           XMLMessages.MSG_PREFIX_DECLARED,
                                                           XMLMessages.NC_PREFIX_DECLARED,
                                                           args,
                                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                            }
                            attrList.setAttrURI(index, uri);
                        }
                    }
                }
                index = attrList.getNextAttr(index);
            }
        }

        fCurrentElementIndex = elementIndex;
        fCurrentContentSpecType = contentSpecType;

        if (fValidating && contentSpecType == XMLElementDecl.TYPE_SIMPLE) {
            fBufferDatatype = true;
            fDatatypeBuffer.setLength(0);
        }

        fInElementContent = (contentSpecType == XMLElementDecl.TYPE_CHILDREN);

    } // validateElementAndAttributes(QName,XMLAttrList)


    //validate attributes in DTD fashion
    private void validateDTDattribute(QName element, int attValue,
                                      XMLAttributeDecl attributeDecl) throws Exception{
        AttributeValidator av = null;
        switch (attributeDecl.type) {
        case XMLAttributeDecl.TYPE_ENTITY:
            {
                boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
                String  unTrimValue      = fStringPool.toString(attValue);
                String  value            = unTrimValue.trim();
                //System.out.println("value = " + value );
                                                               //changes fTempAttDef
                if (fValidationEnabled) {
                    if (value != unTrimValue) {
                        if (invalidStandaloneAttDef(element, attributeDecl.name)) {
                            reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
                                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                      fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
                        }
                    }
                }

                try {
                    if ( isAlistAttribute ) {
                        fValENTITIES.validate( value, null );
                    } else {
                        fValENTITY.validate( value, null );
                    }
                } catch ( InvalidDatatypeValueException ex ) {
                    if ( ex.getMajorCode() != 1 && ex.getMinorCode() != -1 ) {
                        reportRecoverableXMLError(ex.getMajorCode(),
                                                  ex.getMinorCode(),
                                                  fStringPool.toString( attributeDecl.name.rawname), value );
                    } else {
                        System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
                    }
                }

                /*if (attributeDecl.list) {
                    av = fAttValidatorENTITIES;
                }
                else {
                    av = fAttValidatorENTITY;
                }*/

            }
            break;
        case XMLAttributeDecl.TYPE_ENUMERATION:
            av = fAttValidatorENUMERATION;
            break;
        case XMLAttributeDecl.TYPE_ID:
            {
                String  unTrimValue = fStringPool.toString(attValue);
                String  value       = unTrimValue.trim();
                if (fValidationEnabled) {
                    if (value != unTrimValue) {
                        if (invalidStandaloneAttDef(element, attributeDecl.name)) {
                            reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
                                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                      fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
                        }
                    }
                }
                try {
                    //this.fIdDefs = (Hashtable) fValID.validate( value, null );
                    //System.out.println("this.fIdDefs = " + this.fIdDefs );

                    this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
                } catch ( InvalidDatatypeValueException ex ) {
                    reportRecoverableXMLError(ex.getMajorCode(),
                                              ex.getMinorCode(),
                                              fStringPool.toString( attributeDecl.name.rawname), value );
                }
            }
            break;
        case XMLAttributeDecl.TYPE_IDREF:
            {
                String  unTrimValue = fStringPool.toString(attValue);
                String  value       = unTrimValue.trim();
                boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
                                                              //changes fTempAttDef
                if (fValidationEnabled) {
                    if (value != unTrimValue) {
                        if (invalidStandaloneAttDef(element, attributeDecl.name)) {
                            reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
                                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                      fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
                        }
                    }
                }
                try {
                    if ( isAlistAttribute ) {
                        fValIDRefs.validate( value, this.fStoreIDRef );
                    } else {
                        fValIDRef.validate( value, this.fStoreIDRef );
                    }
                } catch ( InvalidDatatypeValueException ex ) {
                    if ( ex.getMajorCode() != 1 && ex.getMinorCode() != -1 ) {
                        reportRecoverableXMLError(ex.getMajorCode(),
                                                  ex.getMinorCode(),
                                                  fStringPool.toString( attributeDecl.name.rawname), value );
                    } else {
                        System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
                    }
                }

            }
            break;
        case XMLAttributeDecl.TYPE_NOTATION:
            {
                /* WIP
                String  unTrimValue = fStringPool.toString(attValue);
             String  value       = unTrimValue.trim();
             if (fValidationEnabled) {
                 if (value != unTrimValue) {
                     if (invalidStandaloneAttDef(element, attributeDecl.name)) {
                         reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
                                                   XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                   fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
                     }
                 }
             }
             try {
                 //this.fIdDefs = (Hashtable) fValID.validate( value, null );
                 //System.out.println("this.fIdDefs = " + this.fIdDefs );

                 this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
             } catch ( InvalidDatatypeValueException ex ) {
                 reportRecoverableXMLError(ex.getMajorCode(),
                                           ex.getMinorCode(),
                                           fStringPool.toString( attributeDecl.name.rawname), value );
             }
          }
            */
            av = fAttValidatorNOTATION;


            }
            break;
        case XMLAttributeDecl.TYPE_NMTOKEN:
            {
                String  unTrimValue = fStringPool.toString(attValue);
                String  value       = unTrimValue.trim();
                boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
                //changes fTempAttDef
                if (fValidationEnabled) {
                    if (value != unTrimValue) {
                        if (invalidStandaloneAttDef(element, attributeDecl.name)) {
                            reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
                                                      XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                      fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
                        }
                    }
                }
                try {
                    if ( isAlistAttribute ) {
                        fValNMTOKENS.validate( value, null );
                    } else {
                        fValNMTOKEN.validate( value, null );
                    }
                } catch ( InvalidDatatypeValueException ex ) {
                    reportRecoverableXMLError(XMLMessages.MSG_NMTOKEN_INVALID,
                                              XMLMessages.VC_NAME_TOKEN,
                                              fStringPool.toString(attributeDecl.name.rawname), value);//TODO NMTOKENS messge
                }

            }
            break;
        }
        if ( av != null )
            av.normalize(element, attributeDecl.name, attValue,
                         attributeDecl.type, attributeDecl.enumeration);
    }

    /** Character data in content. */
    private void charDataInContent() {

        if (DEBUG_ELEMENT_CHILDREN) {
            System.out.println("charDataInContent()");
        }
        if (fElementChildren.length <= fElementChildrenLength) {
            QName[] newarray = new QName[fElementChildren.length * 2];
            System.arraycopy(fElementChildren, 0, newarray, 0, fElementChildren.length);
            fElementChildren = newarray;
        }
        QName qname = fElementChildren[fElementChildrenLength];
        if (qname == null) {
            for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
                fElementChildren[i] = new QName();
            }
            qname = fElementChildren[fElementChildrenLength];
        }
        qname.clear();
        fElementChildrenLength++;

    } // charDataInCount()

    /**
     * Check that the content of an element is valid.
     * <p>
     * This is the method of primary concern to the validator. This method is called
     * upon the scanner reaching the end tag of an element. At that time, the
     * element's children must be structurally validated, so it calls this method.
     * The index of the element being checked (in the decl pool), is provided as
     * well as an array of element name indexes of the children. The validator must
     * confirm that this element can have these children in this order.
     * <p>
     * This can also be called to do 'what if' testing of content models just to see
     * if they would be valid.
     * <p>
     * Note that the element index is an index into the element decl pool, whereas
     * the children indexes are name indexes, i.e. into the string pool.
     * <p>
     * A value of -1 in the children array indicates a PCDATA node. All other
     * indexes will be positive and represent child elements. The count can be
     * zero, since some elements have the EMPTY content model and that must be
     * confirmed.
     *
     * @param elementIndex The index within the <code>ElementDeclPool</code> of this
     *                     element.
     * @param childCount The number of entries in the <code>children</code> array.
     * @param children The children of this element.  Each integer is an index within
     *                 the <code>StringPool</code> of the child element name.  An index
     *                 of -1 is used to indicate an occurrence of non-whitespace character
     *                 data.
     *
     * @return The value -1 if fully valid, else the 0 based index of the child
     *         that first failed. If the value returned is equal to the number
     *         of children, then additional content is required to reach a valid
     *         ending state.
     *
     * @exception Exception Thrown on error.
     */
    private int checkContent(int elementIndex,
                             QName[] children,
                             int childOffset,
                             int childCount) throws Exception {

        // Get the element name index from the element
        // REVISIT: Validation
        final int elementType = fCurrentElement.rawname;

        if (DEBUG_PRINT_CONTENT) {
            String strTmp = fStringPool.toString(elementType);
            System.out.println("Name: "+strTmp+", "+
                               "Count: "+childCount+", "+
                               "ContentSpecType: " +fCurrentContentSpecType); //+getContentSpecAsString(elementIndex));
            for (int index = childOffset; index < (childOffset+childCount&& index < 10; index++) {
                if (index == 0) {
                    System.out.print("  (");
                }
                String childName = (children[index].localpart == -1) ? "#PCDATA" : fStringPool.toString(children[index].localpart);
                if (index + 1 == childCount) {
                    System.out.println(childName + ")");
                } else if (index + 1 == 10) {
                    System.out.println(childName + ",...)");
                } else {
                    System.out.print(childName + ",");
                }
            }
        }

        // Get out the content spec for this element
        final int contentType = fCurrentContentSpecType;

// debugging
//System.out.println("~~~~~~in checkContent, fCurrentContentSpecType : " + fCurrentContentSpecType);

        //
        //  Deal with the possible types of content. We try to optimized here
        //  by dealing specially with content models that don't require the
        //  full DFA treatment.
        //
        if (contentType == XMLElementDecl.TYPE_EMPTY) {
            //
            //  If the child count is greater than zero, then this is
            //  an error right off the bat at index 0.
            //
            if (childCount != 0) {
                return 0;
            }
        } else if (contentType == XMLElementDecl.TYPE_ANY) {
            //
            //  This one is open game so we don't pass any judgement on it
            //  at all. Its assumed to fine since it can hold anything.
            //
        } else if (contentType == XMLElementDecl.TYPE_MIXED || 
                   contentType == XMLElementDecl.TYPE_CHILDREN) {
            // Get the content model for this element, faulting it in if needed
            XMLContentModel cmElem = null;
            try {
                cmElem = getElementContentModel(elementIndex);
                int result = cmElem.validateContent(children, childOffset, childCount);
                if (result != -1 && fGrammarIsSchemaGrammar) {
                    // REVISIT: not optimized for performance,
                    EquivClassComparator comparator = new EquivClassComparator(fGrammarResolver, fStringPool);
                    cmElem.setEquivClassComparator(comparator);
                    result = cmElem.validateContentSpecial(children, childOffset, childCount);
                }
                return result;
            } catch (CMException excToCatch) {
                // REVISIT - Translate the caught exception to the protected error API
                int majorCode = excToCatch.getErrorCode();
                fErrorReporter.reportError(fErrorReporter.getLocator(),
                                           ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
                                           majorCode,
                                           0,
                                           null,
                                           XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
            }
        } else if (contentType == -1) {
            reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
                                      XMLMessages.VC_ELEMENT_VALID,
                                      elementType);
        } else if (contentType == XMLElementDecl.TYPE_SIMPLE ) {

            XMLContentModel cmElem = null;
            if (childCount > 0) {
                fErrorReporter.reportError(fErrorReporter.getLocator(),
                                           SchemaMessageProvider.SCHEMA_DOMAIN,
                                           SchemaMessageProvider.DatatypeError,
                                           SchemaMessageProvider.MSG_NONE,
                                           new Object [] { "In element '"+fStringPool.toString(elementType)+"' : "+
                                               "Can not have element children within a simple type content"},
                                           XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
            } else {
                try {

                    fGrammar.getElementDecl(elementIndex, fTempElementDecl);

                    DatatypeValidator dv = fTempElementDecl.datatypeValidator;

                    // If there is xsi:type validator, substitute it.
                    if ( fXsiTypeValidator != null ) {
                        dv = fXsiTypeValidator;
                        fXsiTypeValidator = null;
                    }

                    if (dv == null) {
                        System.out.println("Internal Error: this element have a simpletype "+
                                           "but no datatypevalidator was found, element "+fTempElementDecl.name
                                           +",locapart: "+fStringPool.toString(fTempElementDecl.name.localpart));
                    } else {
                        dv.validate(fDatatypeBuffer.toString(), null);
                    }

                } catch (InvalidDatatypeValueException idve) {
                    fErrorReporter.reportError(fErrorReporter.getLocator(),
                                               SchemaMessageProvider.SCHEMA_DOMAIN,
                                               SchemaMessageProvider.DatatypeError,
                                               SchemaMessageProvider.MSG_NONE,
                                               new Object [] { idve.getMessage()},
                                               XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
                }
            }
        } else {
            fErrorReporter.reportError(fErrorReporter.getLocator(),
                                       ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
                                       ImplementationMessages.VAL_CST,
                                       0,
                                       null,
                                       XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
        }

        // We succeeded
        return -1;

    } // checkContent(int,int,int[]):int


    /**
     * Checks that all declared elements refer to declared elements
     * in their content models. This method calls out to the error
     * handler to indicate warnings.
     */
    /*private void checkDeclaredElements() throws Exception {

                //****DEBUG****
                if (DEBUG) print("(???) XMLValidator.checkDeclaredElements\n");
                //****DEBUG****

        for (int i = 0; i < fElementCount; i++) {
            int type = fGrammar.getContentSpecType(i);
            if (type == XMLElementDecl.TYPE_MIXED || type == XMLElementDecl.TYPE_CHILDREN) {
                int chunk = i >> CHUNK_SHIFT;
                int index = i &  CHUNK_MASK;
                int contentSpecIndex = fContentSpec[chunk][index];
                checkDeclaredElements(i, contentSpecIndex);
            }
        }
    }
    */

    private void printChildren() {
        if (DEBUG_ELEMENT_CHILDREN) {
            System.out.print('[');
            for (int i = 0; i < fElementChildrenLength; i++) {
                System.out.print(' ');
                QName qname = fElementChildren[i];
                if (qname != null) {
                    System.out.print(fStringPool.toString(qname.rawname));
                } else {
                    System.out.print("null");
                }
                if (i < fElementChildrenLength - 1) {
                    System.out.print(", ");
                }
                System.out.flush();
            }
            System.out.print(" ]");
            System.out.println();
        }
    }

    private void printStack() {
        if (DEBUG_ELEMENT_CHILDREN) {
            System.out.print('{');
            for (int i = 0; i <= fElementDepth; i++) {
                System.out.print(' ');
                System.out.print(fElementChildrenOffsetStack[i]);
                if (i < fElementDepth) {
                    System.out.print(", ");
                }
                System.out.flush();
            }
            System.out.print(" }");
            System.out.println();
        }
    }


    //
    // Interfaces
    //

    /**
     * AttributeValidator.
     */
    public interface AttributeValidator {

        //
        // AttributeValidator methods
        //

        /** Normalize. */
        public int normalize(QName element, QName attribute,
                             int attValue, int attType, int enumHandle)
        throws Exception;

    } // interface AttributeValidator


    /** Returns true if invalid standalone attribute definition. */
    boolean invalidStandaloneAttDef(QName element, QName attribute) {
        if (fStandaloneReader == -1) {
            return false;
        }
        // we are normalizing a default att value...  this ok?
        if (element.rawname == -1) {
            return false;
        }
        return getAttDefIsExternal(element, attribute);
    }


    //
    // Classes
    //


    /**
     * AttValidatorNOTATION.
     */
    final class AttValidatorNOTATION
    implements AttributeValidator {

        //
        // AttributeValidator methods
        //

        /** Normalize. */
        public int normalize(QName element, QName attribute,
                             int attValueHandle, int attType,
                             int enumHandle) throws Exception {
            //
            // Normalize attribute based upon attribute type...
            //
            String attValue = fStringPool.toString(attValueHandle);
            String newAttValue = attValue.trim();
            if (fValidating) {
                // REVISIT - can we release the old string?
                if (newAttValue != attValue) {
                    if (invalidStandaloneAttDef(element, attribute)) {
                        reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
                                                  XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                  fStringPool.toString(attribute.rawname), attValue, newAttValue);
                    }
                    attValueHandle = fStringPool.addSymbol(newAttValue);
                } else {
                    attValueHandle = fStringPool.addSymbol(attValueHandle);
                }
                //
                // NOTATION - check that the value is in the AttDef enumeration (V_TAGo)
                //
                if (!fStringPool.stringInList(enumHandle, attValueHandle)) {
                    reportRecoverableXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
                                              XMLMessages.VC_NOTATION_ATTRIBUTES,
                                              fStringPool.toString(attribute.rawname),
                                              newAttValue, fStringPool.stringListAsString(enumHandle));
                }
            } else if (newAttValue != attValue) {
                // REVISIT - can we release the old string?
                attValueHandle = fStringPool.addSymbol(newAttValue);
            }
            return attValueHandle;

        } // normalize(QName,QName,int,int,int):int

        //
        // Package methods
        //

        /** Returns true if invalid standalone attribute definition. */
        boolean invalidStandaloneAttDef(QName element, QName attribute) {
            if (fStandaloneReader == -1) {
                return false;
            }
            // we are normalizing a default att value...  this ok?
            if (element.rawname == -1) {
                return false;
            }
            return getAttDefIsExternal(element, attribute);
        }

    } // class AttValidatorNOTATION

    /**
     * AttValidatorENUMERATION.
     */
    final class AttValidatorENUMERATION
    implements AttributeValidator {

        //
        // AttributeValidator methods
        //

        /** Normalize. */
        public int normalize(QName element, QName attribute,
                             int attValueHandle, int attType,
                             int enumHandle) throws Exception {
            //
            // Normalize attribute based upon attribute type...
            //
            String attValue = fStringPool.toString(attValueHandle);
            String newAttValue = attValue.trim();
            if (fValidating) {
                // REVISIT - can we release the old string?
                if (newAttValue != attValue) {
                    if (invalidStandaloneAttDef(element, attribute)) {
                        reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
                                                  XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
                                                  fStringPool.toString(attribute.rawname), attValue, newAttValue);
                    }
                    attValueHandle = fStringPool.addSymbol(newAttValue);
                } else {
                    attValueHandle = fStringPool.addSymbol(attValueHandle);
                }
                //
                // ENUMERATION - check that value is in the AttDef enumeration (V_TAG9)
                //
                if (!fStringPool.stringInList(enumHandle, attValueHandle)) {
                    reportRecoverableXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
                                              XMLMessages.VC_ENUMERATION,
                                              fStringPool.toString(attribute.rawname),
                                              newAttValue, fStringPool.stringListAsString(enumHandle));
                }
            } else if (newAttValue != attValue) {
                // REVISIT - can we release the old string?
                attValueHandle = fStringPool.addSymbol(newAttValue);
            }
            return attValueHandle;

        } // normalize(QName,QName,int,int,int):int

        //
        // Package methods
        //

        /** Returns true if invalid standalone attribute definition. */
        boolean invalidStandaloneAttDef(QName element, QName attribute) {
            if (fStandaloneReader == -1) {
                return false;
            }
            // we are normalizing a default att value...  this ok?
            if (element.rawname == -1) {
                return false;
            }
            return getAttDefIsExternal(element, attribute);
        }

    } // class AttValidatorENUMERATION

} // class XMLValidator
TOP

Related Classes of org.apache.xerces.validators.common.XMLValidator$Resolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.