content: /*
   *  This file is part of AndroidIDE.
   *
   *  AndroidIDE is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation, either version 3 of the License, or
   *  (at your option) any later version.
   *
   *  AndroidIDE is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *   along with AndroidIDE.  If not, see <https://www.gnu.org/licenses/>.
   */
  
  /*
   * 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 jaxp.sun.org.apache.xerces.internal.impl.xs.traversers;
  
  import jaxp.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException;
  import jaxp.sun.org.apache.xerces.internal.impl.dv.XSFacets;
  import jaxp.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
  import jaxp.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XSConstraints;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XSModelGroupImpl;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.util.XInt;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
  import jaxp.sun.org.apache.xerces.internal.util.DOMUtil;
  import jaxp.sun.org.apache.xerces.internal.xni.QName;
  import jaxp.sun.org.apache.xerces.internal.xs.XSAttributeUse;
  import jaxp.sun.org.apache.xerces.internal.xs.XSConstants;
  import jaxp.sun.org.apache.xerces.internal.xs.XSObjectList;
  import jaxp.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
   *
   * @version $Id: XSDComplexTypeTraverser.java,v 1.8 2010-11-01 04:40:02 joehw Exp $
   */
  
  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;
      }
  }
  