    private void traverseSchema(Element root) throws Exception {
        if (root == null) {
            return;
        }
        for (Element child = XUtil.getFirstChildElement(root);
             child != null;
             child = XUtil.getNextSiblingElement(child)) {
            String name = child.getNodeName();
			if (name.equals(ELT_COMMENT)) {
				traverseComment(child);
            } else if (name.equals(ELT_DATATYPEDECL)) {
				traverseDatatypeDecl(child);
            } else if (name.equals(ELT_ARCHETYPEDECL)) {
				traverseTypeDecl(child);
			} else if (name.equals(ELT_ELEMENTDECL)) { 
				traverseElementDecl(child);
			} else if (name.equals(ELT_ATTRGROUPDECL)) {
				traverseAttrGroup(child);
			} else if (name.equals(ELT_MODELGROUPDECL)) {
				traverseModelGroup(child);
			}
            else if (name.equals(ELT_TEXTENTITYDECL) ||
                     name.equals(ELT_EXTERNALENTITYDECL) ||
                     name.equals(ELT_UNPARSEDENTITYDECL)) {
                int entityName = fStringPool.addSymbol(child.getAttribute(ATT_NAME));
                if (name.equals(ELT_TEXTENTITYDECL)) {
                    int value = fStringPool.addString(child.getFirstChild().getNodeValue());
                    fEntityPool.addEntityDecl(entityName, value, -1, -1, -1, -1, true);
                }
                else {
                    int publicId = fStringPool.addString(child.getAttribute("public"));
                    int systemId = fStringPool.addString(child.getAttribute("system"));
                    if (name.equals(ELT_EXTERNALENTITYDECL)) {
                        fEntityPool.addEntityDecl(entityName, -1, -1, publicId, systemId, -1, true);
                    }
                    else {
                        int notationName = fStringPool.addSymbol(child.getAttribute("notation"));
                        fEntityPool.addEntityDecl(entityName, -1, -1, publicId, systemId, notationName, true);
                    }
                }
            }
            else if (name.equals(ELT_NOTATIONDECL)) {
                int notationName = fStringPool.addSymbol(child.getAttribute(ATT_NAME));
                int publicId = fStringPool.addString(child.getAttribute("public"));
                int systemId = fStringPool.addString(child.getAttribute("system"));
                fEntityPool.addNotationDecl(notationName, publicId, systemId, true);
            }
        } 
        cleanupForwardReferences();
    } 
    private void cleanupForwardReferences() {
        for (java.util.Enumeration keys = fForwardRefs.keys(); keys.hasMoreElements();) {
            Object k = keys.nextElement();
            int ik = ((Integer) k).intValue();
            cleanupForwardReferencesTo(ik);
        }
    }
    private void cleanupForwardReferencesTo(int r) {
        Vector referrers = (Vector) fForwardRefs.get(new Integer(r));
        if (referrers == null) return;
        for (int i = 0; i < referrers.size(); i++) {
            int ref = ((Integer) referrers.elementAt(i)).intValue();
            fElementDeclPool.copyAtts(r, ((Integer) referrers.elementAt(i)).intValue());
        }
    }
	private void traverseComment(Element comment) {
        return; 
	}
	private int traverseTypeDecl(Element typeDecl) throws Exception {
		String typeName = typeDecl.getAttribute(ATT_NAME);
		String content = typeDecl.getAttribute(ATT_CONTENT);
		String model = typeDecl.getAttribute(ATT_MODEL);
		String order = typeDecl.getAttribute(ATT_ORDER);
		String type = typeDecl.getAttribute(ATT_TYPE);
		String deflt = typeDecl.getAttribute(ATT_DEFAULT);
		String fixed = typeDecl.getAttribute(ATT_FIXED);
		String schemaAbbrev = typeDecl.getAttribute(ATT_SCHEMAABBREV);
		String schemaName = typeDecl.getAttribute(ATT_SCHEMANAME);
		if (typeName.equals("")) { 
		    typeName = "http://www.apache.org/xml/xerces/internalType"+fTypeCount++;
		}
		if (type.equals("")) {
		    if (!schemaAbbrev.equals(""))
				reportSchemaError(SchemaMessageProvider.AttMissingType,
							new Object [] { "schemaAbbrev" });
		    if (!schemaName.equals(""))
				reportSchemaError(SchemaMessageProvider.AttMissingType,
							new Object [] { "schemaName" });
		    if (!deflt.equals(""))
				reportSchemaError(SchemaMessageProvider.AttMissingType,
							new Object [] { "default" });
		    if (!fixed.equals(""))
				reportSchemaError(SchemaMessageProvider.AttMissingType,
							new Object [] { "fixed" });
		} else {
            if (fDatatypeRegistry.getValidatorFor(type) != null) 
				reportSchemaError(SchemaMessageProvider.NotADatatype,
								  new Object [] { type }); 
            if (!content.equals(ATTVAL_TEXTONLY)) 
				reportSchemaError(SchemaMessageProvider.TextOnlyContentWithType, null);
		}
		Element child = XUtil.getFirstChildElement(typeDecl);
		Element refines = null;
		if (child != null && child.getNodeName().equals(ELT_REFINES)) {
			reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
							  new Object [] { "Refinement" });
			refines = child;
			child = XUtil.getNextSiblingElement(child);
		}
		int contentSpecType = 0;
		int csnType = 0;
        boolean mixedContent = false;
        boolean elementContent = false;
        boolean textContent = false;
        boolean buildAll = false;
        int allChildren[] = null;
        int allChildCount = 0;
		int left = -2;
		int right = -2;
		boolean hadContent = false;
        if (order.equals(ATTVAL_CHOICE)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_CHOICE;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_SEQ)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_SEQ;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_ALL)) {
            buildAll = true;
            allChildren = new int[((org.apache.xerces.dom.NodeImpl)typeDecl).getLength()];
            allChildCount = 0;
		}
		if (content.equals(ATTVAL_EMPTY)) {
			contentSpecType = fStringPool.addSymbol("EMPTY");
			left = -1; 
		} else if (content.equals(ATTVAL_ANY)) {
			contentSpecType = fStringPool.addSymbol("ANY");
			left = -1; 
		} else if (content.equals(ATTVAL_MIXED)) {
		    contentSpecType = fStringPool.addSymbol("MIXED");
		    mixedContent = true;
		    csnType = XMLContentSpecNode.CONTENTSPECNODE_CHOICE;
		} else if (content.equals(ATTVAL_ELEMONLY)) {
            elementContent = true;
		} else if (content.equals(ATTVAL_TEXTONLY)) {
            textContent = true;
        }
        if (mixedContent) {
            left = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
					      							   -1, 
													   -1, false);
        }
        Vector uses = new Vector();
		for (;
			 child != null;
			 child = XUtil.getNextSiblingElement(child)) {
			int index = -2;
            hadContent = true;
			String childName = child.getNodeName();
			if (childName.equals(ELT_ELEMENTDECL)) {
			    if (child.getAttribute(ATT_REF).equals("")) { 
			        if (elementContent)   
						reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
										  new Object [] { "Nesting element declarations" });
        			else
						reportSchemaError(SchemaMessageProvider.NestedOnlyInElemOnly, null);
    			} else if (mixedContent || elementContent) { 
    			    index = traverseElementRef(child);
    			} else {
					reportSchemaError(SchemaMessageProvider.EltRefOnlyInMixedElemOnly, null);
    			}
			} else if (childName.equals(ELT_GROUP)) {
			    if (elementContent && !buildAll) {
    			    int groupNameIndex = traverseGroup(child);
	    			index = getContentSpec(getElement(groupNameIndex));
				} else if (!elementContent)
					reportSchemaError(SchemaMessageProvider.OnlyInEltContent,
									  new Object [] { "group" });
			    else 
					reportSchemaError(SchemaMessageProvider.OrderIsAll,
									  new Object [] { "group" } );
			} else if (childName.equals(ELT_MODELGROUPREF)) {
			    if (elementContent && !buildAll) {
    				int modelGroupNameIndex = traverseModelGroup(child);
	    			index = getContentSpec(getElement(modelGroupNameIndex));
		    		if (index == -1)
						reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
										  new Object [] { "Forward reference to model group" });
				    index = expandContentModel(index, child);
				} else if (!elementContent)
					reportSchemaError(SchemaMessageProvider.OnlyInEltContent,
									  new Object [] { "modelGroupRef" });
				else 
					reportSchemaError(SchemaMessageProvider.OrderIsAll,
									  new Object [] { "modelGroupRef" });
			} else if (childName.equals(ELT_ATTRIBUTEDECL) || childName.equals(ELT_ATTRGROUPREF)) {
			    break; 
			} else { 
			    if (type.equals(""))
					reportSchemaError(SchemaMessageProvider.DatatypeWithType, null);
			    else
					reportSchemaError(SchemaMessageProvider.DatatypeQualUnsupported,
									  new Object [] { childName });
			}
            uses.addElement(new Integer(index));
			if (buildAll) {
			    allChildren[allChildCount++] = index;
			} else if (left == -2) {
				left = index;
			} else if (right == -2) {
				right = index;
			} else {
   				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
    			right = index;
   			}
		}
		if (buildAll) {
		    left = buildAllModel(allChildren,allChildCount);
		} else {
		    if (hadContent && right != -2)
       		    left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
    		if (mixedContent && hadContent) {
		    	left = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_ZERO_OR_MORE,
													   left, -1, false);
	    	}
		}
		int typeNameIndex = fStringPool.addSymbol(typeName); 
		int typeIndex = fElementDeclPool.addElementDecl(typeNameIndex, contentSpecType, left, false);
        for (int x = 0; x < uses.size(); x++)
            addUse(typeNameIndex, (Integer)uses.elementAt(x));
		for (;
			 child != null;
			 child = XUtil.getNextSiblingElement(child)) {
			String childName = child.getNodeName();
			if (childName.equals(ELT_ATTRIBUTEDECL)) {
				traverseAttributeDecl(child, typeIndex);
			} else if (childName.equals(ELT_ATTRGROUPREF)) {
    			int index = traverseAttrGroupRef(child);
    			if (getContentSpec(getElement(index)) == -1) {
					reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
									  new Object [] { "Forward References to attrGroup" });
    			    Vector v = null;
    			    Integer i = new Integer(index);
    			    if ((v = (Vector) fForwardRefs.get(i)) == null)
    			        v = new Vector();
                    v.addElement(new Integer(typeNameIndex));
    			    fForwardRefs.put(i,v);
                    addUse(typeNameIndex, index);
    			} else
        			fElementDeclPool.copyAtts(index, typeNameIndex);
			}
		}
        return typeNameIndex;
	}
	private int traverseGroup(Element groupDecl) throws Exception {
		String groupName = groupDecl.getAttribute(ATT_NAME);
		String collection = groupDecl.getAttribute(ATT_COLLECTION);
		String order = groupDecl.getAttribute(ATT_ORDER);
		if (groupName.equals("")) { 
		    groupName = "http://www.apache.org/xml/xerces/internalGroup"+fGroupCount++;
		}
		Element child = XUtil.getFirstChildElement(groupDecl);
		int contentSpecType = 0;
		int csnType = 0;
        boolean buildAll = false;
        int allChildren[] = null;
        int allChildCount = 0;
		if (order.equals(ATTVAL_CHOICE)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_CHOICE;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_SEQ)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_SEQ;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_ALL)) {
            buildAll = true;
            allChildren = new int[((org.apache.xerces.dom.NodeImpl)groupDecl).getLength()];
            allChildCount = 0;
		}
		int left = -2;
		int right = -2;
		boolean hadContent = false;
		int groupIndices[] = new int [((org.apache.xerces.dom.NodeImpl)groupDecl).getLength()];
		int numGroups = 0;
		for (;
			 child != null;
			 child = XUtil.getNextSiblingElement(child)) {
			int index = -2;
            hadContent = true;
			String childName = child.getNodeName();
			if (childName.equals(ELT_ELEMENTDECL)) {
			    if (child.getAttribute(ATT_REF).equals(""))
					reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
									  new Object [] { "Nesting element declarations" });
			    else
    			    index = traverseElementRef(child);
			} else if (childName.equals(ELT_GROUP)) {
			    if (!buildAll) {
    			    int groupNameIndex = traverseGroup(child);
	    			groupIndices[numGroups++] = groupNameIndex;
		    		index = getContentSpec(getElement(groupNameIndex));
		    	} else
					reportSchemaError(SchemaMessageProvider.OrderIsAll,
									  new Object [] { "group" } );
			} else if (childName.equals(ELT_MODELGROUPREF)) {
			    if (!buildAll) {
                    int modelGroupNameIndex = traverseModelGroupRef(child);
                    index = getContentSpec(getElement(modelGroupNameIndex));
                    index = expandContentModel(index, child);
                } else
					reportSchemaError(SchemaMessageProvider.OrderIsAll,
									  new Object [] { "modelGroupRef" });
			} else {
				reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
								  new Object [] { "group", childName });
			}
			if (buildAll) {
			    allChildren[allChildCount++] = index;
			} else if (left == -2) {
				left = index;
			} else if (right == -2) {
				right = index;
			} else {
   				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
    			right = index;
   			}
		}
		if (buildAll) {
		    left = buildAllModel(allChildren,allChildCount);
		} else {
			if (hadContent && right != -2)
				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
		}
		left = expandContentModel(left, groupDecl);
		int groupNameIndex = fStringPool.addSymbol(groupName); 
		int groupIndex = fElementDeclPool.addElementDecl(groupNameIndex, contentSpecType, left, false);
        return groupNameIndex;
	}
	private int traverseModelGroup(Element modelGroupDecl) throws Exception {
		String modelGroupName = modelGroupDecl.getAttribute(ATT_NAME);
		String order = modelGroupDecl.getAttribute(ATT_ORDER);
		if (modelGroupName.equals("")) { 
		    modelGroupName = "http://www.apache.org/xml/xerces/internalModelGroup"+fModelGroupCount++;
		}
		Element child = XUtil.getFirstChildElement(modelGroupDecl);
		int contentSpecType = 0;
		int csnType = 0;
        boolean buildAll = false;
        int allChildren[] = null;
        int allChildCount = 0;
		if (order.equals(ATTVAL_CHOICE)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_CHOICE;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_SEQ)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_SEQ;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_ALL)) {
			buildAll = true;
            allChildren = new int[((org.apache.xerces.dom.NodeImpl)modelGroupDecl).getLength()];
            allChildCount = 0;
		}
		int left = -2;
		int right = -2;
		boolean hadContent = false;
		for (;
			 child != null;
			 child = XUtil.getNextSiblingElement(child)) {
			int index = -2;
            hadContent = true;
			String childName = child.getNodeName();
			if (childName.equals(ELT_ELEMENTDECL)) {
			    if (child.getAttribute(ATT_REF).equals(""))
					reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
									  new Object [] { "Nesting element declarations" });
			    else {
    			    index = traverseElementRef(child);
                }
			} else if (childName.equals(ELT_GROUP)) {
			    int groupNameIndex = traverseGroup(child);
				index = getContentSpec(getElement(groupNameIndex));
			} else if (childName.equals(ELT_MODELGROUPREF)) {
                int modelGroupNameIndex = traverseModelGroupRef(child);
                index = getContentSpec(getElement(modelGroupNameIndex));
                index = expandContentModel(index, child);
			} else {
				reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
								  new Object [] { "modelGroup", childName });
			}
			if (buildAll) {
			    allChildren[allChildCount++] = index;
			} else if (left == -2) {
				left = index;
			} else if (right == -2) {
				right = index;
			} else {
   				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
    			right = index;
   			}
		}
		if (buildAll) {
		    left = buildAllModel(allChildren,allChildCount);
		} else {
			if (hadContent && right != -2)
				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
		}
		left = expandContentModel(left, modelGroupDecl);
		int modelGroupNameIndex = fStringPool.addSymbol(modelGroupName); 
		int modelGroupIndex = fElementDeclPool.addElementDecl(modelGroupNameIndex, contentSpecType, left, false);
        return modelGroupNameIndex;
	}
	private int traverseModelGroupRef(Element modelGroupRef) {
	    String name = modelGroupRef.getAttribute(ATT_NAME);
	    int index = fStringPool.addSymbol(name);
        return index;
	}
	public int traverseDatatypeDecl(Element datatypeDecl) {
		int newTypeName = fStringPool.addSymbol(datatypeDecl.getAttribute(ATT_NAME));
		int export = fStringPool.addSymbol(datatypeDecl.getAttribute(ATT_EXPORT));
		Element datatypeChild = XUtil.getFirstChildElement(datatypeDecl);
		int basetype = fStringPool.addSymbol(datatypeChild.getNodeName());
		DatatypeValidator baseValidator = fDatatypeRegistry.getValidatorFor(datatypeChild.getAttribute(ATT_NAME));
		if (baseValidator == null) {
			reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
							  new Object [] { datatypeChild.getAttribute(ATT_NAME), datatypeDecl.getAttribute(ATT_NAME) });
			return -1;
		}
		int numFacets = 0;
		int numEnumerationLiterals = 0;
		Hashtable facetData = new Hashtable();
		Vector enumData = new Vector();
		Node facet = datatypeChild.getNextSibling();
		while (facet != null) {
			if (facet.getNodeType() == Node.ELEMENT_NODE) {
				numFacets++;
				if (facet.getNodeName().equals(DatatypeValidator.ENUMERATION)) {
					Node literal = XUtil.getFirstChildElement(facet);
					while (literal != null) {
						numEnumerationLiterals++;
						enumData.addElement(literal.getFirstChild().getNodeValue());
						literal = XUtil.getNextSiblingElement(literal);
					}
				} else {
					facetData.put(facet.getNodeName(),facet.getFirstChild().getNodeValue());
				}
			}
			facet = facet.getNextSibling();
		}
		if (numEnumerationLiterals > 0) {
			facetData.put(DatatypeValidator.ENUMERATION, enumData);
		}
		try {
			DatatypeValidator newValidator = (DatatypeValidator) baseValidator.getClass().newInstance();
			if (numFacets > 0)
				newValidator.setFacets(facetData);
			fDatatypeRegistry.addValidator(fStringPool.toString(newTypeName),newValidator);
		} catch (Exception e) {
			reportSchemaError(SchemaMessageProvider.DatatypeError,
							  new Object [] { e.getMessage() });
		}
        return -1;
	}
	private int traverseElementDecl(Element elementDecl) throws Exception {
		int contentSpecType      = -1;
		int contentSpecNodeIndex = -1;
        int typeNameIndex = -1;
		String name = elementDecl.getAttribute(ATT_NAME);
		String ref = elementDecl.getAttribute(ATT_REF);
		String archRef = elementDecl.getAttribute(ATT_ARCHREF);
		String type = elementDecl.getAttribute(ATT_TYPE);
		String schemaAbbrev = elementDecl.getAttribute(ATT_SCHEMAABBREV);
		String schemaName = elementDecl.getAttribute(ATT_SCHEMANAME);
		String minOccurs = elementDecl.getAttribute(ATT_MINOCCURS);
		String maxOccurs = elementDecl.getAttribute(ATT_MAXOCCURS);
		String export = elementDecl.getAttribute(ATT_EXPORT);
        int attrCount = 0;
		if (!ref.equals("")) attrCount++;
		if (!type.equals("")) attrCount++;
		if (!archRef.equals("")) attrCount++;
		if (attrCount > 1)
			reportSchemaError(SchemaMessageProvider.OneOfTypeRefArchRef, null);
		if (!ref.equals("") || !archRef.equals("")) {
		    if (XUtil.getFirstChildElement(elementDecl) != null)
				reportSchemaError(SchemaMessageProvider.NoContentForRef, null);
		   	int typeName = (!ref.equals("")) ? fStringPool.addSymbol(ref) : fStringPool.addSymbol(archRef);
		   	contentSpecNodeIndex = getContentSpec(getElement(typeName));
		   	contentSpecType = getContentSpecType(getElement(typeName));
		   	int elementNameIndex = fStringPool.addSymbol(name);
            int elementIndex = -1;
		   	if (contentSpecNodeIndex == -1) {
		   	    contentSpecType = XMLContentSpecNode.CONTENTSPECNODE_LEAF;
            	contentSpecNodeIndex = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
	        							                                   elementNameIndex, -1, false);
                fElementDeclPool.addElementDecl(elementNameIndex, contentSpecType, contentSpecNodeIndex, true);
				reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
								  new Object [] { "Forward references to archetypes" });
    			Vector v = null;
    			Integer i = new Integer(typeName);
    			if ((v = (Vector) fForwardRefs.get(i)) == null)
    			     v = new Vector();
                v.addElement(new Integer(elementNameIndex));
    			fForwardRefs.put(i,v);
    			addUse(elementNameIndex, typeName);
		   	} else {
                fElementDeclPool.addElementDecl(elementNameIndex, contentSpecType, contentSpecNodeIndex, true);
                fElementDeclPool.copyAtts(typeName, elementNameIndex);
            }
		    return elementNameIndex;
		}
		Element content = XUtil.getFirstChildElement(elementDecl);
		if (content != null) {
			String contentName = content.getNodeName();
			if (contentName.equals(ELT_ARCHETYPEDECL)) {
				typeNameIndex = traverseTypeDecl(content);
				contentSpecNodeIndex = getContentSpec(getElement(typeNameIndex));
				contentSpecType = getContentSpecType(getElement(typeNameIndex));
			} else if (contentName.equals(ELT_DATATYPEDECL)) {
				reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
								  new Object [] { "Nesting datatype declarations" });
			} else if (!type.equals("")) { 
				contentSpecType = fStringPool.addSymbol("DATATYPE");
				contentSpecNodeIndex = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
																		   fStringPool.addSymbol(content.getAttribute(ATT_NAME)),
																		   -1, false);
				contentSpecNodeIndex = expandContentModel(contentSpecNodeIndex, content);
			} else if (type.equals("")) { 
	    		contentSpecType = fStringPool.addSymbol("CHILDREN");
				int leftIndex = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
																	fStringPool.addSymbol(content.getAttribute(ATT_NAME)),
																	-1, false);
	    		contentSpecNodeIndex = expandContentModel(contentSpecNodeIndex, content);
			} else {
				System.out.println("unhandled case in element decl code");
			}
		} else if (!type.equals("")) { 
			contentSpecType = fStringPool.addSymbol("DATATYPE");
			contentSpecNodeIndex = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
																	   fStringPool.addSymbol(type),
																	   -1, false);
			contentSpecNodeIndex = expandContentModel(contentSpecNodeIndex, elementDecl);
		}
		int elementNameIndex     = fStringPool.addSymbol(elementDecl.getAttribute(ATT_NAME));
		int elementIndex = fElementDeclPool.addElementDecl(elementNameIndex, contentSpecType, contentSpecNodeIndex, true);
        fElementDeclPool.copyAtts(typeNameIndex, elementNameIndex);
        return elementNameIndex;
	}

    private void traverseSchema(Element root) throws Exception {
        if (root == null) {
            return;
        }
        for (Element child = XUtil.getFirstChildElement(root);
             child != null;
             child = XUtil.getNextSiblingElement(child)) {
            String name = child.getNodeName();
			if (name.equals(ELT_COMMENT)) {
				traverseComment(child);
            } else if (name.equals(ELT_DATATYPEDECL)) {
				traverseDatatypeDecl(child);
            } else if (name.equals(ELT_ARCHETYPEDECL)) {
				traverseTypeDecl(child);
			} else if (name.equals(ELT_ELEMENTDECL)) { 
				traverseElementDecl(child);
			} else if (name.equals(ELT_ATTRGROUPDECL)) {
				traverseAttrGroup(child);
			} else if (name.equals(ELT_MODELGROUPDECL)) {
				traverseModelGroup(child);
			}
            else if (name.equals(ELT_TEXTENTITYDECL) ||
                     name.equals(ELT_EXTERNALENTITYDECL) ||
                     name.equals(ELT_UNPARSEDENTITYDECL)) {
                int entityName = fStringPool.addSymbol(child.getAttribute(ATT_NAME));
                if (name.equals(ELT_TEXTENTITYDECL)) {
                    int value = fStringPool.addString(child.getFirstChild().getFirstChild().getNodeValue());
                    fEntityPool.addEntityDecl(entityName, value, -1, -1, -1, -1, true);
                }
                else {
                    int publicId = fStringPool.addString(child.getAttribute("public"));
                    int systemId = fStringPool.addString(child.getAttribute("system"));
                    if (name.equals(ELT_EXTERNALENTITYDECL)) {
                        fEntityPool.addEntityDecl(entityName, -1, -1, publicId, systemId, -1, true);
                    }
                    else {
                        int notationName = fStringPool.addSymbol(child.getAttribute("notation"));
                        fEntityPool.addEntityDecl(entityName, -1, -1, publicId, systemId, notationName, true);
                    }
                }
            }
            else if (name.equals(ELT_NOTATIONDECL)) {
                int notationName = fStringPool.addSymbol(child.getAttribute(ATT_NAME));
                int publicId = fStringPool.addString(child.getAttribute("public"));
                int systemId = fStringPool.addString(child.getAttribute("system"));
                fEntityPool.addNotationDecl(notationName, publicId, systemId, true);
            }
        } 
        cleanupForwardReferences();
    } 
    private void cleanupForwardReferences() {
        for (java.util.Enumeration keys = fForwardRefs.keys(); keys.hasMoreElements();) {
            Object k = keys.nextElement();
            int ik = ((Integer) k).intValue();
            cleanupForwardReferencesTo(ik);
        }
    }
    private void cleanupForwardReferencesTo(int r) {
        Vector referrers = (Vector) fForwardRefs.get(new Integer(r));
        if (referrers == null) return;
        for (int i = 0; i < referrers.size(); i++) {
            int ref = ((Integer) referrers.elementAt(i)).intValue();
            fElementDeclPool.copyAtts(r, ((Integer) referrers.elementAt(i)).intValue());
        }
    }
	private void traverseComment(Element comment) {
        return; 
	}
	private int traverseTypeDecl(Element typeDecl) throws Exception {
		String typeName = typeDecl.getAttribute(ATT_NAME);
		String content = typeDecl.getAttribute(ATT_CONTENT);
		String model = typeDecl.getAttribute(ATT_MODEL);
		String order = typeDecl.getAttribute(ATT_ORDER);
		String type = typeDecl.getAttribute(ATT_TYPE);
		String deflt = typeDecl.getAttribute(ATT_DEFAULT);
		String fixed = typeDecl.getAttribute(ATT_FIXED);
		String schemaAbbrev = typeDecl.getAttribute(ATT_SCHEMAABBREV);
		String schemaName = typeDecl.getAttribute(ATT_SCHEMANAME);
		if (typeName.equals("")) { 
		    typeName = "http://www.apache.org/xml/xerces/internalType"+fTypeCount++;
		}
		if (type.equals("")) {
		    if (!schemaAbbrev.equals(""))
				reportSchemaError(SchemaMessageProvider.AttMissingType,
							new Object [] { "schemaAbbrev" });
		    if (!schemaName.equals(""))
				reportSchemaError(SchemaMessageProvider.AttMissingType,
							new Object [] { "schemaName" });
		    if (!deflt.equals(""))
				reportSchemaError(SchemaMessageProvider.AttMissingType,
							new Object [] { "default" });
		    if (!fixed.equals(""))
				reportSchemaError(SchemaMessageProvider.AttMissingType,
							new Object [] { "fixed" });
		} else {
            if (fDatatypeRegistry.getValidatorFor(type) != null) 
				reportSchemaError(SchemaMessageProvider.NotADatatype,
								  new Object [] { type }); 
            if (!content.equals(ATTVAL_TEXTONLY)) 
				reportSchemaError(SchemaMessageProvider.TextOnlyContentWithType, null);
		}
		Element child = XUtil.getFirstChildElement(typeDecl);
		Element refines = null;
		if (child != null && child.getNodeName().equals(ELT_REFINES)) {
			reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
							  new Object [] { "Refinement" });
			refines = child;
			child = XUtil.getNextSiblingElement(child);
		}
		int contentSpecType = 0;
		int csnType = 0;
        boolean mixedContent = false;
        boolean elementContent = false;
        boolean textContent = false;
        boolean buildAll = false;
        int allChildren[] = null;
        int allChildCount = 0;
		int left = -2;
		int right = -2;
		boolean hadContent = false;
        if (order.equals(ATTVAL_CHOICE)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_CHOICE;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_SEQ)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_SEQ;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_ALL)) {
            buildAll = true;
            allChildren = new int[((org.apache.xerces.dom.NodeImpl)typeDecl).getLength()];
            allChildCount = 0;
		}
		if (content.equals(ATTVAL_EMPTY)) {
			contentSpecType = fStringPool.addSymbol("EMPTY");
			left = -1; 
		} else if (content.equals(ATTVAL_ANY)) {
			contentSpecType = fStringPool.addSymbol("ANY");
			left = -1; 
		} else if (content.equals(ATTVAL_MIXED)) {
		    contentSpecType = fStringPool.addSymbol("MIXED");
		    mixedContent = true;
		    csnType = XMLContentSpecNode.CONTENTSPECNODE_CHOICE;
		} else if (content.equals(ATTVAL_ELEMONLY)) {
            elementContent = true;
		} else if (content.equals(ATTVAL_TEXTONLY)) {
            textContent = true;
        }
        if (mixedContent) {
            left = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
					      							   -1, 
													   -1, false);
        }
        Vector uses = new Vector();
		for (;
			 child != null;
			 child = XUtil.getNextSiblingElement(child)) {
			int index = -2;
            hadContent = true;
			String childName = child.getNodeName();
			if (childName.equals(ELT_ELEMENTDECL)) {
			    if (child.getAttribute(ATT_REF).equals("")) { 
			        if (elementContent)   
						reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
										  new Object [] { "Nesting element declarations" });
        			else
						reportSchemaError(SchemaMessageProvider.NestedOnlyInElemOnly, null);
    			} else if (mixedContent || elementContent) { 
    			    index = traverseElementRef(child);
    			} else {
					reportSchemaError(SchemaMessageProvider.EltRefOnlyInMixedElemOnly, null);
    			}
			} else if (childName.equals(ELT_GROUP)) {
			    if (elementContent && !buildAll) {
    			    int groupNameIndex = traverseGroup(child);
	    			index = getContentSpec(getElement(groupNameIndex));
				} else if (!elementContent)
					reportSchemaError(SchemaMessageProvider.OnlyInEltContent,
									  new Object [] { "group" });
			    else 
					reportSchemaError(SchemaMessageProvider.OrderIsAll,
									  new Object [] { "group" } );
			} else if (childName.equals(ELT_MODELGROUPREF)) {
			    if (elementContent && !buildAll) {
    				int modelGroupNameIndex = traverseModelGroup(child);
	    			index = getContentSpec(getElement(modelGroupNameIndex));
		    		if (index == -1)
						reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
										  new Object [] { "Forward reference to model group" });
				    index = expandContentModel(index, child);
				} else if (!elementContent)
					reportSchemaError(SchemaMessageProvider.OnlyInEltContent,
									  new Object [] { "modelGroupRef" });
				else 
					reportSchemaError(SchemaMessageProvider.OrderIsAll,
									  new Object [] { "modelGroupRef" });
			} else if (childName.equals(ELT_ATTRIBUTEDECL) || childName.equals(ELT_ATTRGROUPREF)) {
			    break; 
			} else { 
			    if (type.equals(""))
					reportSchemaError(SchemaMessageProvider.DatatypeWithType, null);
			    else
					reportSchemaError(SchemaMessageProvider.DatatypeQualUnsupported,
									  new Object [] { childName });
			}
            uses.addElement(new Integer(index));
			if (buildAll) {
			    allChildren[allChildCount++] = index;
			} else if (left == -2) {
				left = index;
			} else if (right == -2) {
				right = index;
			} else {
   				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
    			right = index;
   			}
		}
		if (buildAll) {
		    left = buildAllModel(allChildren,allChildCount);
		} else {
		    if (hadContent && right != -2)
       		    left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
    		if (mixedContent && hadContent) {
		    	left = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_ZERO_OR_MORE,
													   left, -1, false);
	    	}
		}
		int typeNameIndex = fStringPool.addSymbol(typeName); 
		int typeIndex = fElementDeclPool.addElementDecl(typeNameIndex, contentSpecType, left, false);
        for (int x = 0; x < uses.size(); x++)
            addUse(typeNameIndex, (Integer)uses.elementAt(x));
		for (;
			 child != null;
			 child = XUtil.getNextSiblingElement(child)) {
			String childName = child.getNodeName();
			if (childName.equals(ELT_ATTRIBUTEDECL)) {
				traverseAttributeDecl(child, typeIndex);
			} else if (childName.equals(ELT_ATTRGROUPREF)) {
    			int index = traverseAttrGroupRef(child);
    			if (getContentSpec(getElement(index)) == -1) {
					reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
									  new Object [] { "Forward References to attrGroup" });
    			    Vector v = null;
    			    Integer i = new Integer(index);
    			    if ((v = (Vector) fForwardRefs.get(i)) == null)
    			        v = new Vector();
                    v.addElement(new Integer(typeNameIndex));
    			    fForwardRefs.put(i,v);
                    addUse(typeNameIndex, index);
    			} else
        			fElementDeclPool.copyAtts(index, typeNameIndex);
			}
		}
        return typeNameIndex;
	}
	private int traverseGroup(Element groupDecl) throws Exception {
		String groupName = groupDecl.getAttribute(ATT_NAME);
		String collection = groupDecl.getAttribute(ATT_COLLECTION);
		String order = groupDecl.getAttribute(ATT_ORDER);
		if (groupName.equals("")) { 
		    groupName = "http://www.apache.org/xml/xerces/internalGroup"+fGroupCount++;
		}
		Element child = XUtil.getFirstChildElement(groupDecl);
		int contentSpecType = 0;
		int csnType = 0;
        boolean buildAll = false;
        int allChildren[] = null;
        int allChildCount = 0;
		if (order.equals(ATTVAL_CHOICE)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_CHOICE;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_SEQ)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_SEQ;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_ALL)) {
            buildAll = true;
            allChildren = new int[((org.apache.xerces.dom.NodeImpl)groupDecl).getLength()];
            allChildCount = 0;
		}
		int left = -2;
		int right = -2;
		boolean hadContent = false;
		int groupIndices[] = new int [((org.apache.xerces.dom.NodeImpl)groupDecl).getLength()];
		int numGroups = 0;
		for (;
			 child != null;
			 child = XUtil.getNextSiblingElement(child)) {
			int index = -2;
            hadContent = true;
			String childName = child.getNodeName();
			if (childName.equals(ELT_ELEMENTDECL)) {
			    if (child.getAttribute(ATT_REF).equals(""))
					reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
									  new Object [] { "Nesting element declarations" });
			    else
    			    index = traverseElementRef(child);
			} else if (childName.equals(ELT_GROUP)) {
			    if (!buildAll) {
    			    int groupNameIndex = traverseGroup(child);
	    			groupIndices[numGroups++] = groupNameIndex;
		    		index = getContentSpec(getElement(groupNameIndex));
		    	} else
					reportSchemaError(SchemaMessageProvider.OrderIsAll,
									  new Object [] { "group" } );
			} else if (childName.equals(ELT_MODELGROUPREF)) {
			    if (!buildAll) {
                    int modelGroupNameIndex = traverseModelGroupRef(child);
                    index = getContentSpec(getElement(modelGroupNameIndex));
                    index = expandContentModel(index, child);
                } else
					reportSchemaError(SchemaMessageProvider.OrderIsAll,
									  new Object [] { "modelGroupRef" });
			} else {
				reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
								  new Object [] { "group", childName });
			}
			if (buildAll) {
			    allChildren[allChildCount++] = index;
			} else if (left == -2) {
				left = index;
			} else if (right == -2) {
				right = index;
			} else {
   				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
    			right = index;
   			}
		}
		if (buildAll) {
		    left = buildAllModel(allChildren,allChildCount);
		} else {
			if (hadContent && right != -2)
				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
		}
		left = expandContentModel(left, groupDecl);
		int groupNameIndex = fStringPool.addSymbol(groupName); 
		int groupIndex = fElementDeclPool.addElementDecl(groupNameIndex, contentSpecType, left, false);
        return groupNameIndex;
	}
	private int traverseModelGroup(Element modelGroupDecl) throws Exception {
		String modelGroupName = modelGroupDecl.getAttribute(ATT_NAME);
		String order = modelGroupDecl.getAttribute(ATT_ORDER);
		if (modelGroupName.equals("")) { 
		    modelGroupName = "http://www.apache.org/xml/xerces/internalModelGroup"+fModelGroupCount++;
		}
		Element child = XUtil.getFirstChildElement(modelGroupDecl);
		int contentSpecType = 0;
		int csnType = 0;
        boolean buildAll = false;
        int allChildren[] = null;
        int allChildCount = 0;
		if (order.equals(ATTVAL_CHOICE)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_CHOICE;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_SEQ)) {
			csnType = XMLContentSpecNode.CONTENTSPECNODE_SEQ;
			contentSpecType = fStringPool.addSymbol("CHILDREN");
		} else if (order.equals(ATTVAL_ALL)) {
			buildAll = true;
            allChildren = new int[((org.apache.xerces.dom.NodeImpl)modelGroupDecl).getLength()];
            allChildCount = 0;
		}
		int left = -2;
		int right = -2;
		boolean hadContent = false;
		for (;
			 child != null;
			 child = XUtil.getNextSiblingElement(child)) {
			int index = -2;
            hadContent = true;
			String childName = child.getNodeName();
			if (childName.equals(ELT_ELEMENTDECL)) {
			    if (child.getAttribute(ATT_REF).equals(""))
					reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
									  new Object [] { "Nesting element declarations" });
			    else {
    			    index = traverseElementRef(child);
                }
			} else if (childName.equals(ELT_GROUP)) {
			    int groupNameIndex = traverseGroup(child);
				index = getContentSpec(getElement(groupNameIndex));
			} else if (childName.equals(ELT_MODELGROUPREF)) {
                int modelGroupNameIndex = traverseModelGroupRef(child);
                index = getContentSpec(getElement(modelGroupNameIndex));
                index = expandContentModel(index, child);
			} else {
				reportSchemaError(SchemaMessageProvider.GroupContentRestricted,
								  new Object [] { "modelGroup", childName });
			}
			if (buildAll) {
			    allChildren[allChildCount++] = index;
			} else if (left == -2) {
				left = index;
			} else if (right == -2) {
				right = index;
			} else {
   				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
    			right = index;
   			}
		}
		if (buildAll) {
		    left = buildAllModel(allChildren,allChildCount);
		} else {
			if (hadContent && right != -2)
				left = fElementDeclPool.addContentSpecNode(csnType, left, right, false);
		}
		left = expandContentModel(left, modelGroupDecl);
		int modelGroupNameIndex = fStringPool.addSymbol(modelGroupName); 
		int modelGroupIndex = fElementDeclPool.addElementDecl(modelGroupNameIndex, contentSpecType, left, false);
        return modelGroupNameIndex;
	}
	private int traverseModelGroupRef(Element modelGroupRef) {
	    String name = modelGroupRef.getAttribute(ATT_NAME);
	    int index = fStringPool.addSymbol(name);
        return index;
	}
	public int traverseDatatypeDecl(Element datatypeDecl) {
		int newTypeName = fStringPool.addSymbol(datatypeDecl.getAttribute(ATT_NAME));
		int export = fStringPool.addSymbol(datatypeDecl.getAttribute(ATT_EXPORT));
		Element datatypeChild = XUtil.getFirstChildElement(datatypeDecl);
		int basetype = fStringPool.addSymbol(datatypeChild.getNodeName());
		DatatypeValidator baseValidator = fDatatypeRegistry.getValidatorFor(datatypeChild.getAttribute(ATT_NAME));
		if (baseValidator == null) {
			reportSchemaError(SchemaMessageProvider.UnknownBaseDatatype,
							  new Object [] { datatypeChild.getAttribute(ATT_NAME), datatypeDecl.getAttribute(ATT_NAME) });
			return -1;
		}
		int numFacets = 0;
		int numEnumerationLiterals = 0;
		Hashtable facetData = new Hashtable();
		Vector enumData = new Vector();
		Node facet = datatypeChild.getNextSibling();
		while (facet != null) {
			if (facet.getNodeType() == Node.ELEMENT_NODE) {
				numFacets++;
				if (facet.getNodeName().equals(DatatypeValidator.ENUMERATION)) {
					Node literal = XUtil.getFirstChildElement(facet);
					while (literal != null) {
						numEnumerationLiterals++;
						enumData.addElement(literal.getFirstChild().getNodeValue());
						literal = XUtil.getNextSiblingElement(literal);
					}
				} else {
					facetData.put(facet.getNodeName(),facet.getFirstChild().getNodeValue());
				}
			}
			facet = facet.getNextSibling();
		}
		if (numEnumerationLiterals > 0) {
			facetData.put(DatatypeValidator.ENUMERATION, enumData);
		}
		try {
			DatatypeValidator newValidator = (DatatypeValidator) baseValidator.getClass().newInstance();
			if (numFacets > 0)
				newValidator.setFacets(facetData);
			fDatatypeRegistry.addValidator(fStringPool.toString(newTypeName),newValidator);
		} catch (Exception e) {
			reportSchemaError(SchemaMessageProvider.DatatypeError,
							  new Object [] { e.getMessage() });
		}
        return -1;
	}
	private int traverseElementDecl(Element elementDecl) throws Exception {
		int contentSpecType      = -1;
		int contentSpecNodeIndex = -1;
        int typeNameIndex = -1;
		String name = elementDecl.getAttribute(ATT_NAME);
		String ref = elementDecl.getAttribute(ATT_REF);
		String archRef = elementDecl.getAttribute(ATT_ARCHREF);
		String type = elementDecl.getAttribute(ATT_TYPE);
		String schemaAbbrev = elementDecl.getAttribute(ATT_SCHEMAABBREV);
		String schemaName = elementDecl.getAttribute(ATT_SCHEMANAME);
		String minOccurs = elementDecl.getAttribute(ATT_MINOCCURS);
		String maxOccurs = elementDecl.getAttribute(ATT_MAXOCCURS);
		String export = elementDecl.getAttribute(ATT_EXPORT);
        int attrCount = 0;
		if (!ref.equals("")) attrCount++;
		if (!type.equals("")) attrCount++;
		if (!archRef.equals("")) attrCount++;
		if (attrCount > 1)
			reportSchemaError(SchemaMessageProvider.OneOfTypeRefArchRef, null);
		if (!ref.equals("") || !archRef.equals("")) {
		    if (XUtil.getFirstChildElement(elementDecl) != null)
				reportSchemaError(SchemaMessageProvider.NoContentForRef, null);
		   	int typeName = (!ref.equals("")) ? fStringPool.addSymbol(ref) : fStringPool.addSymbol(archRef);
		   	contentSpecNodeIndex = getContentSpec(getElement(typeName));
		   	contentSpecType = getContentSpecType(getElement(typeName));
		   	int elementNameIndex = fStringPool.addSymbol(name);
            int elementIndex = -1;
		   	if (contentSpecNodeIndex == -1) {
		   	    contentSpecType = XMLContentSpecNode.CONTENTSPECNODE_LEAF;
            	contentSpecNodeIndex = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
	        							                                   elementNameIndex, -1, false);
                fElementDeclPool.addElementDecl(elementNameIndex, contentSpecType, contentSpecNodeIndex, true);
				reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
								  new Object [] { "Forward references to archetypes" });
    			Vector v = null;
    			Integer i = new Integer(typeName);
    			if ((v = (Vector) fForwardRefs.get(i)) == null)
    			     v = new Vector();
                v.addElement(new Integer(elementNameIndex));
    			fForwardRefs.put(i,v);
    			addUse(elementNameIndex, typeName);
		   	} else {
                fElementDeclPool.addElementDecl(elementNameIndex, contentSpecType, contentSpecNodeIndex, true);
                fElementDeclPool.copyAtts(typeName, elementNameIndex);
            }
		    return elementNameIndex;
		}
		Element content = XUtil.getFirstChildElement(elementDecl);
		if (content != null) {
			String contentName = content.getNodeName();
			if (contentName.equals(ELT_ARCHETYPEDECL)) {
				typeNameIndex = traverseTypeDecl(content);
				contentSpecNodeIndex = getContentSpec(getElement(typeNameIndex));
				contentSpecType = getContentSpecType(getElement(typeNameIndex));
			} else if (contentName.equals(ELT_DATATYPEDECL)) {
				reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
								  new Object [] { "Nesting datatype declarations" });
			} else if (!type.equals("")) { 
				contentSpecType = fStringPool.addSymbol("DATATYPE");
				contentSpecNodeIndex = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
																		   fStringPool.addSymbol(content.getAttribute(ATT_NAME)),
																		   -1, false);
				contentSpecNodeIndex = expandContentModel(contentSpecNodeIndex, content);
			} else if (type.equals("")) { 
	    		contentSpecType = fStringPool.addSymbol("CHILDREN");
				int leftIndex = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
																	fStringPool.addSymbol(content.getAttribute(ATT_NAME)),
																	-1, false);
	    		contentSpecNodeIndex = expandContentModel(contentSpecNodeIndex, content);
			} else {
				System.out.println("unhandled case in element decl code");
			}
		} else if (!type.equals("")) { 
			contentSpecType = fStringPool.addSymbol("DATATYPE");
			contentSpecNodeIndex = fElementDeclPool.addContentSpecNode(XMLContentSpecNode.CONTENTSPECNODE_LEAF,
																	   fStringPool.addSymbol(type),
																	   -1, false);
			contentSpecNodeIndex = expandContentModel(contentSpecNodeIndex, elementDecl);
		}
		int elementNameIndex     = fStringPool.addSymbol(elementDecl.getAttribute(ATT_NAME));
		int elementIndex = fElementDeclPool.addElementDecl(elementNameIndex, contentSpecType, contentSpecNodeIndex, true);
        fElementDeclPool.copyAtts(typeNameIndex, elementNameIndex);
        return elementNameIndex;
	}
