protected Expression annealExpression(Expression exp) {
    // hook this ComplexTypeExp into the base type's restrictions list.

    final XMLSchemaReader reader = (XMLSchemaReader) this.reader;
    exp = super.annealExpression(exp);

    String refQName = startTag.getAttribute("base");
    if (refQName == null) {
      reader.reportError(XMLSchemaReader.ERR_MISSING_ATTRIBUTE, startTag.qName, "base");
      return exp;
      // recover by abandoning proper derivation processing
    }

    String[] r = reader.splitQName(refQName);
    if (r == null) {
      reader.reportError(XMLSchemaReader.ERR_UNDECLARED_PREFIX, refQName);
      return exp;
      // recover by abandoning proper derivation processing
    }

    if (reader.isSchemaNamespace(r[0]) && r[1].equals("anyType"))
      // derivation from anyType means this expression is the root of
      // derivation. So we don't have to connect this complex type to
      // the super class.
      return exp;

    ComplexTypeExp baseType =
        reader.getOrCreateSchema(r[0] /*uri*/).complexTypes.getOrCreate(r[1] /*local name*/);
    if (baseType == null)
      return exp; // recover by abandoning further processing of this declaration.

    reader.backwardReference.memorizeLink(baseType);

    /*        if( extension )
                baseType.extensions.exp = reader.pool.createChoice(
                                                baseType.extensions.exp,
                                                parentDecl.selfWType );
                // actual content model will be <baseTypeContentModel>,<AddedContentModel>
            else
                baseType.restrictions.exp = reader.pool.createChoice(
                                                baseType.restrictions.exp,
                                                parentDecl.selfWType );
    */
    // set other fields of the ComplexTypeExp.
    parentDecl.derivationMethod = extension ? ComplexTypeExp.EXTENSION : ComplexTypeExp.RESTRICTION;
    parentDecl.complexBaseType = baseType;

    return combineToBaseType(baseType, exp);
  }
  /** Gets the expression for the base type. */
  private Expression getBody() {
    final XMLSchemaReader reader = (XMLSchemaReader) this.reader;

    final String base = startTag.getAttribute("base");
    if (base == null) {
      // in extension, base attribute must is mandatory.
      reader.reportError(XMLSchemaReader.ERR_MISSING_ATTRIBUTE, startTag.localName, "base");
      return Expression.nullSet;
    }

    final String[] baseTypeName = reader.splitQName(base);
    if (baseTypeName == null) {
      reader.reportError(XMLSchemaReader.ERR_UNDECLARED_PREFIX, base);
      return Expression.nullSet;
    }

    // we need a special handling for built-in types
    if (reader.isSchemaNamespace(baseTypeName[0])) {
      XSDatatype dt = reader.resolveBuiltinDataType(baseTypeName[1]);
      if (dt != null) {
        XSDatatypeExp dtexp = new XSDatatypeExp(dt, reader.pool);
        parentDecl.simpleBaseType = dtexp;
        return dtexp;
      }

      // maybe we are parsing the schema for schema.
      // consult externally specified schema.
    }

    final XMLSchemaSchema schema = reader.grammar.getByNamespace(baseTypeName[0]);

    // we don't know whether it's a complex type or a simple type.
    // so back patch it
    final ReferenceExp ref = new ReferenceExp(null);
    reader.addBackPatchJob(
        new GrammarReader.BackPatch() {
          public State getOwnerState() {
            return SimpleContentExtensionState.this;
          }

          public void patch() {
            SimpleTypeExp sexp = schema.simpleTypes.get(baseTypeName[1]);
            if (sexp != null) {
              // we've found the simple type
              ref.exp = sexp;
              parentDecl.simpleBaseType = sexp.getType();
              _assert(parentDecl.simpleBaseType != null);
              return;
            }
            ComplexTypeExp cexp = schema.complexTypes.get(baseTypeName[1]);
            if (cexp != null) {
              // we've found the complex type as the base type
              ref.exp = cexp.body;
              parentDecl.complexBaseType = cexp;
              return;
            }

            // there is no base type.
            reader.reportError(XMLSchemaReader.ERR_UNDEFINED_COMPLEX_OR_SIMPLE_TYPE, base);
          }
        });

    return ref;
  }
 protected Expression annealExpression(Expression exp) {
   parentDecl.derivationMethod = ComplexTypeExp.EXTENSION;
   return reader.pool.createSequence(super.annealExpression(exp), getBody());
 }
 public void setAttributeWildcard(AttributeWildcard local) {
   parentDecl.wildcard = local;
 }