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

import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException;
import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory;
import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
import com.sun.org.apache.xerces.internal.impl.xs.XSConstraints;
import com.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl;
import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
import com.sun.org.apache.xerces.internal.util.DOMUtil;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
import com.sun.org.apache.xerces.internal.xs.XSConstants;
import com.sun.org.apache.xerces.internal.xs.XSObjectList;
import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
import org.w3c.dom.Element;

/**
 * A complex type definition schema component traverser.
 *
 * <complexType
 *   abstract = boolean : false
 *   block = (#all | List of (extension | restriction))
 *   final = (#all | List of (extension | restriction))
 *   id = ID
 *   mixed = boolean : false
 *   name = NCName
 *   {any attributes with non-schema namespace . . .}>
 *   Content: (annotation?, (simpleContent | complexContent |
 *            ((group | all | choice | sequence)?,
 *            ((attribute | attributeGroup)*, anyAttribute?))))
 * </complexType>
 *
 * @xerces.internal
 *
 */

class  XSDComplexTypeTraverser extends XSDAbstractParticleTraverser {

    // size of stack to hold globals:
    private final static int GLOBAL_NUM = 11;

    private static XSParticleDecl fErrorContent = null;
    private static XSWildcardDecl fErrorWildcard = null;
    private static XSParticleDecl getErrorContent() {
        if (fErrorContent == null) {
            XSParticleDecl particle = new XSParticleDecl();
            particle.fType = XSParticleDecl.PARTICLE_WILDCARD;
            particle.fValue = getErrorWildcard();
            particle.fMinOccurs = 0;
            particle.fMaxOccurs = SchemaSymbols.OCCURRENCE_UNBOUNDED;
            XSModelGroupImpl group = new XSModelGroupImpl();
            group.fCompositor = XSModelGroupImpl.MODELGROUP_SEQUENCE;
            group.fParticleCount = 1;
            group.fParticles = new XSParticleDecl[1];
            group.fParticles[0] = particle;
            XSParticleDecl errorContent = new XSParticleDecl();
            errorContent.fType = XSParticleDecl.PARTICLE_MODELGROUP;
            errorContent.fValue = group;
            fErrorContent = errorContent;
        }
        return fErrorContent;
    }
    private static XSWildcardDecl getErrorWildcard() {
        if (fErrorWildcard == null) {
            XSWildcardDecl wildcard = new XSWildcardDecl();
            wildcard.fProcessContents = XSWildcardDecl.PC_SKIP;
            fErrorWildcard = wildcard;
        }
        return fErrorWildcard;
    }

    // globals for building XSComplexTypeDecls
    private String fName = null;
    private String fTargetNamespace = null;
    private short fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
    private short fFinal = XSConstants.DERIVATION_NONE;
    private short fBlock = XSConstants.DERIVATION_NONE;
    private short fContentType = XSComplexTypeDecl.CONTENTTYPE_EMPTY;
    private XSTypeDefinition fBaseType = null;
    private XSAttributeGroupDecl fAttrGrp = null;
    private XSSimpleType fXSSimpleType = null;
    private XSParticleDecl fParticle = null;
    private boolean fIsAbstract = false;
    private XSComplexTypeDecl fComplexTypeDecl = null;
    private XSAnnotationImpl [] fAnnotations = null;

    // our own little stack to retain state when getGlobalDecls is called:
    private Object [] fGlobalStore = null;
    private int fGlobalStorePos = 0;

    XSDComplexTypeTraverser (XSDHandler handler,
            XSAttributeChecker gAttrCheck) {
        super(handler, gAttrCheck);
    }


    private static final boolean DEBUG=false;

    private static final class ComplexTypeRecoverableError extends Exception {

        private static final long serialVersionUID = 6802729912091130335L;

        Object[] errorSubstText=null;
        Element  errorElem = null;
        ComplexTypeRecoverableError() {
            super();
        }
        ComplexTypeRecoverableError(String msgKey, Object[] args, Element e) {
            super(msgKey);
            errorSubstText=args;
            errorElem = e;
        }

    }

    /**
     * Traverse local complexType declarations
     *
     * @param Element
     * @param XSDocumentInfo
     * @param SchemaGrammar
     * @return XSComplexTypeDecl
     */
    XSComplexTypeDecl traverseLocal(Element complexTypeNode,
            XSDocumentInfo schemaDoc,
            SchemaGrammar grammar) {


        Object[] attrValues = fAttrChecker.checkAttributes(complexTypeNode, false,
                schemaDoc);
        String complexTypeName = genAnonTypeName(complexTypeNode);
        contentBackup();
        XSComplexTypeDecl type = traverseComplexTypeDecl (complexTypeNode,
                complexTypeName, attrValues, schemaDoc, grammar);
        contentRestore();
        // need to add the type to the grammar for later constraint checking
        grammar.addComplexTypeDecl(type, fSchemaHandler.element2Locator(complexTypeNode));
        type.setIsAnonymous();
        fAttrChecker.returnAttrArray(attrValues, schemaDoc);

        return type;
    }

    /**
     * Traverse global complexType declarations
     *
     * @param Element
     * @param XSDocumentInfo
     * @param SchemaGrammar
     * @return XSComplexTypeDecXSComplexTypeDecl
     */
    XSComplexTypeDecl traverseGlobal (Element complexTypeNode,
            XSDocumentInfo schemaDoc,
            SchemaGrammar grammar) {

        Object[] attrValues = fAttrChecker.checkAttributes(complexTypeNode, true,
                schemaDoc);
        String complexTypeName = (String)  attrValues[XSAttributeChecker.ATTIDX_NAME];
        contentBackup();
        XSComplexTypeDecl type = traverseComplexTypeDecl (complexTypeNode,
                complexTypeName, attrValues, schemaDoc, grammar);
        contentRestore();
        // need to add the type to the grammar for later constraint checking
        grammar.addComplexTypeDecl(type, fSchemaHandler.element2Locator(complexTypeNode));

        if (complexTypeName == null) {
            reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_COMPLEXTYPE, SchemaSymbols.ATT_NAME}, complexTypeNode);
            type = null;
        } else {
            if (grammar.getGlobalTypeDecl(type.getName()) == null) {
                grammar.addGlobalComplexTypeDecl(type);
            }

            // also add it to extended map
            final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc);
            final XSTypeDefinition type2 = grammar.getGlobalTypeDecl(type.getName(), loc);
            if (type2 == null) {
                grammar.addGlobalComplexTypeDecl(type, loc);
            }

            // handle duplicates
            if (fSchemaHandler.fTolerateDuplicates) {
                if (type2 != null) {
                    if (type2 instanceof XSComplexTypeDecl) {
                        type = (XSComplexTypeDecl) type2;
                    }
                }
                fSchemaHandler.addGlobalTypeDecl(type);
            }
        }

        fAttrChecker.returnAttrArray(attrValues, schemaDoc);

        return type;
    }


    private XSComplexTypeDecl traverseComplexTypeDecl(Element complexTypeDecl,
            String complexTypeName,
            Object[] attrValues,
            XSDocumentInfo schemaDoc,
            SchemaGrammar grammar) {

        fComplexTypeDecl = new XSComplexTypeDecl();
        fAttrGrp = new XSAttributeGroupDecl();
        Boolean abstractAtt  = (Boolean) attrValues[XSAttributeChecker.ATTIDX_ABSTRACT];
        XInt    blockAtt     = (XInt)    attrValues[XSAttributeChecker.ATTIDX_BLOCK];
        Boolean mixedAtt     = (Boolean) attrValues[XSAttributeChecker.ATTIDX_MIXED];
        XInt    finalAtt     = (XInt)    attrValues[XSAttributeChecker.ATTIDX_FINAL];

        fName = complexTypeName;
        fComplexTypeDecl.setName(fName);
        fTargetNamespace = schemaDoc.fTargetNamespace;

        fBlock = blockAtt == null ? schemaDoc.fBlockDefault : blockAtt.shortValue();
        fFinal = finalAtt == null ? schemaDoc.fFinalDefault : finalAtt.shortValue();
        //discard valid Block/Final 'Default' values that are invalid for Block/Final
        fBlock &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION);
        fFinal &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION);

        fIsAbstract = (abstractAtt != null && abstractAtt.booleanValue());
        fAnnotations = null;

        Element child = null;

        try {
            // ---------------------------------------------------------------
            // First, handle any ANNOTATION declaration and get next child
            // ---------------------------------------------------------------
            child = DOMUtil.getFirstChildElement(complexTypeDecl);
            if(child != null) {
                if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
                    addAnnotation(traverseAnnotationDecl(child, attrValues, false, schemaDoc));
                    child = DOMUtil.getNextSiblingElement(child);
                }
                else {
                    String text = DOMUtil.getSyntheticAnnotation(complexTypeDecl);
                    if (text != null) {
                        addAnnotation(traverseSyntheticAnnotation(complexTypeDecl, text, attrValues, false, schemaDoc));
                    }
                }
                if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
                    throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                            new Object[]{fName,SchemaSymbols.ELT_ANNOTATION},
                            child);
                }
            }
            else {
                String text = DOMUtil.getSyntheticAnnotation(complexTypeDecl);
                if (text != null) {
                    addAnnotation(traverseSyntheticAnnotation(complexTypeDecl, text, attrValues, false, schemaDoc));
                }
            }
            // ---------------------------------------------------------------
            // Process the content of the complex type definition
            // ---------------------------------------------------------------
            if (child==null) {
                //
                // EMPTY complexType with complexContent
                //

                // set the base to the anyType
                fBaseType = SchemaGrammar.fAnyType;
                fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
                processComplexContent(child, mixedAtt.booleanValue(), false,
                        schemaDoc, grammar);
            }
            else if (DOMUtil.getLocalName(child).equals
                    (SchemaSymbols.ELT_SIMPLECONTENT)) {
                //
                // SIMPLE CONTENT
                //
                traverseSimpleContent(child, schemaDoc, grammar);
                Element elemTmp = DOMUtil.getNextSiblingElement(child);
                if (elemTmp != null) {
                    String siblingName = DOMUtil.getLocalName(elemTmp);
                    throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                            new Object[]{fName,siblingName},
                            elemTmp);
                }
            }
            else if (DOMUtil.getLocalName(child).equals
                    (SchemaSymbols.ELT_COMPLEXCONTENT)) {
                traverseComplexContent(child, mixedAtt.booleanValue(),
                        schemaDoc, grammar);
                Element elemTmp = DOMUtil.getNextSiblingElement(child);
                if (elemTmp != null) {
                    String siblingName = DOMUtil.getLocalName(elemTmp);
                    throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                            new Object[]{fName,siblingName},
                            elemTmp);
                }
            }
            else {
                //
                // We must have ....
                // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes
                // Note that it's possible that only attributes are specified.
                //

                // set the base to the anyType
                fBaseType = SchemaGrammar.fAnyType;
                fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
                processComplexContent(child, mixedAtt.booleanValue(), false,
                        schemaDoc, grammar);
            }

        }
        catch (ComplexTypeRecoverableError e) {
            handleComplexTypeError(e.getMessage(), e.errorSubstText,
                    e.errorElem);
        }

        if (DEBUG) {
            System.out.println(fName);
        }
        fComplexTypeDecl.setValues(fName, fTargetNamespace, fBaseType,
                fDerivedBy, fFinal, fBlock, fContentType, fIsAbstract,
                fAttrGrp, fXSSimpleType, fParticle, new XSObjectListImpl(fAnnotations,
                        fAnnotations == null? 0 : fAnnotations.length));
        return fComplexTypeDecl;
    }


    private void traverseSimpleContent(Element simpleContentElement,
            XSDocumentInfo schemaDoc,
            SchemaGrammar grammar)
    throws ComplexTypeRecoverableError {


        Object[] simpleContentAttrValues = fAttrChecker.checkAttributes(simpleContentElement, false,
                schemaDoc);

        // -----------------------------------------------------------------------
        // Set content type
        // -----------------------------------------------------------------------
        fContentType = XSComplexTypeDecl.CONTENTTYPE_SIMPLE;
        fParticle = null;

        Element simpleContent = DOMUtil.getFirstChildElement(simpleContentElement);
        if (simpleContent != null && DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
            addAnnotation(traverseAnnotationDecl(simpleContent, simpleContentAttrValues, false, schemaDoc));
            simpleContent = DOMUtil.getNextSiblingElement(simpleContent);
        }
        else {
            String text = DOMUtil.getSyntheticAnnotation(simpleContentElement);
            if (text != null) {
                addAnnotation(traverseSyntheticAnnotation(simpleContentElement, text, simpleContentAttrValues, false, schemaDoc));
            }
        }

        // If there are no children, return
        if (simpleContent==null) {
            fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.2",
                    new Object[]{fName,SchemaSymbols.ELT_SIMPLECONTENT},
                    simpleContentElement);
        }

        // -----------------------------------------------------------------------
        // The content should be either "restriction" or "extension"
        // -----------------------------------------------------------------------
        String simpleContentName = DOMUtil.getLocalName(simpleContent);
        if (simpleContentName.equals(SchemaSymbols.ELT_RESTRICTION))
            fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
        else if (simpleContentName.equals(SchemaSymbols.ELT_EXTENSION))
            fDerivedBy = XSConstants.DERIVATION_EXTENSION;
        else {
            fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                    new Object[]{fName,simpleContentName},
                    simpleContent);
        }
        Element elemTmp = DOMUtil.getNextSiblingElement(simpleContent);
        if (elemTmp != null) {
            fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
            String siblingName = DOMUtil.getLocalName(elemTmp);
            throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                    new Object[]{fName,siblingName},
                    elemTmp);
        }

        Object [] derivationTypeAttrValues = fAttrChecker.checkAttributes(simpleContent, false,
                schemaDoc);
        QName baseTypeName = (QName)  derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE];


        // -----------------------------------------------------------------------
        // Need a base type.
        // -----------------------------------------------------------------------
        if (baseTypeName==null) {
            fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
            fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError("s4s-att-must-appear",
                    new Object[]{simpleContentName, "base"}, simpleContent);
        }

        XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc,
                XSDHandler.TYPEDECL_TYPE, baseTypeName,
                simpleContent);
        if (type==null) {
            fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
            fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError();
        }

        fBaseType = type;

        XSSimpleType baseValidator = null;
        XSComplexTypeDecl baseComplexType = null;
        int baseFinalSet = 0;

        // If the base type is complex, it must have simpleContent
        if ((type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE)) {

            baseComplexType = (XSComplexTypeDecl)type;
            baseFinalSet = baseComplexType.getFinal();
            // base is a CT with simple content (both restriction and extension are OK)
            if (baseComplexType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_SIMPLE) {
                baseValidator = (XSSimpleType)baseComplexType.getSimpleType();
            }
            // base is a CT with mixed/emptiable content (only restriction is OK)
            else if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION &&
                    baseComplexType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_MIXED &&
                    ((XSParticleDecl)baseComplexType.getParticle()).emptiable()) {
            }
            else {
                fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw new ComplexTypeRecoverableError("src-ct.2.1",
                        new Object[]{fName, baseComplexType.getName()}, simpleContent);
            }
        }
        else {
            baseValidator = (XSSimpleType)type;
            // base is a ST (only extension is OK)
            if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION) {
                fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw new ComplexTypeRecoverableError("src-ct.2.1",
                        new Object[]{fName, baseValidator.getName()}, simpleContent);
            }
            baseFinalSet=baseValidator.getFinal();
        }

        // -----------------------------------------------------------------------
        // Check that the base permits the derivation
        // -----------------------------------------------------------------------
        if ((baseFinalSet & fDerivedBy)!=0) {
            fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
            fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
            String errorKey = (fDerivedBy==XSConstants.DERIVATION_EXTENSION) ?
                    "cos-ct-extends.1.1" : "derivation-ok-restriction.1";
            throw new ComplexTypeRecoverableError(errorKey,
                    new Object[]{fName, fBaseType.getName()}, simpleContent);
        }

        // -----------------------------------------------------------------------
        // Skip over any potential annotations
        // -----------------------------------------------------------------------
        Element scElement = simpleContent;
        simpleContent = DOMUtil.getFirstChildElement(simpleContent);
        if (simpleContent != null) {
            // traverse annotation if any

            if (DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
                addAnnotation(traverseAnnotationDecl(simpleContent, derivationTypeAttrValues, false, schemaDoc));
                simpleContent = DOMUtil.getNextSiblingElement(simpleContent);
            }
            else {
                String text = DOMUtil.getSyntheticAnnotation(scElement);
                if (text != null) {
                    addAnnotation(traverseSyntheticAnnotation(scElement, text, derivationTypeAttrValues, false, schemaDoc));
                }
            }

            if (simpleContent !=null &&
                    DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)){
                fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                        new Object[]{fName,SchemaSymbols.ELT_ANNOTATION},
                        simpleContent);
            }
        }
        else {
            String text = DOMUtil.getSyntheticAnnotation(scElement);
            if (text != null) {
                addAnnotation(traverseSyntheticAnnotation(scElement, text, derivationTypeAttrValues, false, schemaDoc));
            }
        }

        // -----------------------------------------------------------------------
        // Process a RESTRICTION
        // -----------------------------------------------------------------------
        if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION) {

            // -----------------------------------------------------------------------
            // There may be a simple type definition in the restriction element
            // The data type validator will be based on it, if specified
            // -----------------------------------------------------------------------
            if (simpleContent !=null &&
                    DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_SIMPLETYPE )) {

                XSSimpleType dv = fSchemaHandler.fSimpleTypeTraverser.traverseLocal(
                        simpleContent, schemaDoc, grammar);
                if (dv == null) {
                    fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError();
                }
                //check that this datatype validator is validly derived from the base
                //according to derivation-ok-restriction 5.1.2.1

                if (baseValidator != null &&
                        !XSConstraints.checkSimpleDerivationOk(dv, baseValidator,
                                baseValidator.getFinal())) {
                    fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.2.2.1",
                            new Object[]{fName, dv.getName(), baseValidator.getName()},
                            simpleContent);
                }
                baseValidator = dv;
                simpleContent = DOMUtil.getNextSiblingElement(simpleContent);
            }

            // this only happens when restricting a mixed/emptiable CT
            // but there is no <simpleType>, which is required
            if (baseValidator == null) {
                fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw new ComplexTypeRecoverableError("src-ct.2.2",
                        new Object[]{fName}, simpleContent);
            }

            // -----------------------------------------------------------------------
            // Traverse any facets
            // -----------------------------------------------------------------------
            Element attrNode = null;
            XSFacets facetData = null;
            short presentFacets = 0 ;
            short fixedFacets = 0 ;

            if (simpleContent!=null) {
                FacetInfo fi = traverseFacets(simpleContent, baseValidator, schemaDoc);
                attrNode = fi.nodeAfterFacets;
                facetData = fi.facetdata;
                presentFacets = fi.fPresentFacets;
                fixedFacets = fi.fFixedFacets;
            }

            String name = genAnonTypeName(simpleContentElement);
            fXSSimpleType = fSchemaHandler.fDVFactory.createTypeRestriction(name,schemaDoc.fTargetNamespace,(short)0,baseValidator,null);
            try{
                fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport);
                fXSSimpleType.applyFacets(facetData, presentFacets, fixedFacets, fValidationState);
            }catch(InvalidDatatypeFacetException ex){
                reportSchemaError(ex.getKey(), ex.getArgs(), simpleContent);
                // Recreate the type, ignoring the facets
                fXSSimpleType = fSchemaHandler.fDVFactory.createTypeRestriction(name,schemaDoc.fTargetNamespace,(short)0,baseValidator,null);
            }
            if (fXSSimpleType instanceof XSSimpleTypeDecl) {
                ((XSSimpleTypeDecl)fXSSimpleType).setAnonymous(true);
            }

            // -----------------------------------------------------------------------
            // Traverse any attributes
            // -----------------------------------------------------------------------
            if (attrNode != null) {
                if (!isAttrOrAttrGroup(attrNode)) {
                    fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                            new Object[]{fName,DOMUtil.getLocalName(attrNode)},
                            attrNode);
                }
                Element node=traverseAttrsAndAttrGrps(attrNode,fAttrGrp,
                        schemaDoc,grammar,fComplexTypeDecl);
                if (node!=null) {
                    fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                            new Object[]{fName,DOMUtil.getLocalName(node)},
                            node);
                }
            }

            try {
                mergeAttributes(baseComplexType.getAttrGrp(), fAttrGrp, fName, false, simpleContentElement);
            } catch (ComplexTypeRecoverableError e) {
                fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw e;
            }
            // Prohibited uses must be removed after merge for RESTRICTION
            fAttrGrp.removeProhibitedAttrs();

            Object[] errArgs=fAttrGrp.validRestrictionOf(fName, baseComplexType.getAttrGrp());
            if (errArgs != null) {
                fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw new ComplexTypeRecoverableError((String)errArgs[errArgs.length-1],
                        errArgs, attrNode);
            }

        }
        // -----------------------------------------------------------------------
        // Process a EXTENSION
        // -----------------------------------------------------------------------
        else {
            fXSSimpleType = baseValidator;
            if (simpleContent != null) {
                // -----------------------------------------------------------------------
                // Traverse any attributes
                // -----------------------------------------------------------------------
                Element attrNode = simpleContent;
                if (!isAttrOrAttrGroup(attrNode)) {
                    fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                            new Object[]{fName,DOMUtil.getLocalName(attrNode)},
                            attrNode);
                }
                Element node=traverseAttrsAndAttrGrps(attrNode,fAttrGrp,
                        schemaDoc,grammar,fComplexTypeDecl);

                if (node!=null) {
                    fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                            new Object[]{fName,DOMUtil.getLocalName(node)},
                            node);
                }
                // Remove prohibited uses.   Should be done prior to any merge.
                fAttrGrp.removeProhibitedAttrs();
            }

            if (baseComplexType != null) {
                try {
                    mergeAttributes(baseComplexType.getAttrGrp(), fAttrGrp, fName, true, simpleContentElement);
                } catch (ComplexTypeRecoverableError e) {
                    fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw e;
                }
            }
        }
        // and finally, since we've nothing more to traverse, we can
        // return the attributes (and thereby reset the namespace support)
        fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc);
        fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
    }

    private void traverseComplexContent(Element complexContentElement,
            boolean mixedOnType, XSDocumentInfo schemaDoc,
            SchemaGrammar grammar)
    throws ComplexTypeRecoverableError {


        Object[] complexContentAttrValues = fAttrChecker.checkAttributes(complexContentElement, false,
                schemaDoc);


        // -----------------------------------------------------------------------
        // Determine if this is mixed content
        // -----------------------------------------------------------------------
        boolean mixedContent = mixedOnType;
        Boolean mixedAtt     = (Boolean) complexContentAttrValues[XSAttributeChecker.ATTIDX_MIXED];
        if (mixedAtt != null) {
            mixedContent = mixedAtt.booleanValue();
        }


        // -----------------------------------------------------------------------
        // Since the type must have complex content, set the simple type validators
        // to null
        // -----------------------------------------------------------------------
        fXSSimpleType = null;

        Element complexContent = DOMUtil.getFirstChildElement(complexContentElement);
        if (complexContent != null && DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
            addAnnotation(traverseAnnotationDecl(complexContent, complexContentAttrValues, false, schemaDoc));
            complexContent = DOMUtil.getNextSiblingElement(complexContent);
        }
        else {
            String text = DOMUtil.getSyntheticAnnotation(complexContentElement);
            if (text != null) {
                addAnnotation(traverseSyntheticAnnotation(complexContentElement, text, complexContentAttrValues, false, schemaDoc));
            }
        }

        // If there are no children, return
        if (complexContent==null) {
            fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.2",
                    new Object[]{fName,SchemaSymbols.ELT_COMPLEXCONTENT},
                    complexContentElement);
        }

        // -----------------------------------------------------------------------
        // The content should be either "restriction" or "extension"
        // -----------------------------------------------------------------------
        String complexContentName = DOMUtil.getLocalName(complexContent);
        if (complexContentName.equals(SchemaSymbols.ELT_RESTRICTION))
            fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
        else if (complexContentName.equals(SchemaSymbols.ELT_EXTENSION))
            fDerivedBy = XSConstants.DERIVATION_EXTENSION;
        else {
            fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                    new Object[]{fName, complexContentName}, complexContent);
        }
        Element elemTmp = DOMUtil.getNextSiblingElement(complexContent);
        if (elemTmp != null) {
            fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
            String siblingName = DOMUtil.getLocalName(elemTmp);
            throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                    new Object[]{fName, siblingName}, elemTmp);
        }

        Object[] derivationTypeAttrValues = fAttrChecker.checkAttributes(complexContent, false,
                schemaDoc);
        QName baseTypeName = (QName)  derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE];


        // -----------------------------------------------------------------------
        // Need a base type.  Check that it's a complex type
        // -----------------------------------------------------------------------
        if (baseTypeName==null) {
            fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
            fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError("s4s-att-must-appear",
                    new Object[]{complexContentName, "base"}, complexContent);
        }

        XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc,
                XSDHandler.TYPEDECL_TYPE,
                baseTypeName,
                complexContent);

        if (type==null) {
            fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
            fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError();
        }

        if (! (type instanceof XSComplexTypeDecl)) {
            fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
            fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
            throw new ComplexTypeRecoverableError("src-ct.1",
                    new Object[]{fName, type.getName()}, complexContent);
        }
        XSComplexTypeDecl baseType = (XSComplexTypeDecl)type;
        fBaseType = baseType;

        // -----------------------------------------------------------------------
        // Check that the base permits the derivation
        // -----------------------------------------------------------------------
        if ((baseType.getFinal() & fDerivedBy)!=0) {
            fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
            fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
            String errorKey = (fDerivedBy==XSConstants.DERIVATION_EXTENSION) ?
                    "cos-ct-extends.1.1" : "derivation-ok-restriction.1";
            throw new ComplexTypeRecoverableError(errorKey,
                    new Object[]{fName, fBaseType.getName()}, complexContent);
        }

        // -----------------------------------------------------------------------
        // Skip over any potential annotations
        // -----------------------------------------------------------------------
        complexContent = DOMUtil.getFirstChildElement(complexContent);

        if (complexContent != null) {
            // traverse annotation if any
            if (DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
                addAnnotation(traverseAnnotationDecl(complexContent, derivationTypeAttrValues, false, schemaDoc));
                complexContent = DOMUtil.getNextSiblingElement(complexContent);
            }
            else {
                String text = DOMUtil.getSyntheticAnnotation(complexContent);
                if (text != null) {
                    addAnnotation(traverseSyntheticAnnotation(complexContent, text, derivationTypeAttrValues, false, schemaDoc));
                }
            }
            if (complexContent !=null &&
                    DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)){
                fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                        new Object[]{fName,SchemaSymbols.ELT_ANNOTATION}, complexContent);
            }
        }
        else {
            String text = DOMUtil.getSyntheticAnnotation(complexContent);
            if (text != null) {
                addAnnotation(traverseSyntheticAnnotation(complexContent, text, derivationTypeAttrValues, false, schemaDoc));
            }
        }
        // -----------------------------------------------------------------------
        // Process the content.  Note:  should I try to catch any complexType errors
        // here in order to return the attr array?
        // -----------------------------------------------------------------------
        try {
            processComplexContent(complexContent, mixedContent, true, schemaDoc,
                    grammar);
        } catch (ComplexTypeRecoverableError e) {
            fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
            fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
            throw e;
        }

        // -----------------------------------------------------------------------
        // Compose the final content and attribute uses
        // -----------------------------------------------------------------------
        XSParticleDecl baseContent = (XSParticleDecl)baseType.getParticle();
        if (fDerivedBy==XSConstants.DERIVATION_RESTRICTION) {

            // This is an RESTRICTION

            // N.B. derivation-ok-restriction.5.3 is checked under schema
            // full checking.   That's because we need to wait until locals are
            // traversed so that occurrence information is correct.


            if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED &&
                    baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) {
                fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.4.1.2",
                        new Object[]{fName, baseType.getName()},
                        complexContent);
            }

            try {
                mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, false, complexContent);
            } catch (ComplexTypeRecoverableError e) {
                fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw e;
            }
            // Remove prohibited uses.   Must be done after merge for RESTRICTION.
            fAttrGrp.removeProhibitedAttrs();

            if (baseType != SchemaGrammar.fAnyType) {
                Object[] errArgs = fAttrGrp.validRestrictionOf(fName, baseType.getAttrGrp());
                if (errArgs != null) {
                    fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError((String)errArgs[errArgs.length-1],
                            errArgs, complexContent);
                }
            }
        }
        else {

            // This is an EXTENSION

            // Create the particle
            if (fParticle == null) {
                fContentType = baseType.getContentType();
                fXSSimpleType = (XSSimpleType)baseType.getSimpleType();
                fParticle = baseContent;
            }
            else if (baseType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_EMPTY) {
            }
            else {
                //
                // Check if the contentType of the base is consistent with the new type
                // cos-ct-extends.1.4.3.2
                if (fContentType == XSComplexTypeDecl.CONTENTTYPE_ELEMENT &&
                        baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_ELEMENT) {
                    fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.a",
                            new Object[]{fName}, complexContent);
                }
                else if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED &&
                        baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) {
                    fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.b",
                            new Object[]{fName}, complexContent);
                }

                // if the content of either type is an "all" model group, error.
                if (fParticle.fType == XSParticleDecl.PARTICLE_MODELGROUP &&
                        ((XSModelGroupImpl)fParticle.fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL ||
                        ((XSParticleDecl)baseType.getParticle()).fType == XSParticleDecl.PARTICLE_MODELGROUP &&
                        ((XSModelGroupImpl)(((XSParticleDecl)baseType.getParticle())).fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL) {
                    fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
                    fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                    throw new ComplexTypeRecoverableError("cos-all-limited.1.2",
                            new Object[]{}, complexContent);
                }
                // the "sequence" model group to contain both particles
                XSModelGroupImpl group = new XSModelGroupImpl();
                group.fCompositor = XSModelGroupImpl.MODELGROUP_SEQUENCE;
                group.fParticleCount = 2;
                group.fParticles = new XSParticleDecl[2];
                group.fParticles[0] = (XSParticleDecl)baseType.getParticle();
                group.fParticles[1] = fParticle;
                group.fAnnotations = XSObjectListImpl.EMPTY_LIST;
                // the particle to contain the above sequence
                XSParticleDecl particle = new XSParticleDecl();
                particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
                particle.fValue = group;
                particle.fAnnotations = XSObjectListImpl.EMPTY_LIST;

                fParticle = particle;
            }

            // Remove prohibited uses.   Must be done before merge for EXTENSION.
            fAttrGrp.removeProhibitedAttrs();
            try {
                mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, true, complexContent);
            } catch (ComplexTypeRecoverableError e) {
                fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
                fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
                throw e;
            }

        }

        // and *finally* we can legitimately return the attributes!
        fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
        fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);

    } // end of traverseComplexContent


    // This method merges attribute uses from the base, into the derived set.
    // LM: may want to merge with attributeGroup processing.
    private void mergeAttributes(XSAttributeGroupDecl fromAttrGrp,
            XSAttributeGroupDecl toAttrGrp,
            String typeName,
            boolean extension,
            Element elem)
    throws ComplexTypeRecoverableError {

        XSObjectList attrUseS = fromAttrGrp.getAttributeUses();
        XSAttributeUseImpl oneAttrUse = null;
        int attrCount = attrUseS.getLength();
        for (int i=0; i<attrCount; i++) {
            oneAttrUse = (XSAttributeUseImpl)attrUseS.item(i);
            XSAttributeUse existingAttrUse = toAttrGrp.getAttributeUse(oneAttrUse.fAttrDecl.getNamespace(),
                    oneAttrUse.fAttrDecl.getName());
            if (existingAttrUse == null) {

                String idName = toAttrGrp.addAttributeUse(oneAttrUse);
                if (idName != null) {
                    throw new ComplexTypeRecoverableError("ct-props-correct.5",
                            new Object[]{typeName, idName, oneAttrUse.fAttrDecl.getName()},
                            elem);
                }
            }
            else if (existingAttrUse != oneAttrUse) {
                if (extension) {
                    reportSchemaError("ct-props-correct.4",
                            new Object[]{typeName, oneAttrUse.fAttrDecl.getName()},
                            elem);
                    // Recover by using the attribute use from the base type,
                    // to make the resulting schema "more valid".
                    toAttrGrp.replaceAttributeUse(existingAttrUse, oneAttrUse);
                }
            }
        }
        // For extension, the wildcard must be formed by doing a union of the wildcards
        if (extension) {
            if (toAttrGrp.fAttributeWC==null) {
                toAttrGrp.fAttributeWC = fromAttrGrp.fAttributeWC;
            }
            else if (fromAttrGrp.fAttributeWC != null) {
                toAttrGrp.fAttributeWC = toAttrGrp.fAttributeWC.performUnionWith(fromAttrGrp.fAttributeWC, toAttrGrp.fAttributeWC.fProcessContents);
                if (toAttrGrp.fAttributeWC == null) {
                    // REVISIT: XML Schema 1.0 2nd edition doesn't actually specify this constraint. It's a bug in the spec
                    // which will eventually be fixed. We're just guessing what the error code will be. If it turns out to be
                    // something else we'll need to change it. -- mrglavas
                    throw new ComplexTypeRecoverableError("src-ct.5", new Object[]{typeName}, elem);
                }
            }

        }
    }

    private void processComplexContent(Element complexContentChild,
            boolean isMixed, boolean isDerivation,
            XSDocumentInfo schemaDoc, SchemaGrammar grammar)
    throws ComplexTypeRecoverableError {

        Element attrNode = null;
        XSParticleDecl particle = null;

        // whether there is a particle with empty model group
        boolean emptyParticle = false;
        if (complexContentChild != null) {
            // -------------------------------------------------------------
            // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified.
            // Note that it's possible that only attributes are specified.
            // -------------------------------------------------------------


            String childName = DOMUtil.getLocalName(complexContentChild);

            if (childName.equals(SchemaSymbols.ELT_GROUP)) {

                particle = fSchemaHandler.fGroupTraverser.traverseLocal(complexContentChild,
                        schemaDoc, grammar);
                attrNode = DOMUtil.getNextSiblingElement(complexContentChild);
            }
            else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
                particle = traverseSequence(complexContentChild,schemaDoc,grammar,
                        NOT_ALL_CONTEXT,fComplexTypeDecl);
                if (particle != null) {
                    XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue;
                    if (group.fParticleCount == 0)
                        emptyParticle = true;
                }
                attrNode = DOMUtil.getNextSiblingElement(complexContentChild);
            }
            else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
                particle = traverseChoice(complexContentChild,schemaDoc,grammar,
                        NOT_ALL_CONTEXT,fComplexTypeDecl);
                if (particle != null && particle.fMinOccurs == 0) {
                    XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue;
                    if (group.fParticleCount == 0)
                        emptyParticle = true;
                }
                attrNode = DOMUtil.getNextSiblingElement(complexContentChild);
            }
            else if (childName.equals(SchemaSymbols.ELT_ALL)) {
                particle = traverseAll(complexContentChild,schemaDoc,grammar,
                        PROCESSING_ALL_GP,fComplexTypeDecl);
                if (particle != null) {
                    XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue;
                    if (group.fParticleCount == 0)
                        emptyParticle = true;
                }
                attrNode = DOMUtil.getNextSiblingElement(complexContentChild);
            }
            else {
                // Should be attributes here - will check below...
                attrNode = complexContentChild;
            }
        }

        // if the particle is empty because there is no non-annotation chidren,
        // we need to make the particle itself null (so that the effective
        // content is empty).
        if (emptyParticle) {
            // get the first child
            Element child = DOMUtil.getFirstChildElement(complexContentChild);
            // if it's annotation, get the next one
            if (child != null) {
                if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
                    child = DOMUtil.getNextSiblingElement(child);
                }
            }
            // if there is no (non-annotation) children, mark particle empty
            if (child == null)
                particle = null;
            // child != null means we might have seen an element with
            // minOccurs == maxOccurs == 0
        }

        if (particle == null && isMixed) {
            particle = XSConstraints.getEmptySequence();
        }
        fParticle = particle;

        // -----------------------------------------------------------------------
        // Set the content type
        // -----------------------------------------------------------------------
        if (fParticle == null)
            fContentType = XSComplexTypeDecl.CONTENTTYPE_EMPTY;
        else if (isMixed)
            fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED;
        else
            fContentType = XSComplexTypeDecl.CONTENTTYPE_ELEMENT;


        // -------------------------------------------------------------
        // Now, process attributes
        // -------------------------------------------------------------
        if (attrNode != null) {
            if (!isAttrOrAttrGroup(attrNode)) {
                throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                        new Object[]{fName,DOMUtil.getLocalName(attrNode)},
                        attrNode);
            }
            Element node =
                traverseAttrsAndAttrGrps(attrNode,fAttrGrp,schemaDoc,grammar,fComplexTypeDecl);
            if (node!=null) {
                throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
                        new Object[]{fName,DOMUtil.getLocalName(node)},
                        node);
            }
            // Only remove prohibited attribute uses if this isn't a derived type
            // Derivation-specific code worries about this elsewhere
            if (!isDerivation) {
                fAttrGrp.removeProhibitedAttrs();
            }
        }



    } // end processComplexContent


    private boolean isAttrOrAttrGroup(Element e) {
        String elementName = DOMUtil.getLocalName(e);

        if (elementName.equals(SchemaSymbols.ELT_ATTRIBUTE) ||
                elementName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) ||
                elementName.equals(SchemaSymbols.ELT_ANYATTRIBUTE))
            return true;
        else
            return false;
    }

    private void traverseSimpleContentDecl(Element simpleContentDecl) {
    }

    private void traverseComplexContentDecl(Element complexContentDecl,
            boolean mixedOnComplexTypeDecl) {
    }

    /*
     * Generate a name for an anonymous type
     */
    private String genAnonTypeName(Element complexTypeDecl) {

        // Generate a unique name for the anonymous type by concatenating together the
        // names of parent nodes
        // The name is quite good for debugging/error purposes, but we may want to
        // revisit how this is done for performance reasons (LM).
        StringBuffer typeName = new StringBuffer("#AnonType_");
        Element node = DOMUtil.getParent(complexTypeDecl);
        while (node != null && (node != DOMUtil.getRoot(DOMUtil.getDocument(node)))) {
            typeName.append(node.getAttribute(SchemaSymbols.ATT_NAME));
            node = DOMUtil.getParent(node);
        }
        return typeName.toString();
    }


    private void handleComplexTypeError(String messageId,Object[] args,
            Element e) {

        if (messageId!=null) {
            reportSchemaError(messageId, args, e);
        }

        //
        //  Mock up the typeInfo structure so that there won't be problems during
        //  validation
        //
        fBaseType = SchemaGrammar.fAnyType;
        fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED;
        fXSSimpleType = null;
        fParticle = getErrorContent();
        // REVISIT: do we need to remove all attribute uses already added into
        // the attribute group? maybe it's ok to leave them there. -SG
        fAttrGrp.fAttributeWC = getErrorWildcard();

        return;

    }

    private void contentBackup() {
        if(fGlobalStore == null) {
            fGlobalStore = new Object [GLOBAL_NUM];
            fGlobalStorePos = 0;
        }
        if(fGlobalStorePos == fGlobalStore.length) {
            Object [] newArray = new Object[fGlobalStorePos+GLOBAL_NUM];
            System.arraycopy(fGlobalStore, 0, newArray, 0, fGlobalStorePos);
            fGlobalStore = newArray;
        }
        fGlobalStore[fGlobalStorePos++] = fComplexTypeDecl;
        fGlobalStore[fGlobalStorePos++] = fIsAbstract?Boolean.TRUE:Boolean.FALSE;
        fGlobalStore[fGlobalStorePos++] = fName ;
        fGlobalStore[fGlobalStorePos++] = fTargetNamespace;
        // let's save ourselves a couple of objects...
        fGlobalStore[fGlobalStorePos++] = new Integer((fDerivedBy << 16) + fFinal);
        fGlobalStore[fGlobalStorePos++] = new Integer((fBlock << 16) + fContentType);
        fGlobalStore[fGlobalStorePos++] = fBaseType;
        fGlobalStore[fGlobalStorePos++] = fAttrGrp;
        fGlobalStore[fGlobalStorePos++] = fParticle;
        fGlobalStore[fGlobalStorePos++] = fXSSimpleType;
        fGlobalStore[fGlobalStorePos++] = fAnnotations;
    }

    private void contentRestore() {
        fAnnotations = (XSAnnotationImpl [])fGlobalStore[--fGlobalStorePos];
        fXSSimpleType = (XSSimpleType)fGlobalStore[--fGlobalStorePos];
        fParticle = (XSParticleDecl)fGlobalStore[--fGlobalStorePos];
        fAttrGrp = (XSAttributeGroupDecl)fGlobalStore[--fGlobalStorePos];
        fBaseType = (XSTypeDefinition)fGlobalStore[--fGlobalStorePos];
        int i = ((Integer)(fGlobalStore[--fGlobalStorePos])).intValue();
        fBlock = (short)(i >> 16);
        fContentType = (short)i;
        i = ((Integer)(fGlobalStore[--fGlobalStorePos])).intValue();
        fDerivedBy = (short)(i >> 16);
        fFinal = (short)i;
        fTargetNamespace = (String)fGlobalStore[--fGlobalStorePos];
        fName = (String)fGlobalStore[--fGlobalStorePos];
        fIsAbstract = ((Boolean)fGlobalStore[--fGlobalStorePos]).booleanValue();
        fComplexTypeDecl = (XSComplexTypeDecl)fGlobalStore[--fGlobalStorePos];
    }

    private void addAnnotation(XSAnnotationImpl annotation) {
        if(annotation == null)
            return;
        // it isn't very likely that there will be more than one annotation
        // in a complexType decl.  This saves us fromhaving to push/pop
        // one more object from the fGlobalStore, and that's bound
        // to be a savings for most applications
        if(fAnnotations == null) {
            fAnnotations = new XSAnnotationImpl[1];
        } else {
            XSAnnotationImpl [] tempArray = new XSAnnotationImpl[fAnnotations.length + 1];
            System.arraycopy(fAnnotations, 0, tempArray, 0, fAnnotations.length);
            fAnnotations = tempArray;
        }
        fAnnotations[fAnnotations.length-1] = annotation;
    }
}
