FileDocCategorySizeDatePackage
XSDHandler.javaAPI DocApache Xerces 3.0.1134398Fri Sep 14 20:33:52 BST 2007org.apache.xerces.impl.xs.traversers

XSDHandler

public class XSDHandler extends Object
The purpose of this class is to co-ordinate the construction of a grammar object corresponding to a schema. To do this, it must be prepared to parse several schema documents (for instance if the schema document originally referred to contains or information items). If any of the schemas imports a schema, other grammars may be constructed as a side-effect.
xerces.internal
author
Neil Graham, IBM
author
Pavani Mukthipudi, Sun Microsystems
version
$Id: XSDHandler.java 449487 2006-09-24 21:11:28Z mrglavas $

Fields Summary
protected static final String
VALIDATION
Feature identifier: validation.
protected static final String
XMLSCHEMA_VALIDATION
feature identifier: XML Schema validation
protected static final String
ALLOW_JAVA_ENCODINGS
Feature identifier: allow java encodings
protected static final String
CONTINUE_AFTER_FATAL_ERROR
Feature identifier: continue after fatal error
protected static final String
STANDARD_URI_CONFORMANT_FEATURE
Feature identifier: allow java encodings
protected static final String
DISALLOW_DOCTYPE
Feature: disallow doctype
protected static final String
GENERATE_SYNTHETIC_ANNOTATIONS
Feature: generate synthetic annotations
protected static final String
VALIDATE_ANNOTATIONS
Feature identifier: validate annotations.
protected static final String
HONOUR_ALL_SCHEMALOCATIONS
Feature identifier: honour all schemaLocations
private static final String
NAMESPACE_PREFIXES
Feature identifier: namespace prefixes.
protected static final String
STRING_INTERNING
Feature identifier: string interning.
protected static final String
ERROR_HANDLER
Property identifier: error handler.
protected static final String
JAXP_SCHEMA_SOURCE
Property identifier: JAXP schema source.
public static final String
ENTITY_RESOLVER
Property identifier: entity resolver.
protected static final String
ENTITY_MANAGER
Property identifier: entity manager.
public static final String
ERROR_REPORTER
Property identifier: error reporter.
public static final String
XMLGRAMMAR_POOL
Property identifier: grammar pool.
public static final String
SYMBOL_TABLE
Property identifier: symbol table.
protected static final String
SECURITY_MANAGER
Property identifier: security manager.
protected static final boolean
DEBUG_NODE_POOL
static final int
ATTRIBUTE_TYPE
static final int
ATTRIBUTEGROUP_TYPE
static final int
ELEMENT_TYPE
static final int
GROUP_TYPE
static final int
IDENTITYCONSTRAINT_TYPE
static final int
NOTATION_TYPE
static final int
TYPEDECL_TYPE
public static final String
REDEF_IDENTIFIER
protected Hashtable
fNotationRegistry
protected org.apache.xerces.impl.xs.XSDeclarationPool
fDeclPool
private Hashtable
fUnparsedAttributeRegistry
private Hashtable
fUnparsedAttributeGroupRegistry
private Hashtable
fUnparsedElementRegistry
private Hashtable
fUnparsedGroupRegistry
private Hashtable
fUnparsedIdentityConstraintRegistry
private Hashtable
fUnparsedNotationRegistry
private Hashtable
fUnparsedTypeRegistry
private Hashtable
fUnparsedAttributeRegistrySub
private Hashtable
fUnparsedAttributeGroupRegistrySub
private Hashtable
fUnparsedElementRegistrySub
private Hashtable
fUnparsedGroupRegistrySub
private Hashtable
fUnparsedIdentityConstraintRegistrySub
private Hashtable
fUnparsedNotationRegistrySub
private Hashtable
fUnparsedTypeRegistrySub
private Hashtable
fXSDocumentInfoRegistry
private Hashtable
fDependencyMap
private Hashtable
fImportMap
private Vector
fAllTNSs
private Hashtable
fLocationPairs
private static final Hashtable
EMPTY_TABLE
Hashtable
fHiddenNodes
private Hashtable
fTraversed
private Hashtable
fDoc2SystemId
private XSDocumentInfo
fRoot
private Hashtable
fDoc2XSDocumentMap
private Hashtable
fRedefine2XSDMap
private Hashtable
fRedefine2NSSupport
private Hashtable
fRedefinedRestrictedAttributeGroupRegistry
private Hashtable
fRedefinedRestrictedGroupRegistry
private boolean
fLastSchemaWasDuplicate
private boolean
fValidateAnnotations
private boolean
fHonourAllSchemaLocations
private org.apache.xerces.impl.XMLErrorReporter
fErrorReporter
private org.apache.xerces.xni.parser.XMLEntityResolver
fEntityResolver
private XSAttributeChecker
fAttributeChecker
private org.apache.xerces.util.SymbolTable
fSymbolTable
private org.apache.xerces.impl.xs.XSGrammarBucket
fGrammarBucket
private org.apache.xerces.impl.xs.XSDDescription
fSchemaGrammarDescription
private org.apache.xerces.xni.grammars.XMLGrammarPool
fGrammarPool
XSDAttributeGroupTraverser
fAttributeGroupTraverser
XSDAttributeTraverser
fAttributeTraverser
XSDComplexTypeTraverser
fComplexTypeTraverser
XSDElementTraverser
fElementTraverser
XSDGroupTraverser
fGroupTraverser
XSDKeyrefTraverser
fKeyrefTraverser
XSDNotationTraverser
fNotationTraverser
XSDSimpleTypeTraverser
fSimpleTypeTraverser
XSDUniqueOrKeyTraverser
fUniqueOrKeyTraverser
XSDWildcardTraverser
fWildCardTraverser
org.apache.xerces.impl.xs.opti.SchemaDOMParser
fSchemaParser
SchemaContentHandler
fXSContentHandler
org.apache.xerces.parsers.XML11Configuration
fAnnotationValidator
XSAnnotationGrammarPool
fGrammarBucketAdapter
private static final int
INIT_STACK_SIZE
private static final int
INC_STACK_SIZE
private int
fLocalElemStackPos
private org.apache.xerces.impl.xs.XSParticleDecl[]
fParticle
private Element[]
fLocalElementDecl
private XSDocumentInfo[]
fLocalElementDecl_schema
private int[]
fAllContext
private org.apache.xerces.xs.XSObject[]
fParent
private String[]
fLocalElemNamespaceContext
private static final int
INIT_KEYREF_STACK
private static final int
INC_KEYREF_STACK_AMOUNT
private int
fKeyrefStackPos
private Element[]
fKeyrefs
private XSDocumentInfo[]
fKeyrefsMapXSDocumentInfo
private org.apache.xerces.impl.xs.XSElementDecl[]
fKeyrefElems
private String[]
fKeyrefNamespaceContext
private static final String[]
NS_ERROR_CODES
private static final String[]
ELE_ERROR_CODES
private Vector
fReportedTNS
private static final String[]
COMP_TYPE
private static final String[]
CIRCULAR_CODES
private org.apache.xerces.impl.xs.util.SimpleLocator
xl
Constructors Summary
public XSDHandler()

    
    // Constructors
     
        fHiddenNodes = new Hashtable();       
        fSchemaParser = new SchemaDOMParser(new SchemaParsingConfig());
    
public XSDHandler(org.apache.xerces.impl.xs.XSGrammarBucket gBucket)

        this();
        fGrammarBucket = gBucket;
        
        // Note: don't use SchemaConfiguration internally
        //       we will get stack overflaw because
        //       XMLSchemaValidator will be instantiating XSDHandler...
        fSchemaGrammarDescription = new XSDDescription();
    
Methods Summary
protected voidbuildGlobalNameRegistries()

        

        // Starting with fRoot, we examine each child of the schema
        // element.  Skipping all imports and includes, we record the names
        // of all other global components (and children of <redefine>).  We
        // also put <redefine> names in a registry that we look through in
        // case something needs renaming.  Once we're done with a schema we
        // set its Document node to hidden so that we don't try to traverse
        // it again; then we look to its Dependency map entry.  We keep a
        // stack of schemas that we haven't yet finished processing; this
        // is a depth-first traversal.
            
        Stack schemasToProcess = new Stack();
        schemasToProcess.push(fRoot);
       
        while (!schemasToProcess.empty()) {            
            XSDocumentInfo currSchemaDoc =
                (XSDocumentInfo)schemasToProcess.pop();
            Element currDoc = currSchemaDoc.fSchemaElement; 
            if(DOMUtil.isHidden(currDoc, fHiddenNodes)){
                // must have processed this already!
                continue;
            }

            Element currRoot = currDoc;
            // process this schema's global decls
            boolean dependenciesCanOccur = true;
            for (Element globalComp =
                DOMUtil.getFirstChildElement(currRoot);
            globalComp != null;
            globalComp = DOMUtil.getNextSiblingElement(globalComp)) {
                // this loop makes sure the <schema> element ordering is
                // also valid.
                if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_ANNOTATION)) {
                    //skip it; traverse it later
                    continue;
                }
                else if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_INCLUDE) ||
                        DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_IMPORT)) {
                    if (!dependenciesCanOccur) {
                        reportSchemaError("s4s-elt-invalid-content.3", new Object [] {DOMUtil.getLocalName(globalComp)}, globalComp);
                    }
                    DOMUtil.setHidden(globalComp, fHiddenNodes);
                }
                else if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_REDEFINE)) {
                    if (!dependenciesCanOccur) {
                        reportSchemaError("s4s-elt-invalid-content.3", new Object [] {DOMUtil.getLocalName(globalComp)}, globalComp);
                    }
                    for (Element redefineComp = DOMUtil.getFirstChildElement(globalComp);
                    redefineComp != null;
                    redefineComp = DOMUtil.getNextSiblingElement(redefineComp)) {
                        String lName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME);
                        if (lName.length() == 0) // an error we'll catch later
                            continue;
                        String qName = currSchemaDoc.fTargetNamespace == null ?
                                ","+lName:
                                    currSchemaDoc.fTargetNamespace +","+lName;
                        String componentType = DOMUtil.getLocalName(redefineComp);
                        if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
                            checkForDuplicateNames(qName, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, redefineComp, currSchemaDoc);
                            // the check will have changed our name;
                            String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME)+REDEF_IDENTIFIER;
                            // and all we need to do is error-check+rename our kkids:
                            renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_ATTRIBUTEGROUP,
                                    lName, targetLName);
                        }
                        else if ((componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) ||
                                (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE))) {
                            checkForDuplicateNames(qName, fUnparsedTypeRegistry, fUnparsedTypeRegistrySub, redefineComp, currSchemaDoc);
                            // the check will have changed our name;
                            String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME) + REDEF_IDENTIFIER;
                            // and all we need to do is error-check+rename our kkids:
                            if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
                                renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_COMPLEXTYPE,
                                        lName, targetLName);
                            }
                            else { // must be simpleType
                                renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_SIMPLETYPE,
                                        lName, targetLName);
                            }
                        }
                        else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
                            checkForDuplicateNames(qName, fUnparsedGroupRegistry, fUnparsedGroupRegistrySub, redefineComp, currSchemaDoc);
                            // the check will have changed our name;
                            String targetLName = DOMUtil.getAttrValue(redefineComp, SchemaSymbols.ATT_NAME)+REDEF_IDENTIFIER;
                            // and all we need to do is error-check+rename our kids:
                            renameRedefiningComponents(currSchemaDoc, redefineComp, SchemaSymbols.ELT_GROUP,
                                    lName, targetLName);
                        }
                    } // end march through <redefine> children
                    // and now set as traversed
                    //DOMUtil.setHidden(globalComp);
                }
                else {
                    dependenciesCanOccur = false;
                    String lName = DOMUtil.getAttrValue(globalComp, SchemaSymbols.ATT_NAME);
                    if (lName.length() == 0) // an error we'll catch later
                        continue;
                    String qName = currSchemaDoc.fTargetNamespace == null?
                            ","+lName:
                                currSchemaDoc.fTargetNamespace +","+lName;
                    String componentType = DOMUtil.getLocalName(globalComp);
                    if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
                        checkForDuplicateNames(qName, fUnparsedAttributeRegistry, fUnparsedAttributeRegistrySub, globalComp, currSchemaDoc);
                    }
                    else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
                        checkForDuplicateNames(qName, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, globalComp, currSchemaDoc);
                    }
                    else if ((componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) ||
                            (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE))) {
                        checkForDuplicateNames(qName, fUnparsedTypeRegistry, fUnparsedTypeRegistrySub, globalComp, currSchemaDoc);
                    }
                    else if (componentType.equals(SchemaSymbols.ELT_ELEMENT)) {
                        checkForDuplicateNames(qName, fUnparsedElementRegistry, fUnparsedElementRegistrySub, globalComp, currSchemaDoc);
                    }
                    else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
                        checkForDuplicateNames(qName, fUnparsedGroupRegistry, fUnparsedGroupRegistrySub, globalComp, currSchemaDoc);
                    }
                    else if (componentType.equals(SchemaSymbols.ELT_NOTATION)) {
                        checkForDuplicateNames(qName, fUnparsedNotationRegistry, fUnparsedNotationRegistrySub, globalComp, currSchemaDoc);
                    }
                }
            } // end for
            
            // now we're done with this one!
           	DOMUtil.setHidden(currDoc, fHiddenNodes);
            // now add the schemas this guy depends on
            Vector currSchemaDepends = (Vector)fDependencyMap.get(currSchemaDoc);
            for (int i = 0; i < currSchemaDepends.size(); i++) {
                schemasToProcess.push(currSchemaDepends.elementAt(i));
            }
        } // while

    
private intchangeRedefineGroup(java.lang.String originalQName, java.lang.String elementSought, java.lang.String newName, org.w3c.dom.Element curr, XSDocumentInfo schemaDoc)

        int result = 0;
        for (Element child = DOMUtil.getFirstChildElement(curr);
        child != null; child = DOMUtil.getNextSiblingElement(child)) {
            String name = DOMUtil.getLocalName(child);
            if (!name.equals(elementSought))
                result += changeRedefineGroup(originalQName, elementSought, newName, child, schemaDoc);
            else {
                String ref = child.getAttribute( SchemaSymbols.ATT_REF );
                if (ref.length() != 0) {
                    String processedRef = findQName(ref, schemaDoc);
                    if (originalQName.equals(processedRef)) {
                        String prefix = XMLSymbols.EMPTY_STRING;
                        int colonptr = ref.indexOf(":");
                        if (colonptr > 0) {
                            prefix = ref.substring(0,colonptr);
                            child.setAttribute(SchemaSymbols.ATT_REF, prefix + ":" + newName);
                        }
                        else
                            child.setAttribute(SchemaSymbols.ATT_REF, newName);
                        result++;
                        if (elementSought.equals(SchemaSymbols.ELT_GROUP)) {
                            String minOccurs = child.getAttribute( SchemaSymbols.ATT_MINOCCURS );
                            String maxOccurs = child.getAttribute( SchemaSymbols.ATT_MAXOCCURS );
                            if (!((maxOccurs.length() == 0 || maxOccurs.equals("1"))
                                    && (minOccurs.length() == 0 || minOccurs.equals("1")))) {
                                reportSchemaError("src-redefine.6.1.2", new Object [] {ref}, child);
                            }
                        }
                    }
                } // if ref was null some other stage of processing will flag the error
            }
        }
        return result;
    
voidcheckForDuplicateNames(java.lang.String qName, java.util.Hashtable registry, java.util.Hashtable registry_sub, org.w3c.dom.Element currComp, XSDocumentInfo currSchema)
This method makes sure that if this component is being redefined that it lives in the right schema. It then renames the component correctly. If it detects a collision--a duplicate definition--then it complains. Note that redefines must be handled carefully: if there is a collision, it may be because we're redefining something we know about or because we've found the thing we're redefining.

        Object objElem = null;
        // REVISIT:  when we add derivation checking, we'll have to make
        // sure that ID constraint collisions don't necessarily result in error messages.
        if ((objElem = registry.get(qName)) == null) {
            // just add it in!
            registry.put(qName, currComp);
            registry_sub.put(qName, currSchema);
            
        }
        else {
            Element collidingElem = (Element)objElem;
            XSDocumentInfo collidingElemSchema = (XSDocumentInfo)registry_sub.get(qName);
            if (collidingElem == currComp) return;
            Element elemParent = null;
            XSDocumentInfo redefinedSchema = null;
            // case where we've collided with a redefining element
            // (the parent of the colliding element is a redefine)
            boolean collidedWithRedefine = true;
            if ((DOMUtil.getLocalName((elemParent = DOMUtil.getParent(collidingElem))).equals(SchemaSymbols.ELT_REDEFINE))) {
                redefinedSchema = (XSDocumentInfo)(fRedefine2XSDMap.get(elemParent));
                // case where we're a redefining element.
            }
            else if ((DOMUtil.getLocalName(DOMUtil.getParent(currComp)).equals(SchemaSymbols.ELT_REDEFINE))) {
                redefinedSchema = collidingElemSchema;
                collidedWithRedefine = false;
            }
            if (redefinedSchema != null) { //redefinition involved somehow
                // If both components belong to the same document then
                // report an error and return.
                if(collidingElemSchema == currSchema){
                    reportSchemaError("sch-props-correct.2", new Object[]{qName}, currComp);
                    return;
                }
                
                String newName = qName.substring(qName.lastIndexOf(',")+1)+REDEF_IDENTIFIER;
                if (redefinedSchema == currSchema) { // object comp. okay here
                    // now have to do some renaming...
                    currComp.setAttribute(SchemaSymbols.ATT_NAME, newName);
                    if (currSchema.fTargetNamespace == null){
                        registry.put(","+newName, currComp);
                        registry_sub.put(","+newName, currSchema);
                    }
                    else{
                        registry.put(currSchema.fTargetNamespace+","+newName, currComp);
                        registry_sub.put(currSchema.fTargetNamespace+","+newName, currSchema);
                    }
                    // and take care of nested redefines by calling recursively:
                    if (currSchema.fTargetNamespace == null)
                    	checkForDuplicateNames(","+newName, registry, registry_sub, currComp, currSchema);
                    else
                    	checkForDuplicateNames(currSchema.fTargetNamespace+","+newName, registry, registry_sub, currComp, currSchema);
                }
                else { // we may be redefining the wrong schema
                    if (collidedWithRedefine) {
                        if (currSchema.fTargetNamespace == null)
                            checkForDuplicateNames(","+newName, registry, registry_sub, currComp, currSchema);
                        else
                            checkForDuplicateNames(currSchema.fTargetNamespace+","+newName, registry, registry_sub, currComp, currSchema);
                    }
                    else {
                        // error that redefined element in wrong schema
                        reportSchemaError("sch-props-correct.2", new Object [] {qName}, currComp);
                    }
                }
            }
            else {
                // we've just got a flat-out collision
                reportSchemaError("sch-props-correct.2", new Object []{qName}, currComp);
            }
        }
    
protected XSDocumentInfoconstructTrees(org.w3c.dom.Element schemaRoot, java.lang.String locationHint, org.apache.xerces.impl.xs.XSDDescription desc)

    
    // This method does several things:
    // It constructs an instance of an XSDocumentInfo object using the
    // schemaRoot node.  Then, for each <include>,
    // <redefine>, and <import> children, it attempts to resolve the
    // requested schema document, initiates a DOM parse, and calls
    // itself recursively on that document's root.  It also records in
    // the DependencyMap object what XSDocumentInfo objects its XSDocumentInfo
    // depends on.
    // It also makes sure the targetNamespace of the schema it was
    // called to parse is correct.
            
        if (schemaRoot == null) return null;
        String callerTNS = desc.getTargetNamespace();
        short referType = desc.getContextType();
        
        XSDocumentInfo currSchemaInfo = null;
        try {
            // note that attributes are freed at end of traverseSchemas()
            currSchemaInfo = new XSDocumentInfo(schemaRoot, fAttributeChecker, fSymbolTable);
        } catch (XMLSchemaException se) {
            reportSchemaError(ELE_ERROR_CODES[referType],
                    new Object[]{locationHint},
					  schemaRoot);
            return null;
        }
        // targetNamespace="" is not valid, issue a warning, and ignore it
        if (currSchemaInfo.fTargetNamespace != null &&
                currSchemaInfo.fTargetNamespace.length() == 0) {
            reportSchemaWarning("EmptyTargetNamespace",
                    new Object[]{locationHint},
					schemaRoot);
            currSchemaInfo.fTargetNamespace = null;
        }
        
        if (callerTNS != null) {
            // the second index to the NS_ERROR_CODES array
            // if the caller/expected NS is not absent, we use the first column
            int secondIdx = 0;
            // for include and redefine
            if (referType == XSDDescription.CONTEXT_INCLUDE ||
                    referType == XSDDescription.CONTEXT_REDEFINE) {
                // if the referred document has no targetNamespace,
                // it's a chameleon schema
                if (currSchemaInfo.fTargetNamespace == null) {
                    currSchemaInfo.fTargetNamespace = callerTNS;
                    currSchemaInfo.fIsChameleonSchema = true;
                }
                // if the referred document has a target namespace differing
                // from the caller, it's an error
                else if (callerTNS != currSchemaInfo.fTargetNamespace) {
                    reportSchemaError(NS_ERROR_CODES[referType][secondIdx],
                            new Object [] {callerTNS, currSchemaInfo.fTargetNamespace},
							schemaRoot);
                    return null;
                }
            }
            // for instance and import, the two NS's must be the same
            else if (referType != XSDDescription.CONTEXT_PREPARSE && callerTNS != currSchemaInfo.fTargetNamespace) {
                reportSchemaError(NS_ERROR_CODES[referType][secondIdx],
                        new Object [] {callerTNS, currSchemaInfo.fTargetNamespace},
						schemaRoot);
                return null;
            }
        }
        // now there is no caller/expected NS, it's an error for the referred
        // document to have a target namespace, unless we are preparsing a schema
        else if (currSchemaInfo.fTargetNamespace != null) {
            // set the target namespace of the description
            if (referType == XSDDescription.CONTEXT_PREPARSE) {
                desc.setTargetNamespace(currSchemaInfo.fTargetNamespace);
                callerTNS = currSchemaInfo.fTargetNamespace;
            }
            else {
                // the second index to the NS_ERROR_CODES array
                // if the caller/expected NS is absent, we use the second column
                int secondIdx = 1;
                reportSchemaError(NS_ERROR_CODES[referType][secondIdx],
                        new Object [] {callerTNS, currSchemaInfo.fTargetNamespace},
						schemaRoot);
                return null;
            }
        }
        // the other cases (callerTNS == currSchemaInfo.fTargetNamespce == null)
        // are valid
        
        // a schema document can always access it's own target namespace
        currSchemaInfo.addAllowedNS(currSchemaInfo.fTargetNamespace);
        
        SchemaGrammar sg = null;
        
        if (referType == XSDDescription.CONTEXT_INCLUDE ||
                referType == XSDDescription.CONTEXT_REDEFINE) {
            sg = fGrammarBucket.getGrammar(currSchemaInfo.fTargetNamespace);
        }
        else if(fHonourAllSchemaLocations && referType == XSDDescription.CONTEXT_IMPORT) {
            sg = findGrammar(desc);
            if(sg == null) {
                sg = new SchemaGrammar(currSchemaInfo.fTargetNamespace, desc.makeClone(), fSymbolTable);
                fGrammarBucket.putGrammar(sg);
            }
        }
        else {
            sg = new SchemaGrammar(currSchemaInfo.fTargetNamespace, desc.makeClone(), fSymbolTable);
            fGrammarBucket.putGrammar(sg);
        }
        
        // store the document and its location
        // REVISIT: don't expose the DOM tree
        sg.addDocument(null, (String)fDoc2SystemId.get(currSchemaInfo.fSchemaElement));
        
        fDoc2XSDocumentMap.put(schemaRoot, currSchemaInfo);
        Vector dependencies = new Vector();
        Element rootNode = schemaRoot;
        
        Element newSchemaRoot = null;
        for (Element child = DOMUtil.getFirstChildElement(rootNode);
        child != null;
        child = DOMUtil.getNextSiblingElement(child)) {
            String schemaNamespace=null;
            String schemaHint=null;
            String localName = DOMUtil.getLocalName(child);
            
            short refType = -1;
            
            if (localName.equals(SchemaSymbols.ELT_ANNOTATION))
                continue;
            else if (localName.equals(SchemaSymbols.ELT_IMPORT)) {
                refType = XSDDescription.CONTEXT_IMPORT;
                // have to handle some validation here too!
                // call XSAttributeChecker to fill in attrs
                Object[] importAttrs = fAttributeChecker.checkAttributes(child, true, currSchemaInfo);
                schemaHint = (String)importAttrs[XSAttributeChecker.ATTIDX_SCHEMALOCATION];
                schemaNamespace = (String)importAttrs[XSAttributeChecker.ATTIDX_NAMESPACE];
                if (schemaNamespace != null)
                    schemaNamespace = fSymbolTable.addSymbol(schemaNamespace);
                // a document can't import another document with the same namespace
                if (schemaNamespace == currSchemaInfo.fTargetNamespace) {
                    reportSchemaError(schemaNamespace != null ? 
                            "src-import.1.1" : "src-import.1.2", new Object [] {schemaNamespace}, child);
                }
                
                // check contents and process optional annotations
                Element importChild = DOMUtil.getFirstChildElement(child);
                if(importChild != null ) {
                    String importComponentType = DOMUtil.getLocalName(importChild);
                    if (importComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
                        // promoting annotations to parent component
                        sg.addAnnotation(
                                fElementTraverser.traverseAnnotationDecl(importChild, importAttrs, true, currSchemaInfo));
                    } else {
                        reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", importComponentType}, child);
                    }
                    if(DOMUtil.getNextSiblingElement(importChild) != null) {
                        reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", DOMUtil.getLocalName(DOMUtil.getNextSiblingElement(importChild))}, child);
                    }
                }
                else {
                    String text = DOMUtil.getSyntheticAnnotation(child);
                    if (text != null) {
                        sg.addAnnotation(fElementTraverser.traverseSyntheticAnnotation(child, text, importAttrs, true, currSchemaInfo));
                    }
                }
                fAttributeChecker.returnAttrArray(importAttrs, currSchemaInfo);
                
                // if this namespace has not been imported by this document,
                //  then import if multiple imports support is enabled.
                if(currSchemaInfo.isAllowedNS(schemaNamespace)) {
                    if(!fHonourAllSchemaLocations)
                        continue;
                }
                else  {
                    currSchemaInfo.addAllowedNS(schemaNamespace);
                }
                // also record the fact that one namespace imports another one
                // convert null to ""
                String tns = null2EmptyString(currSchemaInfo.fTargetNamespace);
                // get all namespaces imported by this one
                Vector ins = (Vector)fImportMap.get(tns);
                // if no namespace was imported, create new Vector
                if (ins == null) {
                    // record that this one imports other(s)
                    fAllTNSs.addElement(tns);
                    ins = new Vector();
                    fImportMap.put(tns, ins);
                    ins.addElement(schemaNamespace);
                }
                else if (!ins.contains(schemaNamespace)){
                    ins.addElement(schemaNamespace);
                }
                
                fSchemaGrammarDescription.reset();
                fSchemaGrammarDescription.setContextType(XSDDescription.CONTEXT_IMPORT);
                fSchemaGrammarDescription.setBaseSystemId(doc2SystemId(schemaRoot));
                fSchemaGrammarDescription.setLocationHints(new String[]{schemaHint});
                fSchemaGrammarDescription.setTargetNamespace(schemaNamespace);
                
                // if a grammar with the same namespace and location exists (or being
                // built), ignore this one (don't traverse it).
                if ((!fHonourAllSchemaLocations && findGrammar(fSchemaGrammarDescription) != null) || isExistingGrammar(fSchemaGrammarDescription))
                    continue;
                // If "findGrammar" returns a grammar, then this is not the
                // the first time we see a location for a given namespace.
                // Don't consult the location pair hashtable in this case,
                // otherwise the location will be ignored because it'll get
                // resolved to the same location as the first hint.
                newSchemaRoot = resolveSchema(fSchemaGrammarDescription, false, child,
                                              findGrammar(fSchemaGrammarDescription) == null);
            }
            else if ((localName.equals(SchemaSymbols.ELT_INCLUDE)) ||
                    (localName.equals(SchemaSymbols.ELT_REDEFINE))) {
                // validation for redefine/include will be the same here; just
                // make sure TNS is right (don't care about redef contents
                // yet).
                Object[] includeAttrs = fAttributeChecker.checkAttributes(child, true, currSchemaInfo);
                schemaHint = (String)includeAttrs[XSAttributeChecker.ATTIDX_SCHEMALOCATION];
                // store the namespace decls of the redefine element
                if (localName.equals(SchemaSymbols.ELT_REDEFINE)) {
                    fRedefine2NSSupport.put(child, new SchemaNamespaceSupport(currSchemaInfo.fNamespaceSupport));
                }
                
                // check annotations.  Must do this here to avoid having to
                // re-parse attributes later
                if(localName.equals(SchemaSymbols.ELT_INCLUDE)) {
                    Element includeChild = DOMUtil.getFirstChildElement(child);
                    if(includeChild != null ) {
                        String includeComponentType = DOMUtil.getLocalName(includeChild);
                        if (includeComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
                            // promoting annotations to parent component
                            sg.addAnnotation(
                                    fElementTraverser.traverseAnnotationDecl(includeChild, includeAttrs, true, currSchemaInfo));
                        } else {
                            reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", includeComponentType}, child);
                        }
                        if(DOMUtil.getNextSiblingElement(includeChild) != null) {
                            reportSchemaError("s4s-elt-must-match.1", new Object [] {localName, "annotation?", DOMUtil.getLocalName(DOMUtil.getNextSiblingElement(includeChild))}, child);
                        }
                    }
                    else {
                        String text = DOMUtil.getSyntheticAnnotation(child);
                        if (text != null) {
                            sg.addAnnotation(fElementTraverser.traverseSyntheticAnnotation(child, text, includeAttrs, true, currSchemaInfo));
                        }
                    }
                }
                else {
                    for (Element redefinedChild = DOMUtil.getFirstChildElement(child);
                    redefinedChild != null;
                    redefinedChild = DOMUtil.getNextSiblingElement(redefinedChild)) {
                        String redefinedComponentType = DOMUtil.getLocalName(redefinedChild);
                        if (redefinedComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
                            // promoting annotations to parent component
                            sg.addAnnotation(
                                    fElementTraverser.traverseAnnotationDecl(redefinedChild, includeAttrs, true, currSchemaInfo));
                            DOMUtil.setHidden(redefinedChild, fHiddenNodes);
                        }
                        else {
                            String text = DOMUtil.getSyntheticAnnotation(child);
                            if (text != null) {
                                sg.addAnnotation(fElementTraverser.traverseSyntheticAnnotation(child, text, includeAttrs, true, currSchemaInfo));
                            }
                        }
                        // catch all other content errors later
                    }
                }
                fAttributeChecker.returnAttrArray(includeAttrs, currSchemaInfo);
                // schemaLocation is required on <include> and <redefine>
                if (schemaHint == null) {
                    reportSchemaError("s4s-att-must-appear", new Object [] {
                            "<include> or <redefine>", "schemaLocation"},
                            child);
                }
                // pass the systemId of the current document as the base systemId
                boolean mustResolve = false;
                refType = XSDDescription.CONTEXT_INCLUDE;
                if(localName.equals(SchemaSymbols.ELT_REDEFINE)) {
                    mustResolve = nonAnnotationContent(child);
                    refType = XSDDescription.CONTEXT_REDEFINE;
                }
                fSchemaGrammarDescription.reset();
                fSchemaGrammarDescription.setContextType(refType);
                fSchemaGrammarDescription.setBaseSystemId(doc2SystemId(schemaRoot));
                fSchemaGrammarDescription.setLocationHints(new String[]{schemaHint});
                fSchemaGrammarDescription.setTargetNamespace(callerTNS);
                newSchemaRoot = resolveSchema(fSchemaGrammarDescription, mustResolve, child, true);
                schemaNamespace = currSchemaInfo.fTargetNamespace;
            }
            else {
                // no more possibility of schema references in well-formed
                // schema...
                break;
            }
            
            // If the schema is duplicate, we needn't call constructTrees() again.
            // To handle mutual <include>s
            XSDocumentInfo newSchemaInfo = null;
            if (fLastSchemaWasDuplicate) {
                newSchemaInfo = newSchemaRoot == null ? null : (XSDocumentInfo)fDoc2XSDocumentMap.get(newSchemaRoot);
            }
            else {
               	newSchemaInfo = constructTrees(newSchemaRoot, schemaHint, fSchemaGrammarDescription);
            }
            
            if (localName.equals(SchemaSymbols.ELT_REDEFINE) &&
                    newSchemaInfo != null) {
                // must record which schema we're redefining so that we can
                // rename the right things later!
                fRedefine2XSDMap.put(child, newSchemaInfo);
            }
            if (newSchemaRoot != null) {
                if (newSchemaInfo != null)
                    dependencies.addElement(newSchemaInfo);
                newSchemaRoot = null;
            }
        }
        
        fDependencyMap.put(currSchemaInfo, dependencies);
        return currSchemaInfo;
    
private voidcreateAnnotationValidator()

        fAnnotationValidator = new XML11Configuration();
        fGrammarBucketAdapter = new XSAnnotationGrammarPool();
        fAnnotationValidator.setFeature(VALIDATION, true);
        fAnnotationValidator.setFeature(XMLSCHEMA_VALIDATION, true);
        fAnnotationValidator.setProperty(XMLGRAMMAR_POOL, fGrammarBucketAdapter);
        /** Set error handler. **/
        XMLErrorHandler errorHandler = fErrorReporter.getErrorHandler();
        fAnnotationValidator.setProperty(ERROR_HANDLER, (errorHandler != null) ? errorHandler : new DefaultErrorHandler());
    
private voidcreateTraversers()

        fAttributeChecker = new XSAttributeChecker(this);
        fAttributeGroupTraverser = new XSDAttributeGroupTraverser(this, fAttributeChecker);
        fAttributeTraverser = new XSDAttributeTraverser(this, fAttributeChecker);
        fComplexTypeTraverser = new XSDComplexTypeTraverser(this, fAttributeChecker);
        fElementTraverser = new XSDElementTraverser(this, fAttributeChecker);
        fGroupTraverser = new XSDGroupTraverser(this, fAttributeChecker);
        fKeyrefTraverser = new XSDKeyrefTraverser(this, fAttributeChecker);
        fNotationTraverser = new XSDNotationTraverser(this, fAttributeChecker);
        fSimpleTypeTraverser = new XSDSimpleTypeTraverser(this, fAttributeChecker);
        fUniqueOrKeyTraverser = new XSDUniqueOrKeyTraverser(this, fAttributeChecker);
        fWildCardTraverser = new XSDWildcardTraverser(this, fAttributeChecker);
    
private java.lang.Stringdoc2SystemId(org.w3c.dom.Element ele)

        String documentURI = null;
        /**
         * REVISIT: Casting until DOM Level 3 interfaces are available. -- mrglavas
         */
        if(ele.getOwnerDocument() instanceof org.apache.xerces.impl.xs.opti.SchemaDOM){
            documentURI = ((org.apache.xerces.impl.xs.opti.SchemaDOM) ele.getOwnerDocument()).getDocumentURI();
        }
        return documentURI != null ? documentURI : (String) fDoc2SystemId.get(ele);
    
public org.apache.xerces.impl.xs.util.SimpleLocatorelement2Locator(org.w3c.dom.Element e)
Extract location information from an Element node, and create a new SimpleLocator object from such information. Returning null means no information can be retrieved from the element.

    
                                    
        
        if (!( e instanceof ElementImpl))
            return null;
        
        SimpleLocator l = new SimpleLocator();
        return element2Locator(e, l) ? l : null;
    
public booleanelement2Locator(org.w3c.dom.Element e, org.apache.xerces.impl.xs.util.SimpleLocator l)
Extract location information from an Element node, store such information in the passed-in SimpleLocator object, then return true. Returning false means can't extract or store such information.

        if (l == null)
            return false;
        if (e instanceof ElementImpl) {
            ElementImpl ele = (ElementImpl)e;
            // get system id from document object
            Document doc = ele.getOwnerDocument();
            String sid = (String)fDoc2SystemId.get(DOMUtil.getRoot(doc));
            // line/column numbers are stored in the element node
            int line = ele.getLineNumber();
            int column = ele.getColumnNumber();
            l.setValues(sid, sid, line, column, ele.getCharacterOffset());
            return true;
        }
        return false;
    
private java.lang.StringemptyString2Null(java.lang.String ns)

        return ns == XMLSymbols.EMPTY_STRING ? null : ns;
    
voidfillInLocalElemInfo(org.w3c.dom.Element elmDecl, XSDocumentInfo schemaDoc, int allContextFlags, org.apache.xerces.xs.XSObject parent, org.apache.xerces.impl.xs.XSParticleDecl particle)

        
        // if the stack is full, increase the size
        if (fParticle.length == fLocalElemStackPos) {
            // increase size
            XSParticleDecl[] newStackP = new XSParticleDecl[fLocalElemStackPos+INC_STACK_SIZE];
            System.arraycopy(fParticle, 0, newStackP, 0, fLocalElemStackPos);
            fParticle = newStackP;
            Element[] newStackE = new Element[fLocalElemStackPos+INC_STACK_SIZE];
            System.arraycopy(fLocalElementDecl, 0, newStackE, 0, fLocalElemStackPos);
            fLocalElementDecl = newStackE;
            XSDocumentInfo [] newStackE_schema = new XSDocumentInfo[fLocalElemStackPos+INC_STACK_SIZE];
            System.arraycopy(fLocalElementDecl_schema, 0, newStackE_schema, 0, fLocalElemStackPos);
            fLocalElementDecl_schema = newStackE_schema;
            int[] newStackI = new int[fLocalElemStackPos+INC_STACK_SIZE];
            System.arraycopy(fAllContext, 0, newStackI, 0, fLocalElemStackPos);
            fAllContext = newStackI;
            XSObject[] newStackC = new XSObject[fLocalElemStackPos+INC_STACK_SIZE];
            System.arraycopy(fParent, 0, newStackC, 0, fLocalElemStackPos);
            fParent = newStackC;
            String [][] newStackN = new String [fLocalElemStackPos+INC_STACK_SIZE][];
            System.arraycopy(fLocalElemNamespaceContext, 0, newStackN, 0, fLocalElemStackPos);
            fLocalElemNamespaceContext = newStackN;
        }
        
        fParticle[fLocalElemStackPos] = particle;
        fLocalElementDecl[fLocalElemStackPos] = elmDecl;
        fLocalElementDecl_schema[fLocalElemStackPos] = schemaDoc;
        fAllContext[fLocalElemStackPos] = allContextFlags;
        fParent[fLocalElemStackPos] = parent;
        fLocalElemNamespaceContext[fLocalElemStackPos++] = schemaDoc.fNamespaceSupport.getEffectiveLocalContext();
    
protected org.apache.xerces.impl.xs.SchemaGrammarfindGrammar(org.apache.xerces.impl.xs.XSDDescription desc)
First try to find a grammar in the bucket, if failed, consult the grammar pool. If a grammar is found in the pool, then add it (and all imported ones) into the bucket.

        SchemaGrammar sg = fGrammarBucket.getGrammar(desc.getTargetNamespace());
        if (sg == null) {
            if (fGrammarPool != null) {
                sg = (SchemaGrammar)fGrammarPool.retrieveGrammar(desc);
                if (sg != null) {
                    // put this grammar into the bucket, along with grammars
                    // imported by it (directly or indirectly)
                    if (!fGrammarBucket.putGrammar(sg, true)) {
                        // REVISIT: a conflict between new grammar(s) and grammars
                        // in the bucket. What to do? A warning? An exception?
                        reportSchemaWarning("GrammarConflict", null, null);
                        sg = null;
                    }
                }
            }
        }
        return sg;
    
private java.lang.StringfindQName(java.lang.String name, XSDocumentInfo schemaDoc)

        SchemaNamespaceSupport currNSMap = schemaDoc.fNamespaceSupport;
        int colonPtr = name.indexOf(':");
        String prefix = XMLSymbols.EMPTY_STRING;
        if (colonPtr > 0)
            prefix = name.substring(0, colonPtr);
        String uri = currNSMap.getURI(fSymbolTable.addSymbol(prefix));
        String localpart = (colonPtr == 0)?name:name.substring(colonPtr+1);
        if (prefix == XMLSymbols.EMPTY_STRING && uri == null && schemaDoc.fIsChameleonSchema)
            uri = schemaDoc.fTargetNamespace;
        if (uri == null)
            return ","+localpart;
        return uri+","+localpart;
    
private XSDocumentInfofindXSDocumentForDecl(XSDocumentInfo currSchema, org.w3c.dom.Element decl, XSDocumentInfo decl_Doc)

        
        if (DEBUG_NODE_POOL) {
            System.out.println("DOCUMENT NS:"+ currSchema.fTargetNamespace+" hashcode:"+ ((Object)currSchema.fSchemaElement).hashCode());
        }
        Object temp = decl_Doc;
        if (temp == null) {
            // something went badly wrong; we don't know this doc?
            return null;
        }
        XSDocumentInfo declDocInfo = (XSDocumentInfo)temp;
        return declDocInfo;
        /*********
         Logic here is unnecessary after schema WG's recent decision to allow
         schema components from one document to refer to components of any other,
         so long as there's some include/import/redefine path amongst them.
         If they rver reverse this decision the code's right here though...  - neilg
         // now look in fDependencyMap to see if this is reachable
          if(((Vector)fDependencyMap.get(currSchema)).contains(declDocInfo)) {
          return declDocInfo;
          }
          // obviously the requesting doc didn't include, redefine or
           // import the one containing decl...
            return null;
            **********/
    
protected java.lang.ObjectgetGlobalDecl(XSDocumentInfo currSchema, int declType, org.apache.xerces.xni.QName declToTraverse, org.w3c.dom.Element elmNode)

    
    // since it is forbidden for traversers to talk to each other
    // directly (except wen a traverser encounters a local declaration),
    // this provides a generic means for a traverser to call
    // for the traversal of some declaration.  An XSDocumentInfo is
    // required because the XSDocumentInfo that the traverser is traversing
    // may bear no relation to the one the handler is operating on.
    // This method will:
    // 1.  See if a global definition matching declToTraverse exists;
    // 2. if so, determine if there is a path from currSchema to the
    // schema document where declToTraverse lives (i.e., do a lookup
    // in DependencyMap);
    // 3. depending on declType (which will be relevant to step 1 as
    // well), call the appropriate traverser with the appropriate
    // XSDocumentInfo object.
    // This method returns whatever the traverser it called returned;
    // this will be an Object of some kind
    // that lives in the Grammar.
       
             
             
              
        
        if (DEBUG_NODE_POOL) {
            System.out.println("TRAVERSE_GL: "+declToTraverse.toString());
        }
        // from the schema spec, all built-in types are present in all schemas,
        // so if the requested component is a type, and could be found in the
        // default schema grammar, we should return that type.
        // otherwise (since we would support user-defined schema grammar) we'll
        // use the normal way to get the decl
        if (declToTraverse.uri != null &&
                declToTraverse.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA) {
            if (declType == TYPEDECL_TYPE) {
                Object retObj = SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(declToTraverse.localpart);
                if (retObj != null)
                    return retObj;
            }
        }
        
        // now check whether this document can access the requsted namespace
        if (!currSchema.isAllowedNS(declToTraverse.uri)) {
            // cannot get to this schema from the one containing the requesting decl
            if (currSchema.needReportTNSError(declToTraverse.uri)) {
                String code = declToTraverse.uri == null ? "src-resolve.4.1" : "src-resolve.4.2";
                reportSchemaError(code, new Object[]{fDoc2SystemId.get(currSchema.fSchemaElement), declToTraverse.uri, declToTraverse.rawname}, elmNode);
            }
            return null;
        }
        
        // check whether there is grammar for the requested namespace
        SchemaGrammar sGrammar = fGrammarBucket.getGrammar(declToTraverse.uri);
        if (sGrammar == null) {
            if (needReportTNSError(declToTraverse.uri))
                reportSchemaError("src-resolve", new Object[]{declToTraverse.rawname, COMP_TYPE[declType]}, elmNode);
            return null;
        }
        
        // if there is such grammar, check whether the requested component is in the grammar
        Object retObj = null;
        switch (declType) {
        case ATTRIBUTE_TYPE :
            retObj = sGrammar.getGlobalAttributeDecl(declToTraverse.localpart);
            break;
        case ATTRIBUTEGROUP_TYPE :
            retObj = sGrammar.getGlobalAttributeGroupDecl(declToTraverse.localpart);
            break;
        case ELEMENT_TYPE :
            retObj = sGrammar.getGlobalElementDecl(declToTraverse.localpart);
            break;
        case GROUP_TYPE :
            retObj = sGrammar.getGlobalGroupDecl(declToTraverse.localpart);
            break;
        case IDENTITYCONSTRAINT_TYPE :
            retObj = sGrammar.getIDConstraintDecl(declToTraverse.localpart);
            break;
        case NOTATION_TYPE :
            retObj = sGrammar.getGlobalNotationDecl(declToTraverse.localpart);
            break;
        case TYPEDECL_TYPE :
            retObj = sGrammar.getGlobalTypeDecl(declToTraverse.localpart);
            break;
        }
        
        // if the component is parsed, return it
        if (retObj != null)
            return retObj;
        
        XSDocumentInfo schemaWithDecl = null;
        Element decl = null;
        XSDocumentInfo declDoc = null;
        
        // the component is not parsed, try to find a DOM element for it
        String declKey = declToTraverse.uri == null? ","+declToTraverse.localpart:
            declToTraverse.uri+","+declToTraverse.localpart;
        switch (declType) {
        case ATTRIBUTE_TYPE :
            decl = (Element)fUnparsedAttributeRegistry.get(declKey);
            declDoc = (XSDocumentInfo)fUnparsedAttributeRegistrySub.get(declKey);
            break;
        case ATTRIBUTEGROUP_TYPE :
            decl = (Element)fUnparsedAttributeGroupRegistry.get(declKey);
            declDoc = (XSDocumentInfo)fUnparsedAttributeGroupRegistrySub.get(declKey);
            break;
        case ELEMENT_TYPE :
            decl = (Element)fUnparsedElementRegistry.get(declKey);
            declDoc = (XSDocumentInfo)fUnparsedElementRegistrySub.get(declKey);
            break;
        case GROUP_TYPE :
            decl = (Element)fUnparsedGroupRegistry.get(declKey);
            declDoc = (XSDocumentInfo)fUnparsedGroupRegistrySub.get(declKey);
            break;
        case IDENTITYCONSTRAINT_TYPE :
            decl = (Element)fUnparsedIdentityConstraintRegistry.get(declKey);
            declDoc = (XSDocumentInfo)fUnparsedIdentityConstraintRegistrySub.get(declKey);
            break;
        case NOTATION_TYPE :
            decl = (Element)fUnparsedNotationRegistry.get(declKey);
            declDoc = (XSDocumentInfo)fUnparsedNotationRegistrySub.get(declKey);
            break;
        case TYPEDECL_TYPE :
            decl = (Element)fUnparsedTypeRegistry.get(declKey);
            declDoc = (XSDocumentInfo)fUnparsedTypeRegistrySub.get(declKey);
            break;
        default:
            reportSchemaError("Internal-Error", new Object [] {"XSDHandler asked to locate component of type " + declType + "; it does not recognize this type!"}, elmNode);
        }
        
        // no DOM element found, so the component can't be located
        if (decl == null) {
            reportSchemaError("src-resolve", new Object[]{declToTraverse.rawname, COMP_TYPE[declType]}, elmNode);
            return null;
        }
        
        // get the schema doc containing the component to be parsed
        // it should always return non-null value, but since null-checking
        // comes for free, let's be safe and check again
        schemaWithDecl = findXSDocumentForDecl(currSchema, decl, declDoc);
        if (schemaWithDecl == null) {
            // cannot get to this schema from the one containing the requesting decl
            String code = declToTraverse.uri == null ? "src-resolve.4.1" : "src-resolve.4.2";
            reportSchemaError(code, new Object[]{fDoc2SystemId.get(currSchema.fSchemaElement), declToTraverse.uri, declToTraverse.rawname}, elmNode);
            return null;
        }
        // a component is hidden, meaning either it's traversed, or being traversed.
        // but we didn't find it in the grammar, so it's the latter case, and
        // a circular reference. error!
        if (DOMUtil.isHidden(decl, fHiddenNodes)) {
            String code = CIRCULAR_CODES[declType];
            if (declType == TYPEDECL_TYPE) {
                if (SchemaSymbols.ELT_COMPLEXTYPE.equals(DOMUtil.getLocalName(decl)))
                    code = "ct-props-correct.3";
            }
            // decl must not be null if we're here...
            reportSchemaError(code, new Object [] {declToTraverse.prefix+":"+declToTraverse.localpart}, elmNode);
            return null;
        }
        
        DOMUtil.setHidden(decl, fHiddenNodes);
        SchemaNamespaceSupport nsSupport = null;
        // if the parent is <redefine> use the namespace delcs for it.
        Element parent = DOMUtil.getParent(decl);
        if (DOMUtil.getLocalName(parent).equals(SchemaSymbols.ELT_REDEFINE))
            nsSupport = (SchemaNamespaceSupport)fRedefine2NSSupport.get(parent);
        // back up the current SchemaNamespaceSupport, because we need to provide
        // a fresh one to the traverseGlobal methods.
        schemaWithDecl.backupNSSupport(nsSupport);
        
        // traverse the referenced global component
        switch (declType) {
        case ATTRIBUTE_TYPE :
            retObj = fAttributeTraverser.traverseGlobal(decl, schemaWithDecl, sGrammar);
            break;
        case ATTRIBUTEGROUP_TYPE :
            retObj = fAttributeGroupTraverser.traverseGlobal(decl, schemaWithDecl, sGrammar);
            break;
        case ELEMENT_TYPE :
            retObj = fElementTraverser.traverseGlobal(decl, schemaWithDecl, sGrammar);
            break;
        case GROUP_TYPE :
            retObj = fGroupTraverser.traverseGlobal(decl, schemaWithDecl, sGrammar);
            break;
        case IDENTITYCONSTRAINT_TYPE :
            // identity constraints should have been parsed already...
            // we should never get here
            retObj = null;
            break;
        case NOTATION_TYPE :
            retObj = fNotationTraverser.traverse(decl, schemaWithDecl, sGrammar);
            break;
        case TYPEDECL_TYPE :
            if (DOMUtil.getLocalName(decl).equals(SchemaSymbols.ELT_COMPLEXTYPE))
                retObj = fComplexTypeTraverser.traverseGlobal(decl, schemaWithDecl, sGrammar);
            else
                retObj = fSimpleTypeTraverser.traverseGlobal(decl, schemaWithDecl, sGrammar);
        }
        
        // restore the previous SchemaNamespaceSupport, so that the caller can get
        // proper namespace binding.
        schemaWithDecl.restoreNSSupport();
        
        return retObj;
    
org.apache.xerces.impl.xs.SchemaGrammargetGrammar(java.lang.String tns)
Pull the grammar out of the bucket simply using its TNS as a key

        return fGrammarBucket.getGrammar(tns);
    
java.lang.ObjectgetGrpOrAttrGrpRedefinedByRestriction(int type, org.apache.xerces.xni.QName name, XSDocumentInfo currSchema, org.w3c.dom.Element elmNode)

        String realName = name.uri != null?name.uri+","+name.localpart:
            ","+name.localpart;
        String nameToFind = null;
        switch (type) {
        case ATTRIBUTEGROUP_TYPE:
            nameToFind = (String)fRedefinedRestrictedAttributeGroupRegistry.get(realName);
            break;
        case GROUP_TYPE:
            nameToFind = (String)fRedefinedRestrictedGroupRegistry.get(realName);
            break;
        default:
            return null;
        }
        if (nameToFind == null) return null;
        int commaPos = nameToFind.indexOf(",");
        QName qNameToFind = new QName(XMLSymbols.EMPTY_STRING, nameToFind.substring(commaPos+1),
                nameToFind.substring(commaPos), (commaPos == 0)? null : nameToFind.substring(0, commaPos));
        Object retObj = getGlobalDecl(currSchema, type, qNameToFind, elmNode);
        if(retObj == null) {
            switch (type) {
            case ATTRIBUTEGROUP_TYPE:
                reportSchemaError("src-redefine.7.2.1", new Object []{name.localpart}, elmNode);
                break;
            case GROUP_TYPE:
                reportSchemaError("src-redefine.6.2.1", new Object []{name.localpart}, elmNode);
                break;
            }
            return null;
        }
        return retObj;
    
protected java.util.HashtablegetIDRegistry()

        return fUnparsedIdentityConstraintRegistry;
    
protected java.util.HashtablegetIDRegistry_sub()

        return fUnparsedIdentityConstraintRegistrySub;
    
private org.w3c.dom.ElementgetSchemaDocument(java.lang.String schemaNamespace, org.apache.xerces.xni.parser.XMLInputSource schemaSource, boolean mustResolve, short referType, org.w3c.dom.Element referElement)
getSchemaDocument method uses XMLInputSource to parse a schema document.

param
schemaNamespace
param
schemaSource
param
mustResolve
param
referType
param
referElement
return
A schema Element.

        
        boolean hasInput = true;
        // contents of this method will depend on the system we adopt for entity resolution--i.e., XMLEntityHandler, EntityHandler, etc.
        Element schemaElement = null;
        try {
            // when the system id and byte stream and character stream
            // of the input source are all null, it's
            // impossible to find the schema document. so we skip in
            // this case. otherwise we'll receive some NPE or
            // file not found errors. but schemaHint=="" is perfectly
            // legal for import.
            if (schemaSource != null &&
                    (schemaSource.getSystemId() != null ||
                            schemaSource.getByteStream() != null ||
                            schemaSource.getCharacterStream() != null)) {
                
                // When the system id of the input source is used, first try to
                // expand it, and check whether the same document has been
                // parsed before. If so, return the document corresponding to
                // that system id.
                XSDKey key = null;
                String schemaId = null;
                if (referType != XSDDescription.CONTEXT_PREPARSE){
                    schemaId = XMLEntityManager.expandSystemId(schemaSource.getSystemId(), schemaSource.getBaseSystemId(), false);
                    key = new XSDKey(schemaId, referType, schemaNamespace);
                    if((schemaElement = (Element)fTraversed.get(key)) != null) {
                        fLastSchemaWasDuplicate = true;
                        return schemaElement;
                    }
                }
                
                fSchemaParser.parse(schemaSource);
                schemaElement = fSchemaParser.getDocument2() == null ? null: DOMUtil.getRoot(fSchemaParser.getDocument2());
                
                // now we need to store the mapping information from system id
                // to the document. also from the document to the system id.
                if (key != null)
                    fTraversed.put(key, schemaElement );
                if (schemaId != null)
                    fDoc2SystemId.put(schemaElement, schemaId );
                fLastSchemaWasDuplicate = false;
                return schemaElement;
            }
            else {
                hasInput = false;
            }
        }
        catch (IOException ex) {
        }
        
        // either an error occured (exception), or empty input source was
        // returned, we need to report an error or a warning
        if (mustResolve) {
            if (hasInput) {
                reportSchemaError("schema_reference.4",
                        new Object[]{schemaSource.getSystemId()},
                        referElement);
            }
            else {
                reportSchemaError("schema_reference.4",
                        new Object[]{schemaSource == null ? "" : schemaSource.getSystemId()},
                        referElement);
            }
        }
        else if (hasInput) {
            reportSchemaWarning("schema_reference.4",
                    new Object[]{schemaSource.getSystemId()},
                    referElement);
        }
        
        fLastSchemaWasDuplicate = false;
        return null;
    
private booleanisExistingGrammar(org.apache.xerces.impl.xs.XSDDescription desc)

        SchemaGrammar sg = fGrammarBucket.getGrammar(desc.getTargetNamespace());
        if(sg == null) {
            return findGrammar(desc) != null;
        }
        else {
            try {
                return sg.getDocumentLocations().contains(XMLEntityManager.expandSystemId(desc.getLiteralSystemId(), desc.getBaseSystemId(), false));
            } catch (MalformedURIException e) {
                return false;
            }
        }
    
private final booleanneedReportTNSError(java.lang.String uri)

    // check whether we need to report an error against the given uri.
    // if we have reported an error, then we don't need to report again;
    // otherwise we reported the error, and remember this fact.
         
        if (fReportedTNS == null)
            fReportedTNS = new Vector();
        else if (fReportedTNS.contains(uri))
            return false;
        fReportedTNS.addElement(uri);
        return true;
    
private booleannonAnnotationContent(org.w3c.dom.Element elem)

        for(Element child = DOMUtil.getFirstChildElement(elem); child != null; child = DOMUtil.getNextSiblingElement(child)) {
            if(!(DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION))) return true;
        }
        return false;
    
private java.lang.Stringnull2EmptyString(java.lang.String ns)

    
    // convenience methods
        
        return ns == null ? XMLSymbols.EMPTY_STRING : ns;
    
public org.apache.xerces.impl.xs.SchemaGrammarparseSchema(org.apache.xerces.xni.parser.XMLInputSource is, org.apache.xerces.impl.xs.XSDDescription desc, java.util.Hashtable locationPairs)
This method initiates the parse of a schema. It will likely be called from the Validator and it will make the resulting grammar available; it returns a reference to this object just in case. A reset(XMLComponentManager) must be called before this methods is called.

param
is
param
desc
param
locationPairs
return
the SchemaGrammar
throws
IOException

        fLocationPairs = locationPairs;
        fSchemaParser.resetNodePool();   
        SchemaGrammar grammar = null;
        String schemaNamespace  = null;
        short referType = desc.getContextType();
        // if loading using JAXP schemaSource property, or using grammar caching loadGrammar
        // the desc.targetNamespace is always null.
        // Therefore we should not attempt to find out if
        // the schema is already in the bucket, since in the case we have
        // no namespace schema in the bucket, findGrammar will always return the
        // no namespace schema.
        if (referType != XSDDescription.CONTEXT_PREPARSE){
            // first try to find it in the bucket/pool, return if one is found
            if(fHonourAllSchemaLocations && referType == XSDDescription.CONTEXT_IMPORT && isExistingGrammar(desc)) {
                grammar = fGrammarBucket.getGrammar(desc.getTargetNamespace());
            }
            else {
                grammar = findGrammar(desc);
            }
            if (grammar != null)
                return grammar;
            schemaNamespace = desc.getTargetNamespace();
            // handle empty string URI as null
            if (schemaNamespace != null) {
                schemaNamespace = fSymbolTable.addSymbol(schemaNamespace);
            }
        }
        
        // before parsing a schema, need to clear registries associated with
        // parsing schemas
        prepareForParse();       
        
        Document schemaRootDoc = null;
        Element schemaRoot = null;
        // first phase:  construct trees.
        if (is instanceof DOMInputSource) {
            //clean up the field fHiddenNodes, used for DOMInputSource
            fHiddenNodes.clear();
            Node domNode = ((DOMInputSource)is).getNode();
            
            if (domNode instanceof Document) {
                schemaRootDoc = (Document)domNode;
                schemaRoot = DOMUtil.getRoot(schemaRootDoc);
            }
            else if (domNode instanceof Element) {
                schemaRoot = (Element)domNode;
            }
            else {
                return null;
            }
        } // DOMInputSource
        else if (is instanceof SAXInputSource) {
            XMLReader parser = ((SAXInputSource)is).getXMLReader();
            InputSource inputSource = ((SAXInputSource)is).getInputSource(); 
            boolean namespacePrefixes = false;
            if (parser != null) {
                try {
                    namespacePrefixes = parser.getFeature(NAMESPACE_PREFIXES);
                }
                catch (SAXException se) {}
            }
            else {
                try {
                    parser = XMLReaderFactory.createXMLReader();
                }
                // If something went wrong with the factory
                // just use our own SAX parser.
                catch (SAXException se) {
                    parser = new SAXParser();
                }
                try {
                    parser.setFeature(NAMESPACE_PREFIXES, true);
                    namespacePrefixes = true;
                }
                catch (SAXException se) {}
            }
            // If XML names and Namespace URIs are already internalized we
            // can avoid running them through the SymbolTable.
            boolean stringsInternalized = false;
            try {
                stringsInternalized = parser.getFeature(STRING_INTERNING);
            }
            catch (SAXException exc) {
                // The feature isn't recognized or getting it is not supported.
                // In either case, assume that strings are not internalized.
            }
            if (fXSContentHandler == null) {
                fXSContentHandler = new SchemaContentHandler();
            }
            fXSContentHandler.reset(fSchemaParser, fSymbolTable, 
                    namespacePrefixes, stringsInternalized);
            parser.setContentHandler(fXSContentHandler);
            parser.setErrorHandler(fErrorReporter.getSAXErrorHandler());
        	try {
            	parser.parse(inputSource);	
        	}
        	catch (SAXException se) {
        		return null;
        	}
        	schemaRootDoc = fXSContentHandler.getDocument();
            if (schemaRootDoc == null) {
                // something went wrong right off the hop
                return null;
            }
        	schemaRoot = DOMUtil.getRoot(schemaRootDoc);          
        }            
        else {
        	schemaRoot = getSchemaDocument(schemaNamespace, is,
                  referType == XSDDescription.CONTEXT_PREPARSE,
                  referType, null);
             
        }//is instanceof XMLInputSource

        if(schemaRoot == null){
            // something went wrong right off the hop
            return null;
        }      
        
        if ( referType == XSDDescription.CONTEXT_PREPARSE) {
        	Element schemaElem = schemaRoot;
            schemaNamespace = DOMUtil.getAttrValue(schemaElem, SchemaSymbols.ATT_TARGETNAMESPACE);
            if(schemaNamespace != null && schemaNamespace.length() > 0) {
                // Since now we've discovered a namespace, we need to update xsd key
                // and store this schema in traversed schemas bucket
                schemaNamespace = fSymbolTable.addSymbol(schemaNamespace);
                desc.setTargetNamespace(schemaNamespace);
            }
            else {
                schemaNamespace = null;
            }
            grammar = findGrammar(desc);
            if (grammar != null)
                return grammar;
            String schemaId = XMLEntityManager.expandSystemId(is.getSystemId(), is.getBaseSystemId(), false);
            XSDKey key = new XSDKey(schemaId, referType, schemaNamespace);
            fTraversed.put(key, schemaRoot);
            if (schemaId != null) {
            	fDoc2SystemId.put(schemaRoot, schemaId);
            }
        }
        
        // before constructing trees and traversing a schema, need to reset
        // all traversers and clear all registries
        prepareForTraverse();
        
        fRoot = constructTrees(schemaRoot, is.getSystemId(), desc);
        if (fRoot == null) {
            return null;
        }
        
        // second phase:  fill global registries.
        buildGlobalNameRegistries();
        
        // third phase:  call traversers
        ArrayList annotationInfo = fValidateAnnotations ? new ArrayList() : null;
        traverseSchemas(annotationInfo);
        
        // fourth phase: handle local element decls
        traverseLocalElements();
        
        // fifth phase:  handle Keyrefs
        resolveKeyRefs();
        
        // sixth phase:  validate attribute of non-schema namespaces
        // REVISIT: skip this for now. we really don't want to do it.
        //fAttributeChecker.checkNonSchemaAttributes(fGrammarBucket);
        
        // seventh phase:  store imported grammars
        // for all grammars with <import>s
        for (int i = fAllTNSs.size() - 1; i >= 0; i--) {
            // get its target namespace
            String tns = (String)fAllTNSs.elementAt(i);
            // get all namespaces it imports
            Vector ins = (Vector)fImportMap.get(tns);
            // get the grammar
            SchemaGrammar sg = fGrammarBucket.getGrammar(emptyString2Null(tns));
            if (sg == null)
                continue;
            SchemaGrammar isg;
            // for imported namespace
            int count = 0;
            for (int j = 0; j < ins.size(); j++) {
                // get imported grammar
                isg = fGrammarBucket.getGrammar((String)ins.elementAt(j));
                // reuse the same vector
                if (isg != null)
                    ins.setElementAt(isg, count++);
            }
            ins.setSize(count);
            // set the imported grammars
            sg.setImportedGrammars(ins);
        }
        
        /** validate annotations **/
        if (fValidateAnnotations && annotationInfo.size() > 0) {
            validateAnnotations(annotationInfo);
        }

        // and return.
        return fGrammarBucket.getGrammar(fRoot.fTargetNamespace);
    
voidprepareForParse()

        fTraversed.clear();
        fDoc2SystemId.clear();
        fHiddenNodes.clear();
        fLastSchemaWasDuplicate = false;
    
voidprepareForTraverse()

        fUnparsedAttributeRegistry.clear();
        fUnparsedAttributeGroupRegistry.clear();
        fUnparsedElementRegistry.clear();
        fUnparsedGroupRegistry.clear();
        fUnparsedIdentityConstraintRegistry.clear();
        fUnparsedNotationRegistry.clear();
        fUnparsedTypeRegistry.clear();
        
        fUnparsedAttributeRegistrySub.clear();
        fUnparsedAttributeGroupRegistrySub.clear();
        fUnparsedElementRegistrySub.clear();
        fUnparsedGroupRegistrySub.clear();
        fUnparsedIdentityConstraintRegistrySub.clear();
        fUnparsedNotationRegistrySub.clear();
        fUnparsedTypeRegistrySub.clear();
        
        fXSDocumentInfoRegistry.clear();
        fDependencyMap.clear();
        fDoc2XSDocumentMap.clear();
        fRedefine2XSDMap.clear();
        fRedefine2NSSupport.clear();
        fAllTNSs.removeAllElements();
        fImportMap.clear();
        fRoot = null;
        
        // clear local element stack
        for (int i = 0; i < fLocalElemStackPos; i++) {
            fParticle[i] = null;
            fLocalElementDecl[i] = null;
            fLocalElementDecl_schema[i] = null;
            fLocalElemNamespaceContext[i] = null;
        }
        fLocalElemStackPos = 0;
        
        // and do same for keyrefs.
        for (int i = 0; i < fKeyrefStackPos; i++) {
            fKeyrefs[i] = null;
            fKeyrefElems[i] = null;
            fKeyrefNamespaceContext[i] = null;
            fKeyrefsMapXSDocumentInfo[i] = null;
        }
        fKeyrefStackPos = 0;
        
        // create traversers if necessary
        if (fAttributeChecker == null) {
            createTraversers();
        }
        
        // reset traversers
        fAttributeChecker.reset(fSymbolTable);
        fAttributeGroupTraverser.reset(fSymbolTable, fValidateAnnotations);
        fAttributeTraverser.reset(fSymbolTable, fValidateAnnotations);
        fComplexTypeTraverser.reset(fSymbolTable, fValidateAnnotations);
        fElementTraverser.reset(fSymbolTable, fValidateAnnotations);
        fGroupTraverser.reset(fSymbolTable, fValidateAnnotations);
        fKeyrefTraverser.reset(fSymbolTable, fValidateAnnotations);
        fNotationTraverser.reset(fSymbolTable, fValidateAnnotations);
        fSimpleTypeTraverser.reset(fSymbolTable, fValidateAnnotations);
        fUniqueOrKeyTraverser.reset(fSymbolTable, fValidateAnnotations);
        fWildCardTraverser.reset(fSymbolTable, fValidateAnnotations);
        
        fRedefinedRestrictedAttributeGroupRegistry.clear();
        fRedefinedRestrictedGroupRegistry.clear();
    
private booleanremoveParticle(org.apache.xerces.impl.xs.XSModelGroupImpl group, org.apache.xerces.impl.xs.XSParticleDecl particle)

        XSParticleDecl member;
        for (int i = 0; i < group.fParticleCount; i++) {
            member = group.fParticles[i];
            if (member == particle) {
                for (int j = i; j < group.fParticleCount-1; j++)
                    group.fParticles[j] = group.fParticles[j+1];
                group.fParticleCount--;
                return true;
            }
            if (member.fType == XSParticleDecl.PARTICLE_MODELGROUP) {
                if (removeParticle((XSModelGroupImpl)member.fValue, particle))
                    return true;
            }
        }
        return false;
    
private voidrenameRedefiningComponents(XSDocumentInfo currSchema, org.w3c.dom.Element child, java.lang.String componentType, java.lang.String oldName, java.lang.String newName)

        if (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
            Element grandKid = DOMUtil.getFirstChildElement(child);
            if (grandKid == null) {
                reportSchemaError("src-redefine.5.a.a", null, child);
            }
            else {
                String grandKidName = DOMUtil.getLocalName(grandKid);
                if (grandKidName.equals(SchemaSymbols.ELT_ANNOTATION)) {
                    grandKid = DOMUtil.getNextSiblingElement(grandKid);
                }
                if (grandKid == null) {
                    reportSchemaError("src-redefine.5.a.a", null, child);
                }
                else {
                    grandKidName = DOMUtil.getLocalName(grandKid);
                    if (!grandKidName.equals(SchemaSymbols.ELT_RESTRICTION)) {
                        reportSchemaError("src-redefine.5.a.b", new Object[]{grandKidName}, child);
                    }
                    else {
                        Object[] attrs = fAttributeChecker.checkAttributes(grandKid, false, currSchema);
                        QName derivedBase = (QName)attrs[XSAttributeChecker.ATTIDX_BASE];
                        if (derivedBase == null ||
                                derivedBase.uri != currSchema.fTargetNamespace ||
                                !derivedBase.localpart.equals(oldName)) {
                            reportSchemaError("src-redefine.5.a.c",
                                    new Object[]{grandKidName,
                                    (currSchema.fTargetNamespace==null?"":currSchema.fTargetNamespace)
                                    + "," + oldName},
                                    child);
                        }
                        else {
                            // now we have to do the renaming...
                            if (derivedBase.prefix != null && derivedBase.prefix.length() > 0)
                                grandKid.setAttribute( SchemaSymbols.ATT_BASE,
                                        derivedBase.prefix + ":" + newName );
                            else
                                grandKid.setAttribute( SchemaSymbols.ATT_BASE, newName );
                            //                            return true;
                        }
                        fAttributeChecker.returnAttrArray(attrs, currSchema);
                    }
                }
            }
        }
        else if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
            Element grandKid = DOMUtil.getFirstChildElement(child);
            if (grandKid == null) {
                reportSchemaError("src-redefine.5.b.a", null, child);
            }
            else {
                if (DOMUtil.getLocalName(grandKid).equals(SchemaSymbols.ELT_ANNOTATION)) {
                    grandKid = DOMUtil.getNextSiblingElement(grandKid);
                }
                if (grandKid == null) {
                    reportSchemaError("src-redefine.5.b.a", null, child);
                }
                else {
                    // have to go one more level down; let another pass worry whether complexType is valid.
                    Element greatGrandKid = DOMUtil.getFirstChildElement(grandKid);
                    if (greatGrandKid == null) {
                        reportSchemaError("src-redefine.5.b.b", null, grandKid);
                    }
                    else {
                        String greatGrandKidName = DOMUtil.getLocalName(greatGrandKid);
                        if (greatGrandKidName.equals(SchemaSymbols.ELT_ANNOTATION)) {
                            greatGrandKid = DOMUtil.getNextSiblingElement(greatGrandKid);
                        }
                        if (greatGrandKid == null) {
                            reportSchemaError("src-redefine.5.b.b", null, grandKid);
                        }
                        else {
                            greatGrandKidName = DOMUtil.getLocalName(greatGrandKid);
                            if (!greatGrandKidName.equals(SchemaSymbols.ELT_RESTRICTION) &&
                                    !greatGrandKidName.equals(SchemaSymbols.ELT_EXTENSION)) {
                                reportSchemaError("src-redefine.5.b.c", new Object[]{greatGrandKidName}, greatGrandKid);
                            }
                            else {
                                Object[] attrs = fAttributeChecker.checkAttributes(greatGrandKid, false, currSchema);
                                QName derivedBase = (QName)attrs[XSAttributeChecker.ATTIDX_BASE];
                                if (derivedBase == null ||
                                        derivedBase.uri != currSchema.fTargetNamespace ||
                                        !derivedBase.localpart.equals(oldName)) {
                                    reportSchemaError("src-redefine.5.b.d",
                                            new Object[]{greatGrandKidName,
                                            (currSchema.fTargetNamespace==null?"":currSchema.fTargetNamespace)
                                            + "," + oldName},
                                            greatGrandKid);
                                }
                                else {
                                    // now we have to do the renaming...
                                    if (derivedBase.prefix != null && derivedBase.prefix.length() > 0)
                                        greatGrandKid.setAttribute( SchemaSymbols.ATT_BASE,
                                                derivedBase.prefix + ":" + newName );
                                    else
                                        greatGrandKid.setAttribute( SchemaSymbols.ATT_BASE,
                                                newName );
                                    //                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }
        else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
            String processedBaseName = (currSchema.fTargetNamespace == null)?
                    ","+oldName:currSchema.fTargetNamespace+","+oldName;
            int attGroupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
            if (attGroupRefsCount > 1) {
                reportSchemaError("src-redefine.7.1", new Object []{new Integer(attGroupRefsCount)}, child);
            }
            else if (attGroupRefsCount == 1) {
                //                return true;
            }
            else
                if (currSchema.fTargetNamespace == null)
                    fRedefinedRestrictedAttributeGroupRegistry.put(processedBaseName, ","+newName);
                else
                    fRedefinedRestrictedAttributeGroupRegistry.put(processedBaseName, currSchema.fTargetNamespace+","+newName);
        }
        else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
            String processedBaseName = (currSchema.fTargetNamespace == null)?
                    ","+oldName:currSchema.fTargetNamespace+","+oldName;
            int groupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
            if (groupRefsCount > 1) {
                reportSchemaError("src-redefine.6.1.1", new Object []{new Integer(groupRefsCount)}, child);
            }
            else if (groupRefsCount == 1) {
                //                return true;
            }
            else {
                if (currSchema.fTargetNamespace == null)
                    fRedefinedRestrictedGroupRegistry.put(processedBaseName, ","+newName);
                else
                    fRedefinedRestrictedGroupRegistry.put(processedBaseName, currSchema.fTargetNamespace+","+newName);
            }
        }
        else {
            reportSchemaError("Internal-Error", new Object [] {"could not handle this particular <redefine>; please submit your schemas and instance document in a bug report!"}, child);
        }
        // if we get here then we must have reported an error and failed somewhere...
        //        return false;
    
voidreportSchemaError(java.lang.String key, java.lang.Object[] args, org.w3c.dom.Element ele)

        if (element2Locator(ele, xl)) {
            fErrorReporter.reportError(xl, XSMessageFormatter.SCHEMA_DOMAIN,
                    key, args, XMLErrorReporter.SEVERITY_ERROR);
        }
        else {
            fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
                    key, args, XMLErrorReporter.SEVERITY_ERROR);
        }
    
voidreportSchemaWarning(java.lang.String key, java.lang.Object[] args, org.w3c.dom.Element ele)

        if (element2Locator(ele, xl)) {
            fErrorReporter.reportError(xl, XSMessageFormatter.SCHEMA_DOMAIN,
                    key, args, XMLErrorReporter.SEVERITY_WARNING);
        }
        else {
            fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
                    key, args, XMLErrorReporter.SEVERITY_WARNING);
        }
    
public voidreset(org.apache.xerces.xni.parser.XMLComponentManager componentManager)

        
        // set symbol table
        fSymbolTable = (SymbolTable) componentManager.getProperty(SYMBOL_TABLE);
        
        //set entity resolver
        fEntityResolver = (XMLEntityResolver) componentManager.getProperty(ENTITY_MANAGER);
        XMLEntityResolver er = (XMLEntityResolver)componentManager.getProperty(ENTITY_RESOLVER);
        if (er != null)
            fSchemaParser.setEntityResolver(er);
        
        // set error reporter
        fErrorReporter =
            (XMLErrorReporter) componentManager.getProperty(ERROR_REPORTER);
        try {
            XMLErrorHandler currErrorHandler = fErrorReporter.getErrorHandler();
            // Setting a parser property can be much more expensive
            // than checking its value.  Don't set the ERROR_HANDLER
            // property unless it's actually changed.
            if (currErrorHandler != fSchemaParser.getProperty(ERROR_HANDLER)) {
                fSchemaParser.setProperty(ERROR_HANDLER, (currErrorHandler != null) ? currErrorHandler : new DefaultErrorHandler());
                if (fAnnotationValidator != null) {
                    fAnnotationValidator.setProperty(ERROR_HANDLER, (currErrorHandler != null) ? currErrorHandler : new DefaultErrorHandler());
            	}
            }
        } catch (XMLConfigurationException e) {
        }
        
        try {
            fValidateAnnotations = componentManager.getFeature(VALIDATE_ANNOTATIONS);
        } catch (XMLConfigurationException e) {
            fValidateAnnotations = false;
        }
        
        try {
            fHonourAllSchemaLocations = componentManager.getFeature(HONOUR_ALL_SCHEMALOCATIONS);
        } catch (XMLConfigurationException e) {
            fHonourAllSchemaLocations = false;
        }

        try {
            fSchemaParser.setFeature(
                    CONTINUE_AFTER_FATAL_ERROR,
                    fErrorReporter.getFeature(CONTINUE_AFTER_FATAL_ERROR));
        } catch (XMLConfigurationException e) {
        }
        
        try {
            fSchemaParser.setFeature(
                    ALLOW_JAVA_ENCODINGS,
                    componentManager.getFeature(ALLOW_JAVA_ENCODINGS));
        } catch (XMLConfigurationException e) {
        }
        try {
            fSchemaParser.setFeature(
                    STANDARD_URI_CONFORMANT_FEATURE,
                    componentManager.getFeature(STANDARD_URI_CONFORMANT_FEATURE));
        } catch (XMLConfigurationException e) {
        }
        
        try {
            fGrammarPool =
                (XMLGrammarPool) componentManager.getProperty(XMLGRAMMAR_POOL);
        } catch (XMLConfigurationException e) {
            fGrammarPool = null;
        }
        // security features
        try {
            fSchemaParser.setFeature( DISALLOW_DOCTYPE,
                    componentManager.getFeature(DISALLOW_DOCTYPE));
        } catch (XMLConfigurationException e) {
        }
        try {
            Object security = componentManager.getProperty(SECURITY_MANAGER);
            if (security != null){
                fSchemaParser.setProperty(SECURITY_MANAGER, security);
            }
        } catch (XMLConfigurationException e) {
        }
        
    
protected voidresolveKeyRefs()

        for (int i=0; i<fKeyrefStackPos; i++) {
            XSDocumentInfo keyrefSchemaDoc = fKeyrefsMapXSDocumentInfo[i];
            keyrefSchemaDoc.fNamespaceSupport.makeGlobal();
            keyrefSchemaDoc.fNamespaceSupport.setEffectiveContext( fKeyrefNamespaceContext[i] );
            SchemaGrammar keyrefGrammar = fGrammarBucket.getGrammar(keyrefSchemaDoc.fTargetNamespace);
            // need to set <keyref> to hidden before traversing it,
            // because it has global scope
           	DOMUtil.setHidden(fKeyrefs[i], fHiddenNodes);
            fKeyrefTraverser.traverse(fKeyrefs[i], fKeyrefElems[i], keyrefSchemaDoc, keyrefGrammar);
        }
    
private org.w3c.dom.ElementresolveSchema(org.apache.xerces.impl.xs.XSDDescription desc, boolean mustResolve, org.w3c.dom.Element referElement, boolean usePairs)
resolveSchema method is responsible for resolving location of the schema (using XMLEntityResolver), and if it was succefully resolved getting the schema Document.

param
desc
param
mustResolve
param
referElement
return
A schema Element or null.

        XMLInputSource schemaSource = null;
        try {
            Hashtable pairs = usePairs ? fLocationPairs : EMPTY_TABLE;
            schemaSource = XMLSchemaLoader.resolveDocument(desc, pairs, fEntityResolver);
        }
        catch (IOException ex) {
            if (mustResolve) {
                reportSchemaError("schema_reference.4",
                        new Object[]{desc.getLocationHints()[0]},
                        referElement);
            }
            else {
                reportSchemaWarning("schema_reference.4",
                        new Object[]{desc.getLocationHints()[0]},
                        referElement);
            }
        }
        if (schemaSource instanceof DOMInputSource) {
            fHiddenNodes.clear();
            Node node = ((DOMInputSource)schemaSource).getNode();
 
            if (node instanceof Document) {
                return DOMUtil.getRoot((Document) node);
            }
            else if (node instanceof Element) {
                return (Element) node;
            }
            else {
                return null;
            }
        } // DOMInputSource
        else if (schemaSource instanceof SAXInputSource) {
            XMLReader parser = ((SAXInputSource)schemaSource).getXMLReader();
            InputSource inputSource = ((SAXInputSource)schemaSource).getInputSource(); 
            boolean namespacePrefixes = false;
            if (parser != null) {
                try {
                    namespacePrefixes = parser.getFeature(NAMESPACE_PREFIXES);
                }
                catch (SAXException se) {}
            }
            else {
                try {
                    parser = XMLReaderFactory.createXMLReader();
                }
                // If something went wrong with the factory
                // just use our own SAX parser.
                catch (SAXException se) {
                    parser = new SAXParser();
                }
                try {
                    parser.setFeature(NAMESPACE_PREFIXES, true);
                    namespacePrefixes = true;
                }
                catch (SAXException se) {}
            }
            // If XML names and Namespace URIs are already internalized we
            // can avoid running them through the SymbolTable.
            boolean stringsInternalized = false;
            try {
                stringsInternalized = parser.getFeature(STRING_INTERNING);
            }
            catch (SAXException exc) {
                // The feature isn't recognized or getting it is not supported.
                // In either case, assume that strings are not internalized.
            }
            if (fXSContentHandler == null) {
                fXSContentHandler = new SchemaContentHandler();
            }
            fXSContentHandler.reset(fSchemaParser, fSymbolTable, 
                    namespacePrefixes, stringsInternalized);
            parser.setContentHandler(fXSContentHandler);
            parser.setErrorHandler(fErrorReporter.getSAXErrorHandler());
            try {
                parser.parse(inputSource);  
            }
            catch (SAXException se) {
                return null;
            }
            catch (IOException ioe) {
                return null;
            }
            Document root = fXSContentHandler.getDocument();
            if (root == null) {
                // something went wrong right off the hop
                return null;
            }
            return DOMUtil.getRoot(root);          
        }       
        return getSchemaDocument(desc.getTargetNamespace(), schemaSource, mustResolve, desc.getContextType(), referElement);
    
public voidsetDeclPool(org.apache.xerces.impl.xs.XSDeclarationPool declPool)

        fDeclPool = declPool;
    
public voidsetGenerateSyntheticAnnotations(boolean state)

param
state

        fSchemaParser.setFeature(GENERATE_SYNTHETIC_ANNOTATIONS, state);
    
private voidsetSchemasVisible(XSDocumentInfo startSchema)

        if (DOMUtil.isHidden(startSchema.fSchemaElement, fHiddenNodes)) {
            // make it visible
            DOMUtil.setVisible(startSchema.fSchemaElement, fHiddenNodes);           
            Vector dependingSchemas = (Vector)fDependencyMap.get(startSchema);
            for (int i = 0; i < dependingSchemas.size(); i++) {
                setSchemasVisible((XSDocumentInfo)dependingSchemas.elementAt(i));
            }
        }
        // if it's visible already than so must be its children
    
protected voidstoreKeyRef(org.w3c.dom.Element keyrefToStore, XSDocumentInfo schemaDoc, org.apache.xerces.impl.xs.XSElementDecl currElemDecl)

        String keyrefName = DOMUtil.getAttrValue(keyrefToStore, SchemaSymbols.ATT_NAME);
        if (keyrefName.length() != 0) {
            String keyrefQName = schemaDoc.fTargetNamespace == null?
                    "," + keyrefName: schemaDoc.fTargetNamespace+","+keyrefName;
            checkForDuplicateNames(keyrefQName, fUnparsedIdentityConstraintRegistry, fUnparsedIdentityConstraintRegistrySub, keyrefToStore, schemaDoc);
        }
        // now set up all the registries we'll need...
        
        // check array sizes
        if (fKeyrefStackPos == fKeyrefs.length) {
            Element [] elemArray = new Element [fKeyrefStackPos + INC_KEYREF_STACK_AMOUNT];
            System.arraycopy(fKeyrefs, 0, elemArray, 0, fKeyrefStackPos);
            fKeyrefs = elemArray;
            XSElementDecl [] declArray = new XSElementDecl [fKeyrefStackPos + INC_KEYREF_STACK_AMOUNT];
            System.arraycopy(fKeyrefElems, 0, declArray, 0, fKeyrefStackPos);
            fKeyrefElems = declArray;
            String[][] stringArray = new String [fKeyrefStackPos + INC_KEYREF_STACK_AMOUNT][];
            System.arraycopy(fKeyrefNamespaceContext, 0, stringArray, 0, fKeyrefStackPos);
            fKeyrefNamespaceContext = stringArray;
            
            XSDocumentInfo [] xsDocumentInfo = new XSDocumentInfo [fKeyrefStackPos + INC_KEYREF_STACK_AMOUNT];
            System.arraycopy(fKeyrefsMapXSDocumentInfo, 0, xsDocumentInfo, 0, fKeyrefStackPos);
            fKeyrefsMapXSDocumentInfo = xsDocumentInfo;
            
        }
        fKeyrefs[fKeyrefStackPos] = keyrefToStore;
        fKeyrefElems[fKeyrefStackPos] = currElemDecl;
        fKeyrefNamespaceContext[fKeyrefStackPos] = schemaDoc.fNamespaceSupport.getEffectiveLocalContext();
        
        fKeyrefsMapXSDocumentInfo[fKeyrefStackPos++] = schemaDoc; 
    
voidtraverseLocalElements()
Traverse all the deferred local elements. This method should be called by traverseSchemas after we've done with all the global declarations.

        fElementTraverser.fDeferTraversingLocalElements = false;
        
        for (int i = 0; i < fLocalElemStackPos; i++) {
            Element currElem = fLocalElementDecl[i];
            //XSDocumentInfo currSchema = (XSDocumentInfo)fDoc2XSDocumentMap.get(DOMUtil.getDocument(currElem));
            //XSDocumentInfo currSchema = (XSDocumentInfo)fDoc2XSDocumentMap.get(DOMUtil.getRoot(DOMUtil.getDocument(currElem)));
            XSDocumentInfo currSchema = fLocalElementDecl_schema[i];
            SchemaGrammar currGrammar = fGrammarBucket.getGrammar(currSchema.fTargetNamespace);
            fElementTraverser.traverseLocal (fParticle[i], currElem, currSchema, currGrammar, fAllContext[i], fParent[i], fLocalElemNamespaceContext[i]);
            // If it's an empty particle, remove it from the containing component.
            if (fParticle[i].fType == XSParticleDecl.PARTICLE_EMPTY) {
                XSModelGroupImpl group = null;
                if (fParent[i] instanceof XSComplexTypeDecl) {
                    XSParticle p = ((XSComplexTypeDecl)fParent[i]).getParticle();
                    if (p != null)
                        group = (XSModelGroupImpl)p.getTerm();
                }
                else {
                    group = ((XSGroupDecl)fParent[i]).fModelGroup;
                }
                if (group != null)
                    removeParticle(group, fParticle[i]);
            }
        }
    
protected voidtraverseSchemas(java.util.ArrayList annotationInfo)

        // the process here is very similar to that in
        // buildGlobalRegistries, except we can't set our schemas as
        // hidden for a second time; so make them all visible again
        // first!
        setSchemasVisible(fRoot);
        Stack schemasToProcess = new Stack();
        schemasToProcess.push(fRoot);
        while (!schemasToProcess.empty()) {
            XSDocumentInfo currSchemaDoc =
                (XSDocumentInfo)schemasToProcess.pop();
            Element currDoc = currSchemaDoc.fSchemaElement;
       
            SchemaGrammar currSG = fGrammarBucket.getGrammar(currSchemaDoc.fTargetNamespace);

            if(DOMUtil.isHidden(currDoc, fHiddenNodes)) {
                // must have processed this already!
                continue;
            }
            Element currRoot = currDoc;
            boolean sawAnnotation = false;
            // traverse this schema's global decls
            for (Element globalComp =
                DOMUtil.getFirstVisibleChildElement(currRoot, fHiddenNodes);
            globalComp != null;
            globalComp = DOMUtil.getNextVisibleSiblingElement(globalComp, fHiddenNodes)) {
                DOMUtil.setHidden(globalComp, fHiddenNodes); 
                String componentType = DOMUtil.getLocalName(globalComp);
                // includes and imports will not show up here!
                if (DOMUtil.getLocalName(globalComp).equals(SchemaSymbols.ELT_REDEFINE)) {
                    // use the namespace decls for the redefine, instead of for the parent <schema>
                    currSchemaDoc.backupNSSupport((SchemaNamespaceSupport)fRedefine2NSSupport.get(globalComp));
                    for (Element redefinedComp = DOMUtil.getFirstVisibleChildElement(globalComp, fHiddenNodes);
                    redefinedComp != null;
                    redefinedComp = DOMUtil.getNextVisibleSiblingElement(redefinedComp, fHiddenNodes)) {
                        String redefinedComponentType = DOMUtil.getLocalName(redefinedComp);
                        DOMUtil.setHidden(redefinedComp, fHiddenNodes);
                        if (redefinedComponentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
                            fAttributeGroupTraverser.traverseGlobal(redefinedComp, currSchemaDoc, currSG);
                        }
                        else if (redefinedComponentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
                            fComplexTypeTraverser.traverseGlobal(redefinedComp, currSchemaDoc, currSG);
                        }
                        else if (redefinedComponentType.equals(SchemaSymbols.ELT_GROUP)) {
                            fGroupTraverser.traverseGlobal(redefinedComp, currSchemaDoc, currSG);
                        }
                        else if (redefinedComponentType.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
                            fSimpleTypeTraverser.traverseGlobal(redefinedComp, currSchemaDoc, currSG);
                        }
                        // annotations will have been processed already; this is now
                        // unnecessary
                        //else if (redefinedComponentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
                        //    fElementTraverser.traverseAnnotationDecl(redefinedComp, null, true, currSchemaDoc);
                        //}
                        else {
                            reportSchemaError("s4s-elt-must-match.1", new Object [] {DOMUtil.getLocalName(globalComp), "(annotation | (simpleType | complexType | group | attributeGroup))*", redefinedComponentType}, redefinedComp);
                        }
                    } // end march through <redefine> children
                    currSchemaDoc.restoreNSSupport();
                }
                else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
                    fAttributeTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
                }
                else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
                    fAttributeGroupTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
                }
                else if (componentType.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
                    fComplexTypeTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
                }
                else if (componentType.equals(SchemaSymbols.ELT_ELEMENT)) {
                    fElementTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
                }
                else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
                    fGroupTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
                }
                else if (componentType.equals(SchemaSymbols.ELT_NOTATION)) {
                    fNotationTraverser.traverse(globalComp, currSchemaDoc, currSG);
                }
                else if (componentType.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
                    fSimpleTypeTraverser.traverseGlobal(globalComp, currSchemaDoc, currSG);
                }
                else if (componentType.equals(SchemaSymbols.ELT_ANNOTATION)) {
                    currSG.addAnnotation(fElementTraverser.traverseAnnotationDecl(globalComp, currSchemaDoc.getSchemaAttrs(), true, currSchemaDoc));
                    sawAnnotation = true;
                }
                else {
                    reportSchemaError("s4s-elt-invalid-content.1", new Object [] {SchemaSymbols.ELT_SCHEMA, DOMUtil.getLocalName(globalComp)}, globalComp);
                }
            } // end for
            
            if (!sawAnnotation) {
                String text = DOMUtil.getSyntheticAnnotation(currRoot);
                if (text != null) {
                    currSG.addAnnotation(fElementTraverser.traverseSyntheticAnnotation(currRoot, text, currSchemaDoc.getSchemaAttrs(), true, currSchemaDoc));
                }
            }
            
            /** Collect annotation information for validation. **/
            if (annotationInfo != null) {
                XSAnnotationInfo info = currSchemaDoc.getAnnotations();
                /** Only add annotations to the list if there were any in this document. **/
                if (info != null) {
                    annotationInfo.add(doc2SystemId(currDoc));
                    annotationInfo.add(info);
                }
            }
            // now we're done with this one!
            currSchemaDoc.returnSchemaAttrs();
            DOMUtil.setHidden(currDoc, fHiddenNodes);

            // now add the schemas this guy depends on
            Vector currSchemaDepends = (Vector)fDependencyMap.get(currSchemaDoc);
            for (int i = 0; i < currSchemaDepends.size(); i++) {
                schemasToProcess.push(currSchemaDepends.elementAt(i));
            }
        } // while
    
private voidvalidateAnnotations(java.util.ArrayList annotationInfo)

        if (fAnnotationValidator == null) {
            createAnnotationValidator();
        }
        final int size = annotationInfo.size();
        final XMLInputSource src = new XMLInputSource(null, null, null);
        fGrammarBucketAdapter.refreshGrammars(fGrammarBucket);
        for (int i = 0; i < size; i += 2) {
            src.setSystemId((String) annotationInfo.get(i));
            XSAnnotationInfo annotation = (XSAnnotationInfo) annotationInfo.get(i+1);
            while (annotation != null) {
                src.setCharacterStream(new StringReader(annotation.fAnnotation));
                try {
                    fAnnotationValidator.parse(src);
                }
                catch (IOException exc) {}
                annotation = annotation.next;
            }
        }