private XSSimpleType errorType(String name, String namespace, short refType) {
    switch (refType) {
      case XSConstants.DERIVATION_RESTRICTION:
        return schemaFactory.createTypeRestriction(
            name, namespace, (short) 0, SchemaGrammar.fAnySimpleType, null);
      case XSConstants.DERIVATION_LIST:
        return schemaFactory.createTypeList(
            name, namespace, (short) 0, SchemaGrammar.fAnySimpleType, null);
      case XSConstants.DERIVATION_UNION:
        return schemaFactory.createTypeUnion(
            name, namespace, (short) 0, new XSSimpleType[] {SchemaGrammar.fAnySimpleType}, null);
    }

    return null;
  }
  private XSSimpleType traverseSimpleTypeDecl(
      Element simpleTypeDecl,
      Object[] attrValues,
      XSDocumentInfo schemaDoc,
      SchemaGrammar grammar) {

    // get name and final values
    String name = (String) attrValues[XSAttributeChecker.ATTIDX_NAME];
    XInt finalAttr = (XInt) attrValues[XSAttributeChecker.ATTIDX_FINAL];
    int finalProperty = finalAttr == null ? schemaDoc.fFinalDefault : finalAttr.intValue();

    // annotation?,(list|restriction|union)
    Element child = DOMUtil.getFirstChildElement(simpleTypeDecl);
    XSAnnotationImpl[] annotations = null;
    if (child != null) {
      // traverse annotation if any
      if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
        XSAnnotationImpl annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
        if (annotation != null) annotations = new XSAnnotationImpl[] {annotation};
        child = DOMUtil.getNextSiblingElement(child);
      }
    }

    // (list|restriction|union)
    if (child == null) {
      reportSchemaError(
          "s4s-elt-must-match.2",
          new Object[] {
            SchemaSymbols.ELT_SIMPLETYPE, "(annotation?, (restriction | list | union))"
          },
          simpleTypeDecl);
      return errorType(name, schemaDoc.fTargetNamespace, XSConstants.DERIVATION_RESTRICTION);
    }

    // derivation type: restriction/list/union
    String varietyProperty = DOMUtil.getLocalName(child);
    short refType = XSConstants.DERIVATION_RESTRICTION;
    boolean restriction = false, list = false, union = false;
    if (varietyProperty.equals(SchemaSymbols.ELT_RESTRICTION)) {
      refType = XSConstants.DERIVATION_RESTRICTION;
      restriction = true;
    } else if (varietyProperty.equals(SchemaSymbols.ELT_LIST)) {
      refType = XSConstants.DERIVATION_LIST;
      list = true;
    } else if (varietyProperty.equals(SchemaSymbols.ELT_UNION)) {
      refType = XSConstants.DERIVATION_UNION;
      union = true;
    } else {
      reportSchemaError(
          "s4s-elt-must-match.1",
          new Object[] {
            SchemaSymbols.ELT_SIMPLETYPE,
            "(annotation?, (restriction | list | union))",
            varietyProperty
          },
          simpleTypeDecl);
      return errorType(name, schemaDoc.fTargetNamespace, XSConstants.DERIVATION_RESTRICTION);
    }

    // nothing should follow this element
    Element nextChild = DOMUtil.getNextSiblingElement(child);
    if (nextChild != null) {
      reportSchemaError(
          "s4s-elt-must-match.1",
          new Object[] {
            SchemaSymbols.ELT_SIMPLETYPE,
            "(annotation?, (restriction | list | union))",
            DOMUtil.getLocalName(nextChild)
          },
          nextChild);
    }

    // General Attribute Checking: get base/item/member types
    Object[] contentAttrs = fAttrChecker.checkAttributes(child, false, schemaDoc);
    QName baseTypeName =
        (QName)
            contentAttrs[
                restriction ? XSAttributeChecker.ATTIDX_BASE : XSAttributeChecker.ATTIDX_ITEMTYPE];
    Vector memberTypes = (Vector) contentAttrs[XSAttributeChecker.ATTIDX_MEMBERTYPES];

    // content = {annotation?,simpleType?...}
    Element content = DOMUtil.getFirstChildElement(child);

    // check content (annotation?, ...)
    if (content != null) {
      // traverse annotation if any
      if (DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_ANNOTATION)) {
        XSAnnotationImpl annotation =
            traverseAnnotationDecl(content, contentAttrs, false, schemaDoc);
        if (annotation != null) {
          if (annotations == null) annotations = new XSAnnotationImpl[] {annotation};
          else {
            XSAnnotationImpl[] tempArray = new XSAnnotationImpl[2];
            tempArray[0] = annotations[0];
            annotations = tempArray;
            annotations[1] = annotation;
          }
        }
        content = DOMUtil.getNextSiblingElement(content);
      }
    }

    // get base type from "base" attribute
    XSSimpleType baseValidator = null;
    if ((restriction || list) && baseTypeName != null) {
      baseValidator = findDTValidator(child, name, baseTypeName, refType, schemaDoc);
      // if its the built-in type, return null from here
      if (baseValidator == null && fIsBuiltIn) {
        fIsBuiltIn = false;
        return null;
      }
    }

    // get types from "memberTypes" attribute
    Vector dTValidators = null;
    XSSimpleType dv = null;
    XSObjectList dvs;
    if (union && memberTypes != null && memberTypes.size() > 0) {
      int size = memberTypes.size();
      dTValidators = new Vector(size, 2);
      // for each qname in the list
      for (int i = 0; i < size; i++) {
        // get the type decl
        dv =
            findDTValidator(
                child,
                name,
                (QName) memberTypes.elementAt(i),
                XSConstants.DERIVATION_UNION,
                schemaDoc);
        if (dv != null) {
          // if it's a union, expand it
          if (dv.getVariety() == XSSimpleType.VARIETY_UNION) {
            dvs = dv.getMemberTypes();
            for (int j = 0; j < dvs.getLength(); j++) dTValidators.addElement(dvs.item(j));
          } else {
            dTValidators.addElement(dv);
          }
        }
      }
    }

    // when there is an error finding the base type of a restriction
    // we use anySimpleType as the base, then we should skip the facets,
    // because anySimpleType doesn't recognize any facet.
    boolean skipFacets = false;

    // check if there is a child "simpleType"
    if (content != null && DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_SIMPLETYPE)) {
      if (restriction || list) {
        // it's an error for both "base" and "simpleType" to appear
        if (baseTypeName != null) {
          reportSchemaError(list ? "src-simple-type.3.a" : "src-simple-type.2.a", null, content);
        } else {
          // traver this child to get the base type
          baseValidator = traverseLocal(content, schemaDoc, grammar);
        }
        // get the next element
        content = DOMUtil.getNextSiblingElement(content);
      } else if (union) {
        if (dTValidators == null) {
          dTValidators = new Vector(2, 2);
        }
        do {
          // traver this child to get the member type
          dv = traverseLocal(content, schemaDoc, grammar);
          if (dv != null) {
            // if it's a union, expand it
            if (dv.getVariety() == XSSimpleType.VARIETY_UNION) {
              dvs = dv.getMemberTypes();
              for (int j = 0; j < dvs.getLength(); j++) dTValidators.addElement(dvs.item(j));
            } else {
              dTValidators.addElement(dv);
            }
          }
          // get the next element
          content = DOMUtil.getNextSiblingElement(content);
        } while (content != null
            && DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_SIMPLETYPE));
      }
    } else if ((restriction || list) && baseTypeName == null) {
      // it's an error if neither "base" nor "simpleType" appears
      reportSchemaError(list ? "src-simple-type.3.b" : "src-simple-type.2.b", null, child);
      // base can't be found, skip the facets.
      skipFacets = true;
      baseValidator = SchemaGrammar.fAnySimpleType;
    } else if (union && (memberTypes == null || memberTypes.size() == 0)) {
      // it's an error if "memberTypes" is empty and no "simpleType" appears
      reportSchemaError("src-union-memberTypes-or-simpleTypes", null, child);
      dTValidators = new Vector(1);
      dTValidators.addElement(SchemaGrammar.fAnySimpleType);
    }

    // error finding "base" or error traversing "simpleType".
    // don't need to report an error, since some error has been reported.
    if ((restriction || list) && baseValidator == null) {
      baseValidator = SchemaGrammar.fAnySimpleType;
    }
    // error finding "memberTypes" or error traversing "simpleType".
    // don't need to report an error, since some error has been reported.
    if (union && (dTValidators == null || dTValidators.size() == 0)) {
      dTValidators = new Vector(1);
      dTValidators.addElement(SchemaGrammar.fAnySimpleType);
    }

    // item type of list types can't have list content
    if (list && isListDatatype(baseValidator)) {
      reportSchemaError(
          "cos-st-restricts.2.1", new Object[] {name, baseValidator.getName()}, child);
    }

    // create the simple type based on the "base" type
    XSSimpleType newDecl = null;
    if (restriction) {
      newDecl =
          schemaFactory.createTypeRestriction(
              name,
              schemaDoc.fTargetNamespace,
              (short) finalProperty,
              baseValidator,
              annotations == null ? null : new XSObjectListImpl(annotations, annotations.length));
    } else if (list) {
      newDecl =
          schemaFactory.createTypeList(
              name,
              schemaDoc.fTargetNamespace,
              (short) finalProperty,
              baseValidator,
              annotations == null ? null : new XSObjectListImpl(annotations, annotations.length));
    } else if (union) {
      XSSimpleType[] memberDecls = new XSSimpleType[dTValidators.size()];
      for (int i = 0; i < dTValidators.size(); i++)
        memberDecls[i] = (XSSimpleType) dTValidators.elementAt(i);
      newDecl =
          schemaFactory.createTypeUnion(
              name,
              schemaDoc.fTargetNamespace,
              (short) finalProperty,
              memberDecls,
              annotations == null ? null : new XSObjectListImpl(annotations, annotations.length));
    }

    // now traverse facets, if it's derived by restriction
    if (restriction && content != null) {
      FacetInfo fi = traverseFacets(content, baseValidator, schemaDoc);
      content = fi.nodeAfterFacets;

      if (!skipFacets) {
        try {
          fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport);
          newDecl.applyFacets(fi.facetdata, fi.fPresentFacets, fi.fFixedFacets, fValidationState);
        } catch (InvalidDatatypeFacetException ex) {
          reportSchemaError(ex.getKey(), ex.getArgs(), child);
        }
      }
    }

    // now element should appear after this point
    if (content != null) {
      if (restriction) {
        reportSchemaError(
            "s4s-elt-must-match.1",
            new Object[] {
              SchemaSymbols.ELT_RESTRICTION,
              "(annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*))",
              DOMUtil.getLocalName(content)
            },
            content);
      } else if (list) {
        reportSchemaError(
            "s4s-elt-must-match.1",
            new Object[] {
              SchemaSymbols.ELT_LIST, "(annotation?, (simpleType?))", DOMUtil.getLocalName(content)
            },
            content);
      } else if (union) {
        reportSchemaError(
            "s4s-elt-must-match.1",
            new Object[] {
              SchemaSymbols.ELT_UNION, "(annotation?, (simpleType*))", DOMUtil.getLocalName(content)
            },
            content);
      }
    }

    fAttrChecker.returnAttrArray(contentAttrs, schemaDoc);

    // return the new type
    return newDecl;
  }
/**
 * The simple type definition schema component traverser.
 *
 * <p><simpleType final = (#all | (list | union | restriction)) id = ID name = NCName {any
 * attributes with non-schema namespace . . .}> Content: (annotation?, (restriction | list | union))
 * </simpleType>
 *
 * <p><restriction base = QName id = ID {any attributes with non-schema namespace . . .}> Content:
 * (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive |
 * totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace |
 * pattern)*)) </restriction>
 *
 * <p><list id = ID itemType = QName {any attributes with non-schema namespace . . .}> Content:
 * (annotation?, (simpleType?)) </list>
 *
 * <p><union id = ID memberTypes = List of QName {any attributes with non-schema namespace . . .}>
 * Content: (annotation?, (simpleType*)) </union>
 *
 * @author Elena Litani, IBM
 * @author Neeraj Bajaj, Sun Microsystems, Inc.
 * @author Sandy Gao, IBM
 * @version $Id: XSDSimpleTypeTraverser.java,v 1.26 2003/11/11 20:15:00 sandygao Exp $
 */
class XSDSimpleTypeTraverser extends XSDAbstractTraverser {

  // the factory used to query/create simple types
  private final SchemaDVFactory schemaFactory = SchemaDVFactory.getInstance();

  // whether the type being parsed is a S4S built-in type.
  private boolean fIsBuiltIn = false;

  XSDSimpleTypeTraverser(XSDHandler handler, XSAttributeChecker gAttrCheck) {
    super(handler, gAttrCheck);
    if (schemaFactory instanceof SchemaDVFactoryImpl) {
      ((SchemaDVFactoryImpl) schemaFactory).setDeclPool(handler.fDeclPool);
    }
  }

  // return qualified name of simpleType or empty string if error occured
  XSSimpleType traverseGlobal(Element elmNode, XSDocumentInfo schemaDoc, SchemaGrammar grammar) {

    // General Attribute Checking
    Object[] attrValues = fAttrChecker.checkAttributes(elmNode, true, schemaDoc);
    String nameAtt = (String) attrValues[XSAttributeChecker.ATTIDX_NAME];
    XSSimpleType type = traverseSimpleTypeDecl(elmNode, attrValues, schemaDoc, grammar);
    fAttrChecker.returnAttrArray(attrValues, schemaDoc);

    // if it's a global type without a name, return null
    if (nameAtt == null) {
      reportSchemaError(
          "s4s-att-must-appear",
          new Object[] {SchemaSymbols.ELT_SIMPLETYPE, SchemaSymbols.ATT_NAME},
          elmNode);
      type = null;
    }

    // don't add global components without name to the grammar
    if (type != null) {
      grammar.addGlobalTypeDecl(type);
    }

    return type;
  }

  XSSimpleType traverseLocal(Element elmNode, XSDocumentInfo schemaDoc, SchemaGrammar grammar) {

    // General Attribute Checking
    Object[] attrValues = fAttrChecker.checkAttributes(elmNode, false, schemaDoc);
    XSSimpleType type = traverseSimpleTypeDecl(elmNode, attrValues, schemaDoc, grammar);
    fAttrChecker.returnAttrArray(attrValues, schemaDoc);

    return type;
  }

  private XSSimpleType traverseSimpleTypeDecl(
      Element simpleTypeDecl,
      Object[] attrValues,
      XSDocumentInfo schemaDoc,
      SchemaGrammar grammar) {

    // get name and final values
    String name = (String) attrValues[XSAttributeChecker.ATTIDX_NAME];
    XInt finalAttr = (XInt) attrValues[XSAttributeChecker.ATTIDX_FINAL];
    int finalProperty = finalAttr == null ? schemaDoc.fFinalDefault : finalAttr.intValue();

    // annotation?,(list|restriction|union)
    Element child = DOMUtil.getFirstChildElement(simpleTypeDecl);
    XSAnnotationImpl[] annotations = null;
    if (child != null) {
      // traverse annotation if any
      if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
        XSAnnotationImpl annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
        if (annotation != null) annotations = new XSAnnotationImpl[] {annotation};
        child = DOMUtil.getNextSiblingElement(child);
      }
    }

    // (list|restriction|union)
    if (child == null) {
      reportSchemaError(
          "s4s-elt-must-match.2",
          new Object[] {
            SchemaSymbols.ELT_SIMPLETYPE, "(annotation?, (restriction | list | union))"
          },
          simpleTypeDecl);
      return errorType(name, schemaDoc.fTargetNamespace, XSConstants.DERIVATION_RESTRICTION);
    }

    // derivation type: restriction/list/union
    String varietyProperty = DOMUtil.getLocalName(child);
    short refType = XSConstants.DERIVATION_RESTRICTION;
    boolean restriction = false, list = false, union = false;
    if (varietyProperty.equals(SchemaSymbols.ELT_RESTRICTION)) {
      refType = XSConstants.DERIVATION_RESTRICTION;
      restriction = true;
    } else if (varietyProperty.equals(SchemaSymbols.ELT_LIST)) {
      refType = XSConstants.DERIVATION_LIST;
      list = true;
    } else if (varietyProperty.equals(SchemaSymbols.ELT_UNION)) {
      refType = XSConstants.DERIVATION_UNION;
      union = true;
    } else {
      reportSchemaError(
          "s4s-elt-must-match.1",
          new Object[] {
            SchemaSymbols.ELT_SIMPLETYPE,
            "(annotation?, (restriction | list | union))",
            varietyProperty
          },
          simpleTypeDecl);
      return errorType(name, schemaDoc.fTargetNamespace, XSConstants.DERIVATION_RESTRICTION);
    }

    // nothing should follow this element
    Element nextChild = DOMUtil.getNextSiblingElement(child);
    if (nextChild != null) {
      reportSchemaError(
          "s4s-elt-must-match.1",
          new Object[] {
            SchemaSymbols.ELT_SIMPLETYPE,
            "(annotation?, (restriction | list | union))",
            DOMUtil.getLocalName(nextChild)
          },
          nextChild);
    }

    // General Attribute Checking: get base/item/member types
    Object[] contentAttrs = fAttrChecker.checkAttributes(child, false, schemaDoc);
    QName baseTypeName =
        (QName)
            contentAttrs[
                restriction ? XSAttributeChecker.ATTIDX_BASE : XSAttributeChecker.ATTIDX_ITEMTYPE];
    Vector memberTypes = (Vector) contentAttrs[XSAttributeChecker.ATTIDX_MEMBERTYPES];

    // content = {annotation?,simpleType?...}
    Element content = DOMUtil.getFirstChildElement(child);

    // check content (annotation?, ...)
    if (content != null) {
      // traverse annotation if any
      if (DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_ANNOTATION)) {
        XSAnnotationImpl annotation =
            traverseAnnotationDecl(content, contentAttrs, false, schemaDoc);
        if (annotation != null) {
          if (annotations == null) annotations = new XSAnnotationImpl[] {annotation};
          else {
            XSAnnotationImpl[] tempArray = new XSAnnotationImpl[2];
            tempArray[0] = annotations[0];
            annotations = tempArray;
            annotations[1] = annotation;
          }
        }
        content = DOMUtil.getNextSiblingElement(content);
      }
    }

    // get base type from "base" attribute
    XSSimpleType baseValidator = null;
    if ((restriction || list) && baseTypeName != null) {
      baseValidator = findDTValidator(child, name, baseTypeName, refType, schemaDoc);
      // if its the built-in type, return null from here
      if (baseValidator == null && fIsBuiltIn) {
        fIsBuiltIn = false;
        return null;
      }
    }

    // get types from "memberTypes" attribute
    Vector dTValidators = null;
    XSSimpleType dv = null;
    XSObjectList dvs;
    if (union && memberTypes != null && memberTypes.size() > 0) {
      int size = memberTypes.size();
      dTValidators = new Vector(size, 2);
      // for each qname in the list
      for (int i = 0; i < size; i++) {
        // get the type decl
        dv =
            findDTValidator(
                child,
                name,
                (QName) memberTypes.elementAt(i),
                XSConstants.DERIVATION_UNION,
                schemaDoc);
        if (dv != null) {
          // if it's a union, expand it
          if (dv.getVariety() == XSSimpleType.VARIETY_UNION) {
            dvs = dv.getMemberTypes();
            for (int j = 0; j < dvs.getLength(); j++) dTValidators.addElement(dvs.item(j));
          } else {
            dTValidators.addElement(dv);
          }
        }
      }
    }

    // when there is an error finding the base type of a restriction
    // we use anySimpleType as the base, then we should skip the facets,
    // because anySimpleType doesn't recognize any facet.
    boolean skipFacets = false;

    // check if there is a child "simpleType"
    if (content != null && DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_SIMPLETYPE)) {
      if (restriction || list) {
        // it's an error for both "base" and "simpleType" to appear
        if (baseTypeName != null) {
          reportSchemaError(list ? "src-simple-type.3.a" : "src-simple-type.2.a", null, content);
        } else {
          // traver this child to get the base type
          baseValidator = traverseLocal(content, schemaDoc, grammar);
        }
        // get the next element
        content = DOMUtil.getNextSiblingElement(content);
      } else if (union) {
        if (dTValidators == null) {
          dTValidators = new Vector(2, 2);
        }
        do {
          // traver this child to get the member type
          dv = traverseLocal(content, schemaDoc, grammar);
          if (dv != null) {
            // if it's a union, expand it
            if (dv.getVariety() == XSSimpleType.VARIETY_UNION) {
              dvs = dv.getMemberTypes();
              for (int j = 0; j < dvs.getLength(); j++) dTValidators.addElement(dvs.item(j));
            } else {
              dTValidators.addElement(dv);
            }
          }
          // get the next element
          content = DOMUtil.getNextSiblingElement(content);
        } while (content != null
            && DOMUtil.getLocalName(content).equals(SchemaSymbols.ELT_SIMPLETYPE));
      }
    } else if ((restriction || list) && baseTypeName == null) {
      // it's an error if neither "base" nor "simpleType" appears
      reportSchemaError(list ? "src-simple-type.3.b" : "src-simple-type.2.b", null, child);
      // base can't be found, skip the facets.
      skipFacets = true;
      baseValidator = SchemaGrammar.fAnySimpleType;
    } else if (union && (memberTypes == null || memberTypes.size() == 0)) {
      // it's an error if "memberTypes" is empty and no "simpleType" appears
      reportSchemaError("src-union-memberTypes-or-simpleTypes", null, child);
      dTValidators = new Vector(1);
      dTValidators.addElement(SchemaGrammar.fAnySimpleType);
    }

    // error finding "base" or error traversing "simpleType".
    // don't need to report an error, since some error has been reported.
    if ((restriction || list) && baseValidator == null) {
      baseValidator = SchemaGrammar.fAnySimpleType;
    }
    // error finding "memberTypes" or error traversing "simpleType".
    // don't need to report an error, since some error has been reported.
    if (union && (dTValidators == null || dTValidators.size() == 0)) {
      dTValidators = new Vector(1);
      dTValidators.addElement(SchemaGrammar.fAnySimpleType);
    }

    // item type of list types can't have list content
    if (list && isListDatatype(baseValidator)) {
      reportSchemaError(
          "cos-st-restricts.2.1", new Object[] {name, baseValidator.getName()}, child);
    }

    // create the simple type based on the "base" type
    XSSimpleType newDecl = null;
    if (restriction) {
      newDecl =
          schemaFactory.createTypeRestriction(
              name,
              schemaDoc.fTargetNamespace,
              (short) finalProperty,
              baseValidator,
              annotations == null ? null : new XSObjectListImpl(annotations, annotations.length));
    } else if (list) {
      newDecl =
          schemaFactory.createTypeList(
              name,
              schemaDoc.fTargetNamespace,
              (short) finalProperty,
              baseValidator,
              annotations == null ? null : new XSObjectListImpl(annotations, annotations.length));
    } else if (union) {
      XSSimpleType[] memberDecls = new XSSimpleType[dTValidators.size()];
      for (int i = 0; i < dTValidators.size(); i++)
        memberDecls[i] = (XSSimpleType) dTValidators.elementAt(i);
      newDecl =
          schemaFactory.createTypeUnion(
              name,
              schemaDoc.fTargetNamespace,
              (short) finalProperty,
              memberDecls,
              annotations == null ? null : new XSObjectListImpl(annotations, annotations.length));
    }

    // now traverse facets, if it's derived by restriction
    if (restriction && content != null) {
      FacetInfo fi = traverseFacets(content, baseValidator, schemaDoc);
      content = fi.nodeAfterFacets;

      if (!skipFacets) {
        try {
          fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport);
          newDecl.applyFacets(fi.facetdata, fi.fPresentFacets, fi.fFixedFacets, fValidationState);
        } catch (InvalidDatatypeFacetException ex) {
          reportSchemaError(ex.getKey(), ex.getArgs(), child);
        }
      }
    }

    // now element should appear after this point
    if (content != null) {
      if (restriction) {
        reportSchemaError(
            "s4s-elt-must-match.1",
            new Object[] {
              SchemaSymbols.ELT_RESTRICTION,
              "(annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*))",
              DOMUtil.getLocalName(content)
            },
            content);
      } else if (list) {
        reportSchemaError(
            "s4s-elt-must-match.1",
            new Object[] {
              SchemaSymbols.ELT_LIST, "(annotation?, (simpleType?))", DOMUtil.getLocalName(content)
            },
            content);
      } else if (union) {
        reportSchemaError(
            "s4s-elt-must-match.1",
            new Object[] {
              SchemaSymbols.ELT_UNION, "(annotation?, (simpleType*))", DOMUtil.getLocalName(content)
            },
            content);
      }
    }

    fAttrChecker.returnAttrArray(contentAttrs, schemaDoc);

    // return the new type
    return newDecl;
  }

  // @param: elm - top element
  // @param: baseTypeStr - type (base/itemType/memberTypes)
  // @param: baseRefContext:  whether the caller is using this type as a base for restriction, union
  // or list
  // return XSSimpleType available for the baseTypeStr, null if not found or disallowed.
  // also throws an error if the base type won't allow itself to be used in this context.
  // REVISIT: can this code be re-used?
  private XSSimpleType findDTValidator(
      Element elm,
      String refName,
      QName baseTypeStr,
      short baseRefContext,
      XSDocumentInfo schemaDoc) {
    if (baseTypeStr == null) return null;

    XSTypeDefinition baseType =
        (XSTypeDefinition)
            fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE, baseTypeStr, elm);
    if (baseType != null) {
      // if it's a complex type, or if its restriction of anySimpleType
      if (baseType.getTypeCategory() != XSTypeDefinition.SIMPLE_TYPE
          || (baseType == SchemaGrammar.fAnySimpleType
              && baseRefContext == XSConstants.DERIVATION_RESTRICTION)) {
        // if the base type is anySimpleType and the current type is
        // a S4S built-in type, return null. (not an error).
        if (baseType == SchemaGrammar.fAnySimpleType
            && checkBuiltIn(refName, schemaDoc.fTargetNamespace)) {
          return null;
        }
        reportSchemaError("cos-st-restricts.1.1", new Object[] {baseTypeStr.rawname, refName}, elm);
        return SchemaGrammar.fAnySimpleType;
      }
      if ((baseType.getFinal() & baseRefContext) != 0) {
        if (baseRefContext == XSConstants.DERIVATION_RESTRICTION) {
          reportSchemaError("st-props-correct.3", new Object[] {refName, baseTypeStr.rawname}, elm);
        } else if (baseRefContext == XSConstants.DERIVATION_LIST) {
          reportSchemaError(
              "cos-st-restricts.2.3.1.1", new Object[] {baseTypeStr.rawname, refName}, elm);
        } else if (baseRefContext == XSConstants.DERIVATION_UNION) {
          reportSchemaError(
              "cos-st-restricts.3.3.1.1", new Object[] {baseTypeStr.rawname, refName}, elm);
        }
      }
    }

    return (XSSimpleType) baseType;
  }

  // check whethe the type denoted by the name and namespace is a S4S
  // built-in type. update fIsBuiltIn at the same time.
  private final boolean checkBuiltIn(String name, String namespace) {
    if (namespace != SchemaSymbols.URI_SCHEMAFORSCHEMA) return false;
    if (SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(name) != null) fIsBuiltIn = true;
    return fIsBuiltIn;
  }

  // find if a datatype validator is a list or has list datatype member.
  private boolean isListDatatype(XSSimpleType validator) {
    if (validator.getVariety() == XSSimpleType.VARIETY_LIST) return true;

    if (validator.getVariety() == XSSimpleType.VARIETY_UNION) {
      XSObjectList temp = validator.getMemberTypes();
      for (int i = 0; i < temp.getLength(); i++) {
        if (((XSSimpleType) temp.item(i)).getVariety() == XSSimpleType.VARIETY_LIST) {
          return true;
        }
      }
    }

    return false;
  } // isListDatatype(XSSimpleTypeDecl):boolean

  private XSSimpleType errorType(String name, String namespace, short refType) {
    switch (refType) {
      case XSConstants.DERIVATION_RESTRICTION:
        return schemaFactory.createTypeRestriction(
            name, namespace, (short) 0, SchemaGrammar.fAnySimpleType, null);
      case XSConstants.DERIVATION_LIST:
        return schemaFactory.createTypeList(
            name, namespace, (short) 0, SchemaGrammar.fAnySimpleType, null);
      case XSConstants.DERIVATION_UNION:
        return schemaFactory.createTypeUnion(
            name, namespace, (short) 0, new XSSimpleType[] {SchemaGrammar.fAnySimpleType}, null);
    }

    return null;
  }
} // class XSDSimpleTypeTraverser