/**
 * Copyright (c) 2002-2006 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 */
package org.eclipse.xsd.impl;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeGroupContent;
import org.eclipse.xsd.XSDAttributeGroupDefinition;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDAttributeUseCategory;
import org.eclipse.xsd.XSDComplexFinal;
import org.eclipse.xsd.XSDComplexTypeContent;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDComponent;
import org.eclipse.xsd.XSDCompositor;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDContentTypeCategory;
import org.eclipse.xsd.XSDDerivationMethod;
import org.eclipse.xsd.XSDDiagnosticSeverity;
import org.eclipse.xsd.XSDDisallowedSubstitutions;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDNamespaceConstraintCategory;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDParticleContent;
import org.eclipse.xsd.XSDProhibitedSubstitutions;
import org.eclipse.xsd.XSDRedefine;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.XSDWildcard;
import org.eclipse.xsd.util.XSDConstants;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Complex Type Definition</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getDerivationMethod <em>Derivation Method</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getFinal <em>Final</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#isAbstract <em>Abstract</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getContentTypeCategory <em>Content Type Category</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getProhibitedSubstitutions <em>Prohibited Substitutions</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getLexicalFinal <em>Lexical Final</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getBlock <em>Block</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#isMixed <em>Mixed</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getContentAnnotation <em>Content Annotation</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getBaseTypeDefinition <em>Base Type Definition</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getContent <em>Content</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getContentType <em>Content Type</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getAttributeUses <em>Attribute Uses</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getAttributeContents <em>Attribute Contents</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getAttributeWildcard <em>Attribute Wildcard</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getAttributeWildcardContent <em>Attribute Wildcard Content</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getRootTypeDefinition <em>Root Type Definition</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getSyntheticParticle <em>Synthetic Particle</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDComplexTypeDefinitionImpl#getSyntheticWildcard <em>Synthetic Wildcard</em>}</li>
 * </ul>
 *
 * @generated
 */
public class XSDComplexTypeDefinitionImpl 
  extends XSDTypeDefinitionImpl 
  implements XSDComplexTypeDefinition
{
  /**
   * The default value of the '{@link #getDerivationMethod() <em>Derivation Method</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getDerivationMethod()
   * @generated
   * @ordered
   */
  protected static final XSDDerivationMethod DERIVATION_METHOD_EDEFAULT = XSDDerivationMethod.RESTRICTION_LITERAL;

  /**
   * The offset of the flags representing the value of the '{@link #getDerivationMethod() <em>Derivation Method</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int DERIVATION_METHOD_EFLAG_OFFSET = 8;

  /**
   * The flags representing the default value of the '{@link #getDerivationMethod() <em>Derivation Method</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int DERIVATION_METHOD_EFLAG_DEFAULT = DERIVATION_METHOD_EDEFAULT.ordinal() << DERIVATION_METHOD_EFLAG_OFFSET;

  /**
   * The array of enumeration values for '{@link XSDDerivationMethod Derivation Method}'
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  private static final XSDDerivationMethod[] DERIVATION_METHOD_EFLAG_VALUES = XSDDerivationMethod.values();

  /**
   * The flag representing the value of the '{@link #getDerivationMethod() <em>Derivation Method</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getDerivationMethod()
   * @generated
   * @ordered
   */
  protected static final int DERIVATION_METHOD_EFLAG = 1 << DERIVATION_METHOD_EFLAG_OFFSET;

  /**
   * The flag representing whether the Derivation Method attribute has been set.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int DERIVATION_METHOD_ESETFLAG = 1 << 9;

  /**
   * The cached value of the '{@link #getFinal() <em>Final</em>}' attribute list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getFinal()
   * @generated
   * @ordered
   */
  protected EList<XSDComplexFinal> final_;

  /**
   * The default value of the '{@link #isAbstract() <em>Abstract</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #isAbstract()
   * @generated
   * @ordered
   */
  protected static final boolean ABSTRACT_EDEFAULT = false;

  /**
   * The flag representing the value of the '{@link #isAbstract() <em>Abstract</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #isAbstract()
   * @generated
   * @ordered
   */
  protected static final int ABSTRACT_EFLAG = 1 << 10;

  /**
   * The flag representing whether the Abstract attribute has been set.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int ABSTRACT_ESETFLAG = 1 << 11;

  /**
   * The default value of the '{@link #getContentTypeCategory() <em>Content Type Category</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getContentTypeCategory()
   * @generated
   * @ordered
   */
  protected static final XSDContentTypeCategory CONTENT_TYPE_CATEGORY_EDEFAULT = XSDContentTypeCategory.EMPTY_LITERAL;

  /**
   * The offset of the flags representing the value of the '{@link #getContentTypeCategory() <em>Content Type Category</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int CONTENT_TYPE_CATEGORY_EFLAG_OFFSET = 12;

  /**
   * The flags representing the default value of the '{@link #getContentTypeCategory() <em>Content Type Category</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int CONTENT_TYPE_CATEGORY_EFLAG_DEFAULT = CONTENT_TYPE_CATEGORY_EDEFAULT.ordinal() << CONTENT_TYPE_CATEGORY_EFLAG_OFFSET;

  /**
   * The array of enumeration values for '{@link XSDContentTypeCategory Content Type Category}'
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  private static final XSDContentTypeCategory[] CONTENT_TYPE_CATEGORY_EFLAG_VALUES = XSDContentTypeCategory.values();

  /**
   * The flags representing the value of the '{@link #getContentTypeCategory() <em>Content Type Category</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getContentTypeCategory()
   * @generated
   * @ordered
   */
  protected static final int CONTENT_TYPE_CATEGORY_EFLAG = 0x3 << CONTENT_TYPE_CATEGORY_EFLAG_OFFSET;

  /**
   * The cached value of the '{@link #getProhibitedSubstitutions() <em>Prohibited Substitutions</em>}' attribute list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getProhibitedSubstitutions()
   * @generated
   * @ordered
   */
  protected EList<XSDProhibitedSubstitutions> prohibitedSubstitutions;

  /**
   * The cached value of the '{@link #getLexicalFinal() <em>Lexical Final</em>}' attribute list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getLexicalFinal()
   * @generated
   * @ordered
   */
  protected EList<XSDComplexFinal> lexicalFinal;

  /**
   * The cached value of the '{@link #getBlock() <em>Block</em>}' attribute list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getBlock()
   * @generated
   * @ordered
   */
  protected EList<XSDProhibitedSubstitutions> block;

  /**
   * The default value of the '{@link #isMixed() <em>Mixed</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #isMixed()
   * @generated
   * @ordered
   */
  protected static final boolean MIXED_EDEFAULT = false;

  /**
   * The flag representing the value of the '{@link #isMixed() <em>Mixed</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #isMixed()
   * @generated
   * @ordered
   */
  protected static final int MIXED_EFLAG = 1 << 14;

  /**
   * The flag representing whether the Mixed attribute has been set.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int MIXED_ESETFLAG = 1 << 15;

  /**
   * The cached value of the '{@link #getContentAnnotation() <em>Content Annotation</em>}' containment reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getContentAnnotation()
   * @generated
   * @ordered
   */
  protected XSDAnnotation contentAnnotation;

  /**
   * The cached value of the '{@link #getBaseTypeDefinition() <em>Base Type Definition</em>}' reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getBaseTypeDefinition()
   * @generated
   * @ordered
   */
  protected XSDTypeDefinition baseTypeDefinition;

  /**
   * The cached value of the '{@link #getContent() <em>Content</em>}' containment reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getContent()
   * @generated
   * @ordered
   */
  protected XSDComplexTypeContent content;

  /**
   * The cached value of the '{@link #getContentType() <em>Content Type</em>}' reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getContentType()
   * @generated
   * @ordered
   */
  protected XSDComplexTypeContent contentType;

  /**
   * The cached value of the '{@link #getAttributeUses() <em>Attribute Uses</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAttributeUses()
   * @generated
   * @ordered
   */
  protected EList<XSDAttributeUse> attributeUses;

  /**
   * The cached value of the '{@link #getAttributeContents() <em>Attribute Contents</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAttributeContents()
   * @generated
   * @ordered
   */
  protected EList<XSDAttributeGroupContent> attributeContents;

  /**
   * The cached value of the '{@link #getAttributeWildcard() <em>Attribute Wildcard</em>}' reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAttributeWildcard()
   * @generated
   * @ordered
   */
  protected XSDWildcard attributeWildcard;

  /**
   * The cached value of the '{@link #getAttributeWildcardContent() <em>Attribute Wildcard Content</em>}' containment reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAttributeWildcardContent()
   * @generated
   * @ordered
   */
  protected XSDWildcard attributeWildcardContent;

  /**
   * The cached value of the '{@link #getSyntheticParticle() <em>Synthetic Particle</em>}' containment reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getSyntheticParticle()
   * @generated
   * @ordered
   */
  protected XSDParticle syntheticParticle;

  /**
   * The cached value of the '{@link #getSyntheticWildcard() <em>Synthetic Wildcard</em>}' containment reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getSyntheticWildcard()
   * @generated
   * @ordered
   */
  protected XSDWildcard syntheticWildcard;

  public static XSDComplexTypeDefinition createComplexTypeDefinition(Node node)
  {
    if (XSDConstants.nodeType(node) == XSDConstants.COMPLEXTYPE_ELEMENT)
    {
      XSDComplexTypeDefinition xsdComplexTypeDefinition = XSDFactory.eINSTANCE.createXSDComplexTypeDefinition();
      xsdComplexTypeDefinition.setElement((Element)node);
      return xsdComplexTypeDefinition;
    }

   return null;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  protected XSDComplexTypeDefinitionImpl()
  {
    super();
    eFlags |= DERIVATION_METHOD_EFLAG_DEFAULT;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  protected EClass eStaticClass()
  {
    return XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDDerivationMethod getDerivationMethod()
  {
    return DERIVATION_METHOD_EFLAG_VALUES[(eFlags & DERIVATION_METHOD_EFLAG) >>> DERIVATION_METHOD_EFLAG_OFFSET];
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setDerivationMethod(XSDDerivationMethod newDerivationMethod)
  {
    XSDDerivationMethod oldDerivationMethod = DERIVATION_METHOD_EFLAG_VALUES[(eFlags & DERIVATION_METHOD_EFLAG) >>> DERIVATION_METHOD_EFLAG_OFFSET];
    if (newDerivationMethod == null) newDerivationMethod = DERIVATION_METHOD_EDEFAULT;
    eFlags = eFlags & ~DERIVATION_METHOD_EFLAG | newDerivationMethod.ordinal() << DERIVATION_METHOD_EFLAG_OFFSET;
    boolean oldDerivationMethodESet = (eFlags & DERIVATION_METHOD_ESETFLAG) != 0;
    eFlags |= DERIVATION_METHOD_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__DERIVATION_METHOD, oldDerivationMethod, newDerivationMethod, !oldDerivationMethodESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetDerivationMethod()
  {
    XSDDerivationMethod oldDerivationMethod = DERIVATION_METHOD_EFLAG_VALUES[(eFlags & DERIVATION_METHOD_EFLAG) >>> DERIVATION_METHOD_EFLAG_OFFSET];
    boolean oldDerivationMethodESet = (eFlags & DERIVATION_METHOD_ESETFLAG) != 0;
    eFlags = eFlags & ~DERIVATION_METHOD_EFLAG | DERIVATION_METHOD_EFLAG_DEFAULT;
    eFlags &= ~DERIVATION_METHOD_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.UNSET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__DERIVATION_METHOD, oldDerivationMethod, DERIVATION_METHOD_EDEFAULT, oldDerivationMethodESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean isSetDerivationMethod()
  {
    return (eFlags & DERIVATION_METHOD_ESETFLAG) != 0;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDComplexFinal> getFinal()
  {
    if (final_ == null)
    {
      final_ = new EDataTypeUniqueEList<XSDComplexFinal>(XSDComplexFinal.class, this, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__FINAL);
    }
    return final_;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean isAbstract()
  {
    return (eFlags & ABSTRACT_EFLAG) != 0;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setAbstract(boolean newAbstract)
  {
    boolean oldAbstract = (eFlags & ABSTRACT_EFLAG) != 0;
    if (newAbstract) eFlags |= ABSTRACT_EFLAG; else eFlags &= ~ABSTRACT_EFLAG;
    boolean oldAbstractESet = (eFlags & ABSTRACT_ESETFLAG) != 0;
    eFlags |= ABSTRACT_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ABSTRACT, oldAbstract, newAbstract, !oldAbstractESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetAbstract()
  {
    boolean oldAbstract = (eFlags & ABSTRACT_EFLAG) != 0;
    boolean oldAbstractESet = (eFlags & ABSTRACT_ESETFLAG) != 0;
    if (ABSTRACT_EDEFAULT) eFlags |= ABSTRACT_EFLAG; else eFlags &= ~ABSTRACT_EFLAG;
    eFlags &= ~ABSTRACT_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.UNSET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ABSTRACT, oldAbstract, ABSTRACT_EDEFAULT, oldAbstractESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean isSetAbstract()
  {
    return (eFlags & ABSTRACT_ESETFLAG) != 0;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDContentTypeCategory getContentTypeCategory()
  {
    return CONTENT_TYPE_CATEGORY_EFLAG_VALUES[(eFlags & CONTENT_TYPE_CATEGORY_EFLAG) >>> CONTENT_TYPE_CATEGORY_EFLAG_OFFSET];
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setContentTypeCategory(XSDContentTypeCategory newContentTypeCategory)
  {
    XSDContentTypeCategory oldContentTypeCategory = CONTENT_TYPE_CATEGORY_EFLAG_VALUES[(eFlags & CONTENT_TYPE_CATEGORY_EFLAG) >>> CONTENT_TYPE_CATEGORY_EFLAG_OFFSET];
    if (newContentTypeCategory == null) newContentTypeCategory = CONTENT_TYPE_CATEGORY_EDEFAULT;
    eFlags = eFlags & ~CONTENT_TYPE_CATEGORY_EFLAG | newContentTypeCategory.ordinal() << CONTENT_TYPE_CATEGORY_EFLAG_OFFSET;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE_CATEGORY, oldContentTypeCategory, newContentTypeCategory));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDProhibitedSubstitutions> getProhibitedSubstitutions()
  {
    if (prohibitedSubstitutions == null)
    {
      prohibitedSubstitutions = new EDataTypeUniqueEList<XSDProhibitedSubstitutions>(XSDProhibitedSubstitutions.class, this, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__PROHIBITED_SUBSTITUTIONS);
    }
    return prohibitedSubstitutions;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDComplexFinal> getLexicalFinal()
  {
    if (lexicalFinal == null)
    {
      lexicalFinal = new EDataTypeUniqueEList.Unsettable<XSDComplexFinal>(XSDComplexFinal.class, this, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__LEXICAL_FINAL);
    }
    return lexicalFinal;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetLexicalFinal()
  {
    if (lexicalFinal != null) ((InternalEList.Unsettable<?>)lexicalFinal).unset();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean isSetLexicalFinal()
  {
    return lexicalFinal != null && ((InternalEList.Unsettable<?>)lexicalFinal).isSet();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDProhibitedSubstitutions> getBlock()
  {
    if (block == null)
    {
      block = new EDataTypeUniqueEList.Unsettable<XSDProhibitedSubstitutions>(XSDProhibitedSubstitutions.class, this, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BLOCK);
    }
    return block;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetBlock()
  {
    if (block != null) ((InternalEList.Unsettable<?>)block).unset();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean isSetBlock()
  {
    return block != null && ((InternalEList.Unsettable<?>)block).isSet();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean isMixed()
  {
    return (eFlags & MIXED_EFLAG) != 0;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setMixed(boolean newMixed)
  {
    boolean oldMixed = (eFlags & MIXED_EFLAG) != 0;
    if (newMixed) eFlags |= MIXED_EFLAG; else eFlags &= ~MIXED_EFLAG;
    boolean oldMixedESet = (eFlags & MIXED_ESETFLAG) != 0;
    eFlags |= MIXED_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__MIXED, oldMixed, newMixed, !oldMixedESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetMixed()
  {
    boolean oldMixed = (eFlags & MIXED_EFLAG) != 0;
    boolean oldMixedESet = (eFlags & MIXED_ESETFLAG) != 0;
    if (MIXED_EDEFAULT) eFlags |= MIXED_EFLAG; else eFlags &= ~MIXED_EFLAG;
    eFlags &= ~MIXED_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.UNSET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__MIXED, oldMixed, MIXED_EDEFAULT, oldMixedESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean isSetMixed()
  {
    return (eFlags & MIXED_ESETFLAG) != 0;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDAnnotation getContentAnnotation()
  {
    return contentAnnotation;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setContentAnnotation(XSDAnnotation newContentAnnotation)
  {
    if (newContentAnnotation != contentAnnotation)
    {
      NotificationChain msgs = null;
      if (contentAnnotation != null)
        msgs = ((InternalEObject)contentAnnotation).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION, null, msgs);
      if (newContentAnnotation != null)
        msgs = ((InternalEObject)newContentAnnotation).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION, null, msgs);
      msgs = basicSetContentAnnotation(newContentAnnotation, msgs);
      if (msgs != null) msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION, newContentAnnotation, newContentAnnotation));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain basicSetContentAnnotation(XSDAnnotation newContentAnnotation, NotificationChain msgs)
  {
    XSDAnnotation oldContentAnnotation = contentAnnotation;
    contentAnnotation = newContentAnnotation;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION, oldContentAnnotation, newContentAnnotation);
      if (msgs == null) msgs = notification; else msgs.add(notification);
    }
    return msgs;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDTypeDefinition getBaseTypeDefinition()
  {
    return baseTypeDefinition;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setBaseTypeDefinition(XSDTypeDefinition newBaseTypeDefinition)
  {
    XSDTypeDefinition oldBaseTypeDefinition = baseTypeDefinition;
    baseTypeDefinition = newBaseTypeDefinition;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BASE_TYPE_DEFINITION, oldBaseTypeDefinition, baseTypeDefinition));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDComplexTypeContent getContent()
  {
    return content;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setContent(XSDComplexTypeContent newContent)
  {
    if (newContent != content)
    {
      NotificationChain msgs = null;
      if (content != null)
        msgs = ((InternalEObject)content).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT, null, msgs);
      if (newContent != null)
        msgs = ((InternalEObject)newContent).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT, null, msgs);
      msgs = basicSetContent(newContent, msgs);
      if (msgs != null) msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT, newContent, newContent));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain basicSetContent(XSDComplexTypeContent newContent, NotificationChain msgs)
  {
    XSDComplexTypeContent oldContent = content;
    content = newContent;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT, oldContent, newContent);
      if (msgs == null) msgs = notification; else msgs.add(notification);
    }
    return msgs;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDComplexTypeContent getContentType()
  {
    return contentType;
  }

  @Override
  public XSDParticle getComplexType()
  {
    return getContentType() instanceof XSDParticle ? (XSDParticle)getContentType() : null;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setContentType(XSDComplexTypeContent newContentType)
  {
    XSDComplexTypeContent oldContentType = contentType;
    contentType = newContentType;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE, oldContentType, contentType));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDAttributeUse> getAttributeUses()
  {
    if (attributeUses == null)
    {
      attributeUses = new EObjectEList<XSDAttributeUse>(XSDAttributeUse.class, this, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_USES);
    }
    return attributeUses;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDAttributeGroupContent> getAttributeContents()
  {
    if (attributeContents == null)
    {
      attributeContents = new EObjectContainmentEList<XSDAttributeGroupContent>(XSDAttributeGroupContent.class, this, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS);
    }
    return attributeContents;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDWildcard getAttributeWildcard()
  {
    return attributeWildcard;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setAttributeWildcard(XSDWildcard newAttributeWildcard)
  {
    XSDWildcard oldAttributeWildcard = attributeWildcard;
    attributeWildcard = newAttributeWildcard;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD, oldAttributeWildcard, attributeWildcard));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDWildcard getAttributeWildcardContent()
  {
    return attributeWildcardContent;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setAttributeWildcardContent(XSDWildcard newAttributeWildcardContent)
  {
    if (newAttributeWildcardContent != attributeWildcardContent)
    {
      NotificationChain msgs = null;
      if (attributeWildcardContent != null)
        msgs = ((InternalEObject)attributeWildcardContent).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT, null, msgs);
      if (newAttributeWildcardContent != null)
        msgs = ((InternalEObject)newAttributeWildcardContent).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT, null, msgs);
      msgs = basicSetAttributeWildcardContent(newAttributeWildcardContent, msgs);
      if (msgs != null) msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT, newAttributeWildcardContent, newAttributeWildcardContent));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain basicSetAttributeWildcardContent(XSDWildcard newAttributeWildcardContent, NotificationChain msgs)
  {
    XSDWildcard oldAttributeWildcardContent = attributeWildcardContent;
    attributeWildcardContent = newAttributeWildcardContent;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT, oldAttributeWildcardContent, newAttributeWildcardContent);
      if (msgs == null) msgs = notification; else msgs.add(notification);
    }
    return msgs;
  }

  @Override
  public Element createElement()
  {
    Element newElement = createElement(XSDConstants.COMPLEXTYPE_ELEMENT);
    setElement(newElement);

    Element attributeParentElement = newElement;

    XSDComplexTypeContent theContent = getContent();
    if (theContent == null || theContent instanceof XSDParticle)
    {
      XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
      if (theBaseTypeDefinition != null && 
            (!XSDConstants.isURType(theBaseTypeDefinition) || 
               XSDDerivationMethod.EXTENSION_LITERAL == getDerivationMethod()))
      {
        Element [] contentElementPair = createContentElementPair();
        attributeParentElement = contentElementPair[1];

        newElement.appendChild(contentElementPair[0]);
      }

      if (theContent != null)
      {
        Element simpleContentElement = ((XSDConcreteComponentImpl)theContent).createElement(); 
        attributeParentElement.appendChild(simpleContentElement);
      }
    }
    else 
    {
      Element simpleContentElement = ((XSDConcreteComponentImpl)theContent).createElement();
      newElement.appendChild(simpleContentElement);

      LOOP:
      for (Node child = simpleContentElement.getFirstChild(); child != null; child = child.getNextSibling())
      {
        switch (XSDConstants.nodeType(child))
        {
          case XSDConstants.EXTENSION_ELEMENT:
          case XSDConstants.RESTRICTION_ELEMENT:
          {
            attributeParentElement = (Element)child;
            break LOOP;
          }
        }
      }
    }

    for (XSDAttributeGroupContent xsdAttributeGroupContent : getAttributeContents())
    {
      Element attributeElement = ((XSDConcreteComponentImpl)xsdAttributeGroupContent).createElement();
      attributeParentElement.appendChild(attributeElement);
    }

    return newElement;
  }

  protected Element [] createContentElementPair()
  {
    Element [] contentElementPair = new Element [2];
    contentElementPair[0] = createElement(XSDConstants.COMPLEXCONTENT_ELEMENT);
    contentElementPair[1] =
      createElement
       (XSDDerivationMethod.EXTENSION_LITERAL == getDerivationMethod() ?
           XSDConstants.EXTENSION_ELEMENT :
           XSDConstants.RESTRICTION_ELEMENT);
    contentElementPair[0].appendChild(contentElementPair[1]);
    return contentElementPair;
  }

  protected Element createDerivationElement()
  {
    return
      createElement
       (XSDDerivationMethod.EXTENSION_LITERAL == getDerivationMethod() ?
           XSDConstants.EXTENSION_ELEMENT :
           XSDConstants.RESTRICTION_ELEMENT);
  }

  @Override
  protected boolean considerAllContainsForBestConcreteComponent()
  {
    return true;
  }

  @Override
  protected void patch()
  {
    super.patch();
    XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
    if (theBaseTypeDefinition != null && (forceResolve || theBaseTypeDefinition.getContainer() == null))
    {
      theBaseTypeDefinition = resolveTypeDefinition(theBaseTypeDefinition.getTargetNamespace(), theBaseTypeDefinition.getName());
    }
    theBaseTypeDefinition = handleNewBaseTypeDefinition(theBaseTypeDefinition);

    XSDSchema xsdSchema = getSchema();
    if (xsdSchema != null)
    {
      List<XSDComplexFinal> newFinal = new ArrayList<XSDComplexFinal>();
      if (!isSetLexicalFinal())
      {
        for (XSDProhibitedSubstitutions value : getSchema().getFinalDefault())
        {
          switch (value.getValue())
          {
            case XSDProhibitedSubstitutions.ALL:
            {
              newFinal.add(XSDComplexFinal.EXTENSION_LITERAL);
              newFinal.add(XSDComplexFinal.RESTRICTION_LITERAL);
              break;
            }
            case XSDProhibitedSubstitutions.EXTENSION:
            {
              newFinal.add(XSDComplexFinal.EXTENSION_LITERAL);
              break;
            }
            case XSDProhibitedSubstitutions.RESTRICTION:
            {
              newFinal.add(XSDComplexFinal.RESTRICTION_LITERAL);
              break;
            }
          }
        }
      }
      else
      {
        for (XSDComplexFinal value :  getLexicalFinal())
        {
          switch (value.getValue())
          {
            case XSDComplexFinal.ALL:
            {
              newFinal.add(XSDComplexFinal.EXTENSION_LITERAL);
              newFinal.add(XSDComplexFinal.RESTRICTION_LITERAL);
              break;
            }
            case XSDComplexFinal.EXTENSION:
            case XSDComplexFinal.RESTRICTION:
            {
              newFinal.add(value);
              break;
            }
          }
        }
      }

      Collection<XSDComplexFinal> oldFinal = new ArrayList<XSDComplexFinal>(getFinal());
      oldFinal.removeAll(newFinal);
      if (!oldFinal.isEmpty())
      {
        getFinal().removeAll(oldFinal);
      }
      setListContentAndOrder(getFinal(), newFinal);

      List<XSDProhibitedSubstitutions> newProhibitedSubstitutions = new ArrayList<XSDProhibitedSubstitutions>();
      if (!isSetBlock())
      {
        for (XSDDisallowedSubstitutions value :  getSchema().getBlockDefault())
        {
          switch (value.getValue())
          {
            case XSDDisallowedSubstitutions.ALL:
            {
              newProhibitedSubstitutions.add(XSDProhibitedSubstitutions.EXTENSION_LITERAL);
              newProhibitedSubstitutions.add(XSDProhibitedSubstitutions.RESTRICTION_LITERAL);
              break;
            }
            case XSDDisallowedSubstitutions.RESTRICTION:
            {
              newProhibitedSubstitutions.add(XSDProhibitedSubstitutions.RESTRICTION_LITERAL);
              break;
            }
            case XSDDisallowedSubstitutions.EXTENSION:
            {
              newProhibitedSubstitutions.add(XSDProhibitedSubstitutions.EXTENSION_LITERAL);
              break;
            }
          }
        }
      }
      else
      {
        for (XSDProhibitedSubstitutions value : getBlock())
        {
          switch (value.getValue())
          {
            case XSDProhibitedSubstitutions.ALL:
            {
              newProhibitedSubstitutions.add(XSDProhibitedSubstitutions.EXTENSION_LITERAL);
              newProhibitedSubstitutions.add(XSDProhibitedSubstitutions.RESTRICTION_LITERAL);
              break;
            }
            case XSDProhibitedSubstitutions.EXTENSION:
            case XSDProhibitedSubstitutions.RESTRICTION:
            {
              newProhibitedSubstitutions.add(value);
              break;
            }
          }
        }
      }

      Collection<XSDProhibitedSubstitutions> oldProhibitedSubstitutions = new ArrayList<XSDProhibitedSubstitutions>(getProhibitedSubstitutions());
      oldProhibitedSubstitutions.removeAll(newProhibitedSubstitutions);
      if (!oldProhibitedSubstitutions.isEmpty())
      {
        getProhibitedSubstitutions().removeAll(oldProhibitedSubstitutions);
      }
      setListContentAndOrder(getProhibitedSubstitutions(), newProhibitedSubstitutions);
    }
  }

  @Override
  protected void traverseToRootForAnalysis()
  {
    analysisState = UNANALYZED;
    super.traverseToRootForAnalysis();
  }

  protected XSDParticle extensionParticle;
  protected XSDWildcardImpl effectiveWildcard;
  @Override
  protected void handleAnalysis()
  {
    XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
    XSDComplexTypeContent newContentType = null;
    XSDContentTypeCategory newContentTypeCategory = XSDContentTypeCategory.EMPTY_LITERAL;
    XSDWildcard localWildcard = getAttributeWildcardContent();
    XSDWildcard baseWildcard = null;
    if (theBaseTypeDefinition != null && theBaseTypeDefinition.getContainer() != null)
    {
      if (!((XSDConcreteComponentImpl)theBaseTypeDefinition).analyze() && !XSDConstants.isURType(theBaseTypeDefinition) && theBaseTypeDefinition.isCircular())
      {
        analysisState = CIRCULAR;
      }
      if (theBaseTypeDefinition != this)
      {
        List<XSDAttributeUse> baseAttributeUses = Collections.emptyList();
        if (theBaseTypeDefinition instanceof XSDComplexTypeDefinition)
        {
          baseAttributeUses = ((XSDComplexTypeDefinition)theBaseTypeDefinition).getAttributeUses();
        }
        EList<XSDAttributeUse> theAttributeUses = getAttributeUses();
        List<XSDAttributeUse> newAttributeUses = XSDAttributeGroupDefinitionImpl.getAttributeUses(getAttributeContents(), baseAttributeUses);
        List<XSDAttributeUse> remainingAttributeUses = new ArrayList<XSDAttributeUse>(theAttributeUses);
        remainingAttributeUses.removeAll(newAttributeUses);
        theAttributeUses.removeAll(remainingAttributeUses);
        setListContentAndOrder(theAttributeUses, newAttributeUses);

        if (XSDDerivationMethod.EXTENSION_LITERAL == getDerivationMethod() && 
              theBaseTypeDefinition instanceof XSDComplexTypeDefinition)
        {
          baseWildcard = ((XSDComplexTypeDefinition)theBaseTypeDefinition).getAttributeWildcard();
        }
      }
    }

    if (localWildcard != null)
    {
      ((XSDConcreteComponentImpl)localWildcard).analyze();
    }
    XSDWildcard newAttributeWildcard = 
      XSDAttributeGroupDefinitionImpl.getAttributeWildcard(baseWildcard, localWildcard, getAttributeContents());

    if (newAttributeWildcard != null && newAttributeWildcard.getContainer() == null)
    {
      if (effectiveWildcard == null)
      {
        effectiveWildcard = (XSDWildcardImpl)getXSDFactory().createXSDWildcard();
        // effectiveWildcard.setOwner(this);
        setSyntheticWildcard(effectiveWildcard);
      }
      effectiveWildcard.setLike(newAttributeWildcard);
      newAttributeWildcard = effectiveWildcard;
    }

    if (newAttributeWildcard != getAttributeWildcard())
    {
      setAttributeWildcard(newAttributeWildcard);
    }

    newContentType = getContent();
    if (newContentType instanceof XSDSimpleTypeDefinition)
    {
      ((XSDConcreteComponentImpl)newContentType).analyze();
      newContentTypeCategory = XSDContentTypeCategory.SIMPLE_LITERAL;
      if (XSDDerivationMethod.EXTENSION_LITERAL == getDerivationMethod())
      {
        newContentType = ((XSDSimpleTypeDefinition)newContentType).getBaseTypeDefinition();
      }
    }
    else 
    {
      newContentTypeCategory = isMixed() ? XSDContentTypeCategory.MIXED_LITERAL : XSDContentTypeCategory.ELEMENT_ONLY_LITERAL;
      boolean isEmptyContent = isEmptyContent((XSDParticle)newContentType);
      if (XSDDerivationMethod.EXTENSION_LITERAL == getDerivationMethod())
      {
        if (theBaseTypeDefinition instanceof XSDComplexTypeDefinition)
        {
          XSDComplexTypeDefinition complexBaseTypeDefinition = (XSDComplexTypeDefinition)theBaseTypeDefinition;

          if (isEmptyContent)
          {
            if (!isMixed())
            {
              newContentTypeCategory = complexBaseTypeDefinition.getContentTypeCategory();
            }
            newContentType = complexBaseTypeDefinition.getContentType();
          }
          else
          {
            XSDComplexTypeContent baseContentType = complexBaseTypeDefinition.getContentType();
            if (baseContentType instanceof XSDParticle)
            {
              if (extensionParticle == null)
              {
                extensionParticle = getXSDFactory().createXSDParticle();
                setSyntheticParticle(extensionParticle);
                extensionParticle.setMinOccurs(1);
                extensionParticle.setMaxOccurs(1);
                XSDModelGroup xsdModelGroup = getXSDFactory().createXSDModelGroup();
                xsdModelGroup.setCompositor(XSDCompositor.SEQUENCE_LITERAL);
                extensionParticle.setContent(xsdModelGroup);
              }

              XSDModelGroup extensionGroup = (XSDModelGroup)extensionParticle.getTerm();
              List<XSDParticle> newParticles = new ArrayList<XSDParticle>();
              newParticles.add((XSDParticle)baseContentType);
              if (getContent() != null)
              {
                newParticles.add((XSDParticle)getContent());
              }
              List<XSDParticle> remainingParticles = new ArrayList<XSDParticle>(extensionGroup.getParticles());
              remainingParticles.removeAll(newParticles);
              if (!remainingParticles.isEmpty())
              {
                extensionGroup.getParticles().removeAll(remainingParticles);
              }
              setListContentAndOrder(extensionGroup.getParticles(), newParticles);
    
              if (isEmptyContent((XSDParticle)baseContentType))
              {
                newContentType = getContent();
              }
              else
              {
                newContentType = extensionParticle;
              }
            }
          }
        }
        else if (isEmptyContent)
        {
          newContentTypeCategory = XSDContentTypeCategory.EMPTY_LITERAL;
        }
      }
      else
      {
        if (isEmptyContent)
        {
          if (isMixed())
          {
            if (extensionParticle == null)
            {
              extensionParticle = getXSDFactory().createXSDParticle();
              setSyntheticParticle(extensionParticle);
              extensionParticle.setMinOccurs(1);
              extensionParticle.setMaxOccurs(1);
              XSDModelGroup xsdModelGroup = getXSDFactory().createXSDModelGroup();
              xsdModelGroup.setCompositor(XSDCompositor.SEQUENCE_LITERAL);
              extensionParticle.setContent(xsdModelGroup);
            }
            newContentType = extensionParticle;
          }
          else
          {
            newContentTypeCategory = XSDContentTypeCategory.EMPTY_LITERAL;
          }
        }
      }
    }

    if (newContentTypeCategory != getContentTypeCategory())
    {
      setContentTypeCategory(newContentTypeCategory);
    }

    if (newContentType != getContentType())
    {
      setContentType(newContentType);
    }

    if (newAttributeWildcard != getAttributeWildcard())
    {
      setAttributeWildcard(newAttributeWildcard);
    }

    if (analysisState == ANALYZING)
    {
      analysisState = ANALYZED;
    }
    super.handleAnalysis();
  }

  protected boolean isEmptyContent(XSDParticle xsdParticle)
  {
    if (xsdParticle == null)
    {
      return true;
    }
    else
    {
      XSDParticleContent xsdParticleContent = xsdParticle.getContent();
      if (xsdParticleContent instanceof XSDModelGroup)
      {
        XSDModelGroup xsdModelGroup = (XSDModelGroup)xsdParticleContent;
        switch (xsdModelGroup.getCompositor().getValue())
        {
          case XSDCompositor.SEQUENCE:
          case XSDCompositor.ALL:
          {
            return xsdModelGroup.getParticles().isEmpty();
          }
          case XSDCompositor.CHOICE:
          {
            return xsdModelGroup.getParticles().isEmpty() && xsdParticle.getMinOccurs() == 0;
          }
          default:
          {
            return false;
          }
        }
      }
      else
      {
        return false;
      }
    }
  }

  @Override
  public void validate()
  {
    super.validate();

    if (getComplexType() != null && getComplexType().getTerm() instanceof XSDModelGroupImpl)
    {
      ((XSDModelGroupImpl)getComplexType().getTerm()).validateRoot();
    }

    Element theElement = getElement();
    if (theElement != null)
    {
      if (getContainer() instanceof XSDElementDeclaration)
      {
        checkAttributes
          (XSDConstants.PART1,
           "element-complexType",
           theElement,
           new String []
           {
             XSDConstants.ID_ATTRIBUTE,
             XSDConstants.MIXED_ATTRIBUTE
           });

         checkComplexContent("localComplexType", XSDConstants.PART1, "element-complexType", theElement);
      }
      else
      {
        checkAttributes
          (XSDConstants.PART1,
           "element-complexType",
           theElement,
           new String []
           {
             XSDConstants.ABSTRACT_ATTRIBUTE,
             XSDConstants.BLOCK_ATTRIBUTE,
             XSDConstants.FINAL_ATTRIBUTE,
             XSDConstants.ID_ATTRIBUTE,
             XSDConstants.NAME_ATTRIBUTE,
             XSDConstants.MIXED_ATTRIBUTE
           });

         checkComplexContent("topLevelComplexType", XSDConstants.PART1, "element-complexType", theElement);

         checkBuiltInTypeConstraint
           ("boolean",
            null,
            XSDConstants.PART1,
            "element-complexType",
            theElement,
            XSDConstants.ABSTRACT_ATTRIBUTE,
            false);

         checkBuiltInTypeConstraint
           ("derivationSet",
            null,
            XSDConstants.PART1,
            "element-complexType",
            theElement,
            XSDConstants.BLOCK_ATTRIBUTE,
            false);
         
         checkBuiltInTypeConstraint
           ("derivationSet",
            null,
            XSDConstants.PART1,
            "element-complexType",
            theElement,
            XSDConstants.FINAL_ATTRIBUTE,
            false);

      }

      checkBuiltInTypeConstraint
        ("ID",
         null,
         XSDConstants.PART1,
         "element-complexType",
         theElement,
         XSDConstants.ID_ATTRIBUTE,
         false);

      checkBuiltInTypeConstraint
        ("boolean",
         null,
         XSDConstants.PART1,
         "element-complexType",
         theElement,
         XSDConstants.MIXED_ATTRIBUTE,
         false);

      for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
      {
        switch (XSDConstants.nodeType(child))
        {
          case XSDConstants.COMPLEXCONTENT_ELEMENT:
          {
            Element childElement = (Element)child;

            checkAttributes
              (XSDConstants.PART1,
               "element-complexContent",
               childElement,
               new String []
               {
                 XSDConstants.ID_ATTRIBUTE,
                 XSDConstants.MIXED_ATTRIBUTE
               });

            checkElementComplexContent("complexContent", XSDConstants.PART1, "element-complexContent", childElement);

            checkBuiltInTypeConstraint
              ("ID",
               null,
               XSDConstants.PART1,
               "element-complexContent",
               childElement,
               XSDConstants.ID_ATTRIBUTE,
               false);

            checkBuiltInTypeConstraint
              ("boolean",
               null,
               XSDConstants.PART1,
               "element-complexContent",
               childElement,
               XSDConstants.MIXED_ATTRIBUTE,
               false);
            
            for (Node grandChild = childElement.getFirstChild(); grandChild != null; grandChild = grandChild.getNextSibling())
            {
              switch (XSDConstants.nodeType(grandChild))
              {
                case XSDConstants.EXTENSION_ELEMENT:
                {
                  Element grandChildElement = (Element)grandChild;
                  checkAttributes
                    (XSDConstants.PART1,
                     "element-complexContent::extension",
                     grandChildElement,
                     new String []
                     {
                       XSDConstants.ID_ATTRIBUTE,
                       XSDConstants.BASE_ATTRIBUTE
                     });

                  checkBuiltInTypeConstraint
                    ("ID",
                     null,
                     XSDConstants.PART1,
                     "element-complexContent::extension",
                     theElement,
                     XSDConstants.ID_ATTRIBUTE,
                     false);

                  checkComplexContent("extensionType", XSDConstants.PART1, "element-complexContent::extension", grandChildElement);

                  break;
                }
                case XSDConstants.RESTRICTION_ELEMENT:
                {
                  Element grandChildElement = (Element)grandChild;
                  checkAttributes
                    (XSDConstants.PART1,
                     "element-complexContent::restriction",
                     grandChildElement,
                     new String []
                     {
                       XSDConstants.ID_ATTRIBUTE,
                       XSDConstants.BASE_ATTRIBUTE
                     });

                  checkBuiltInTypeConstraint
                    ("ID",
                     null,
                     XSDConstants.PART1,
                     "element-complexContent::restriction",
                     theElement,
                     XSDConstants.ID_ATTRIBUTE,
                     false);

                  checkComplexContent
                    ("complexRestrictionType", XSDConstants.PART1, "element-complexContent::restriction", grandChildElement);

                  break;
                }
              }
            }

            break;
          }
        }
      }
    }

    if (!(getContainer() instanceof XSDElementDeclaration))
    {
      checkBuiltInTypeConstraint
        ("NCName",
         getName(),
         XSDConstants.PART1,
         "element-complexType",
         theElement,
         XSDConstants.NAME_ATTRIBUTE,
         true);
    }

    Map<String, XSDAttributeDeclaration> prohibitedAttributeURIs = null;

    XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
    if (theBaseTypeDefinition == null)
    {
      createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "_UI_UnresolvedTypeDefinition_message", "");
    }
    else if (theBaseTypeDefinition.getContainer() == null)
    {
      createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "_UI_UnresolvedTypeDefinition_message", theBaseTypeDefinition.getURI());
    }
    else
    {
      XSDComplexTypeDefinition xsdComplexTypeDefinition = null;
      XSDSimpleTypeDefinition xsdSimpleTypeDefinition = null;
      switch (getContentTypeCategory().getValue())
      {
        case XSDContentTypeCategory.SIMPLE:
        {
          if (theBaseTypeDefinition instanceof XSDComplexTypeDefinition)
          {
            xsdComplexTypeDefinition = (XSDComplexTypeDefinition)theBaseTypeDefinition;
            xsdSimpleTypeDefinition = xsdComplexTypeDefinition.getSimpleType();

            // EATM this contradicts the more relaxed constraint of derivation-ok-restriction.5.1.2
            // if (xsdSimpleTypeDefinition == null)
            // {
            //  createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-ct.2.1", theBaseTypeDefinition.getURI());
            // }
          }
          else
          {
            xsdSimpleTypeDefinition = (XSDSimpleTypeDefinition)theBaseTypeDefinition;
            if (getDerivationMethod() == XSDDerivationMethod.RESTRICTION_LITERAL)
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-ct.2.2", theBaseTypeDefinition.getURI());
            }
            // else if (!XSDConstants.isSchemaForSchemaNamespace(getTargetNamespace()) && 
            //            XSDConstants.isAnySimpleType(xsdSimpleTypeDefinition))
            // {
            //   createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-ct-retricts.0", theBaseTypeDefinition.getURI());
            // }
          }
          break;
        }
        case XSDContentTypeCategory.EMPTY:
        case XSDContentTypeCategory.MIXED:
        case XSDContentTypeCategory.ELEMENT_ONLY:
        {
          if (theBaseTypeDefinition instanceof XSDComplexTypeDefinition)
          {
            xsdComplexTypeDefinition = (XSDComplexTypeDefinition)theBaseTypeDefinition;
          }
          else
          {
            xsdSimpleTypeDefinition = (XSDSimpleTypeDefinition)theBaseTypeDefinition;
            createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-ct.1", theBaseTypeDefinition.getURI());
          }
          break;
        }
      }

      if (getDerivationMethod() == XSDDerivationMethod.EXTENSION_LITERAL)
      {
        if (xsdComplexTypeDefinition != null)
        {
          prohibitedAttributeURIs = getProhibitedAttributeURIs(xsdComplexTypeDefinition);
          if (xsdComplexTypeDefinition.getFinal().contains(XSDComplexFinal.EXTENSION_LITERAL))
          {
            createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-ct-extends.1.1", theBaseTypeDefinition.getURI());
          }
          else
          {
            for (XSDAttributeUse baseXSDAttributeUse : xsdComplexTypeDefinition.getAttributeUses())
            {
              boolean matched = false;
              XSDAttributeDeclaration baseXSDAttributeDeclaration = baseXSDAttributeUse.getAttributeDeclaration();
              for (XSDAttributeUse xsdAttributeUse : getAttributeUses())
              {
                XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttributeUse.getAttributeDeclaration();
                if (xsdAttributeDeclaration.hasSameNameAndTargetNamespace(baseXSDAttributeDeclaration))
                {
                  if (xsdAttributeDeclaration.getTypeDefinition() != baseXSDAttributeDeclaration.getTypeDefinition())
                  {
                    getDiagnosticTarget(xsdAttributeUse).createDiagnostic
                      (XSDDiagnosticSeverity.ERROR_LITERAL, 
                       "cos-ct-extends.1.2.2", 
                       xsdAttributeDeclaration.getURI(),
                       baseXSDAttributeDeclaration.getTypeDefinition().getURI());
                  }

                  matched = true;
                  break;
                }
              }

              if (!matched)
              {
                createDiagnostic
                  (XSDDiagnosticSeverity.ERROR_LITERAL, 
                   "cos-ct-extends.1.2.1", 
                   baseXSDAttributeDeclaration.getURI());
              }
            }

            // EATM this is impossible to hit by virtue of how the wildcard is constructed.
            //
            XSDWildcard baseXSDWildcard = xsdComplexTypeDefinition.getAttributeWildcard();
            if (baseXSDWildcard != null)
            {
              XSDWildcard xsdWildcard = getAttributeWildcard();
              if (xsdWildcard == null || !baseXSDWildcard.isWildcardSubset(xsdWildcard))
              {
                createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-ct-extends.1.3");
              }
            }

            switch (xsdComplexTypeDefinition.getContentTypeCategory().getValue())
            {
              case XSDContentTypeCategory.SIMPLE:
              {
                if (getContentType() != xsdComplexTypeDefinition.getContentType())
                {
                  createDiagnostic
                    (XSDDiagnosticSeverity.ERROR_LITERAL, 
                     "cos-ct-extends.1.4.1", 
                     xsdComplexTypeDefinition.getSimpleType().getURI());
                }
                break;
              }
              case XSDContentTypeCategory.EMPTY:
              {
                break;
              }
              case XSDContentTypeCategory.MIXED:
              case XSDContentTypeCategory.ELEMENT_ONLY:
              {
                //  EATM problems in spec since definition ignores "mixed" attribute we can't validate it here.
                //
                if (getContentTypeCategory() != xsdComplexTypeDefinition.getContentTypeCategory() ||
                     isSetMixed() && isMixed() != xsdComplexTypeDefinition.isMixed())
                {
                  createDiagnostic
                    (XSDDiagnosticSeverity.ERROR_LITERAL, 
                     "cos-ct-extends.1.4.2.2.2.1", 
                     xsdComplexTypeDefinition.getContentTypeCategory().toString());
                }
                break;
              }
            }
          }
        }
        else
        {
          // EATM can this happen?
          //
          if (theBaseTypeDefinition != getContentType())
          {
            createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-ct-extends.2.1");
          }
          // else if the base isn't final for extension, EATM but we can't test for that because it's not in the spec...
        }
      }
      else
      {
        // The null cases are already diagnosed; EATM except for errors above
        //
        if (xsdComplexTypeDefinition != null)
        {
          if (xsdComplexTypeDefinition.getFinal().contains(XSDComplexFinal.RESTRICTION_LITERAL))
          {
            createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.1", xsdComplexTypeDefinition.getURI());
          }

          XSDComplexTypeDefinitionImpl.validateAttributeGroup
            (this,
             getAttributeWildcardContent(),
             xsdComplexTypeDefinition.getAttributeUses(),
             getAttributeUses(),
             xsdComplexTypeDefinition.getAttributeWildcard(),
             getAttributeWildcard());

          if (getSimpleType() != null)
          {
            if (xsdSimpleTypeDefinition != null)
            {
              XSDTypeDefinition badType = getSimpleType().getBadTypeDerivation(xsdSimpleTypeDefinition, true, true);
              if (badType != null)
              {
                createDiagnostic
                  (XSDDiagnosticSeverity.ERROR_LITERAL, 
                   "derivation-ok-restriction.5.1.1", 
                   getSimpleType().getURI(),
                   xsdSimpleTypeDefinition.getURI());
              }
            }
            else if (xsdComplexTypeDefinition.getContentTypeCategory() != XSDContentTypeCategory.MIXED_LITERAL ||
                       !xsdComplexTypeDefinition.getComplexType().isEmptiable())
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.5.1.2");
            }
          }
          else if (getComplexType() == null || getContentTypeCategory() == XSDContentTypeCategory.EMPTY_LITERAL)
          {
            if (xsdComplexTypeDefinition.getContentTypeCategory() == XSDContentTypeCategory.SIMPLE_LITERAL ||
                  xsdComplexTypeDefinition.getContentTypeCategory() != XSDContentTypeCategory.EMPTY_LITERAL &&
                  !xsdComplexTypeDefinition.getComplexType().isEmptiable())
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.5.2");
            }
          }
          else 
          {
            // EATM the spec kind of trails off here without adequate diagnostics for explanation.
            //
            if (xsdComplexTypeDefinition.getComplexType() == null)
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.5.3.1");
            }
            else if (getContentTypeCategory() == XSDContentTypeCategory.MIXED_LITERAL &&
                       xsdComplexTypeDefinition.getContentTypeCategory() != XSDContentTypeCategory.MIXED_LITERAL)
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.5.3.2");
            }
            else if (!((XSDParticleImpl)getComplexType()).isSubset(xsdComplexTypeDefinition.getComplexType(), true))
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.5.3.3");
            }
          }
        }
      }
    }

    XSDWildcard theAttributeWildcard = getAttributeWildcard();
    if (theAttributeWildcard != null &&
          theAttributeWildcard.getNamespaceConstraint().isEmpty() &&
          theAttributeWildcard.getNamespaceConstraintCategory() == XSDNamespaceConstraintCategory.NOT_LITERAL)
    {
       createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-ct.4");
    }

    if (isCircular() && !XSDConstants.isURType(this))
    {
      createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "ct-props-correct.3");
    }

    XSDAttributeDeclaration idAttribute = null;

    Set<String> uris = new HashSet<String>();
    for (XSDAttributeUse xsdAttributeUse : getAttributeUses())
    {
      XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttributeUse.getAttributeDeclaration();
      String uri = xsdAttributeDeclaration.getURI();
      if (prohibitedAttributeURIs != null && prohibitedAttributeURIs.containsKey(uri))
      {
        getDiagnosticTarget(xsdAttributeUse).createDiagnostic
          (XSDDiagnosticSeverity.ERROR_LITERAL, "cos-ct-extends.1.5.1", uri);
      }
      if (!uris.add(uri))
      {
        getDiagnosticTarget(xsdAttributeUse).createDiagnostic
          (XSDDiagnosticSeverity.ERROR_LITERAL, "ct-props-correct.4", uri);
      }
      if (XSDConstants.isOrIsDerivedFromID(xsdAttributeDeclaration.getTypeDefinition()))
      {
        if (idAttribute != null)
        {
          getDiagnosticTarget(xsdAttributeUse).createDiagnostic
            (XSDDiagnosticSeverity.ERROR_LITERAL, "ct-props-correct.5", xsdAttributeDeclaration.getURI(), idAttribute.getURI());
        }
        else
        {
          idAttribute = xsdAttributeDeclaration;
        }
      }
    }
  }

  protected static Map<String, XSDAttributeDeclaration> getProhibitedAttributeURIs(XSDComplexTypeDefinition xsdComplexTypeDefinition)
  {
    Map<String, XSDAttributeDeclaration> result = getProhibitedAttributes(xsdComplexTypeDefinition.getAttributeContents());
    if (xsdComplexTypeDefinition.getBaseTypeDefinition() instanceof XSDComplexTypeDefinition && 
          !xsdComplexTypeDefinition.isCircular())
    {
      result.putAll
        (getProhibitedAttributes
          (((XSDComplexTypeDefinition)xsdComplexTypeDefinition.getBaseTypeDefinition()).getAttributeContents()));
    }
    return result;
  }

  protected static Map<String, XSDAttributeDeclaration> getProhibitedAttributes(Collection<XSDAttributeGroupContent> xsdAttributeContents)
  {
    Map<String, XSDAttributeDeclaration> result = new HashMap<String, XSDAttributeDeclaration>();
    for (XSDAttributeGroupContent xsdAttributeGroupContent :  xsdAttributeContents)
    {
      if (xsdAttributeGroupContent instanceof XSDAttributeGroupDefinition)
      {
        XSDAttributeGroupDefinition xsdAttributeGroupDefinition = (XSDAttributeGroupDefinition)xsdAttributeGroupContent;
        result.putAll(getProhibitedAttributes(xsdAttributeGroupDefinition.getContents()));
      }
      else
      {
        XSDAttributeUse xsdAttributeUse = (XSDAttributeUse)xsdAttributeGroupContent;
        if (xsdAttributeUse.getUse() == XSDAttributeUseCategory.PROHIBITED_LITERAL)
        {
          XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttributeUse.getAttributeDeclaration();
          result.put(xsdAttributeDeclaration.getURI(), xsdAttributeDeclaration);
        }
      }
    }
    return result;
  }

  public static void validateAttributeGroup
    (XSDConcreteComponentImpl xsdConcreteComponent, 
     XSDWildcard containedWildcard,
     EList<XSDAttributeUse> baseXSDAttributeUses, 
     EList<XSDAttributeUse> xsdAttributeUses, 
     XSDWildcard baseXSDWildcard, 
     XSDWildcard xsdWildcard)
  {
    List<XSDAttributeUse> unmatchedBaseAttributeUses = new ArrayList<XSDAttributeUse>(baseXSDAttributeUses);
    for (XSDAttributeUse xsdAttributeUse : xsdAttributeUses)
    {
      XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttributeUse.getAttributeDeclaration();
      boolean matched = false;
      for (XSDAttributeUse baseXSDAttributeUse :  baseXSDAttributeUses)
      {
        XSDAttributeDeclaration baseXSDAttributeDeclaration = baseXSDAttributeUse.getAttributeDeclaration();
        if (xsdAttributeDeclaration.hasSameNameAndTargetNamespace(baseXSDAttributeDeclaration))
        {
          if (xsdAttributeDeclaration.getTypeDefinition() != null)
          {
            XSDTypeDefinition badType = 
              xsdAttributeDeclaration.getTypeDefinition().getBadTypeDerivation
                (baseXSDAttributeDeclaration.getTypeDefinition(), true, true);
            if (badType != null)
            {
              xsdConcreteComponent.getDiagnosticTarget(xsdAttributeUse).createDiagnostic
                (XSDDiagnosticSeverity.ERROR_LITERAL, 
                 "derivation-ok-restriction.2.1.2", 
                 xsdAttributeDeclaration.getURI(),
                 baseXSDAttributeDeclaration.getTypeDefinition().getURI());
            }
          }

          if (baseXSDAttributeUse.isRequired() && !xsdAttributeUse.isRequired())
          {
            xsdConcreteComponent.getDiagnosticTarget(xsdAttributeUse).createDiagnostic
              (XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.2.1.1", xsdAttributeDeclaration.getURI());
          }

          unmatchedBaseAttributeUses.remove(baseXSDAttributeUse);
          matched = true;
          break;
        }
      }

      if (!matched)
      {
        if (baseXSDWildcard == null || !baseXSDWildcard.allows(xsdAttributeDeclaration.getTargetNamespace()))
        {
          xsdConcreteComponent.getDiagnosticTarget(xsdAttributeUse).createDiagnostic
            (XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.2.2", xsdAttributeDeclaration.getURI());
        }
      }
    }

    for (XSDAttributeUse baseXSDAttributeUse : unmatchedBaseAttributeUses)
    {
      if (baseXSDAttributeUse.isRequired())
      {
        xsdConcreteComponent.createDiagnostic
          (XSDDiagnosticSeverity.ERROR_LITERAL, 
           "derivation-ok-restriction.3", 
           baseXSDAttributeUse.getAttributeDeclaration().getURI());
      }
    }

    if (xsdWildcard != null)
    {
      if (baseXSDWildcard == null || !xsdWildcard.isWildcardSubset(baseXSDWildcard))
      {
        XSDConcreteComponentImpl target = xsdConcreteComponent;
        if (containedWildcard != null)
        {
          target = (XSDConcreteComponentImpl)containedWildcard;
        }
        target.createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "derivation-ok-restriction.4");
      }
    }
  }

  @Override
  protected void reconcileAttributes(Element changedElement)
  {
    super.reconcileAttributes(changedElement);

    switch (XSDConstants.nodeType(changedElement))
    {
      case XSDConstants.COMPLEXTYPE_ELEMENT:
      {
        if (changedElement.hasAttributeNS(null, XSDConstants.ABSTRACT_ATTRIBUTE))
        {
          String newAbstract = changedElement.getAttributeNS(null, XSDConstants.ABSTRACT_ATTRIBUTE);
          setAbstract(convertToBoolean(newAbstract));
        }
        else
        {
          unsetAbstract();
        }

        if (changedElement.hasAttributeNS(null, XSDConstants.FINAL_ATTRIBUTE))
        {
          setStringLexicalFinal(changedElement.getAttributeNS(null, XSDConstants.FINAL_ATTRIBUTE));
        }
        else if (isSetLexicalFinal())
        {
          unsetLexicalFinal();
        }

        if (changedElement.hasAttributeNS(null, XSDConstants.BLOCK_ATTRIBUTE))
        {
          setStringBlock(changedElement.getAttributeNS(null, XSDConstants.BLOCK_ATTRIBUTE));
        }
        else if (isSetBlock())
        {
          unsetBlock();
        }

        if (changedElement.hasAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE))
        {
          String newAbstract = changedElement.getAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE);
          setMixed(convertToBoolean(newAbstract));
        }
        else
        {
          Element [] contentElementPair = getContentElementPair();
          if (contentElementPair != null && 
                contentElementPair[0] != null &&
                contentElementPair[0].hasAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE))
          {
            String newAbstract = contentElementPair[0].getAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE);
            setMixed(convertToBoolean(newAbstract));
          }
          else
          {
            unsetMixed();
          }
        }

        break;
      }
      case XSDConstants.COMPLEXCONTENT_ELEMENT:
      {
        if (changedElement.hasAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE))
        {
          String newMixed = changedElement.getAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE);
          setMixed(convertToBoolean(newMixed));
        }
        else
        {
          Element theElement = getElement();
          if (!theElement.hasAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE))
          {
            unsetMixed();
          }
        }
        break;
      }
      case XSDConstants.EXTENSION_ELEMENT:
      case XSDConstants.RESTRICTION_ELEMENT:
      {

        XSDTypeDefinition newBaseTypeDefinition = getBaseTypeDefinition();
        if (changedElement.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE))
        {
          newBaseTypeDefinition =
            resolveSimpleTypeDefinitionURI(XSDConstants.lookupQNameForAttribute(changedElement, XSDConstants.BASE_ATTRIBUTE));
        }
        handleNewBaseTypeDefinition(newBaseTypeDefinition);
        break;
      }
    }
  }

  protected XSDTypeDefinition handleNewBaseTypeDefinition(XSDTypeDefinition newBaseTypeDefinition)
  {
    if (newBaseTypeDefinition == null)
    {
      XSDSchema xsdSchema = getSchema();
      if (xsdSchema == null)
      {
        Element theElement = getElement();
        if (theElement != null)
        {
          newBaseTypeDefinition =
            XSDSchemaImpl.getSchemaForSchema(theElement.getNamespaceURI()).resolveComplexTypeDefinition("anyType");
        }
        else
        {
          newBaseTypeDefinition = this;
        }
      }
      else
      {
        newBaseTypeDefinition = xsdSchema.getSchemaForSchema().resolveComplexTypeDefinition("anyType");
      }
    }

    if (eContainer instanceof XSDRedefine)
    {
      XSDSchema redefinedSchema = ((XSDRedefine)eContainer).getIncorporatedSchema();
      if (redefinedSchema != null)
      {
        Map<XSDComponent, XSDComponent> redefinitionMap = ((XSDSchemaImpl)redefinedSchema).getRedefinitionMap();
        if (redefinitionMap.containsKey(newBaseTypeDefinition))
        {
          XSDComponent replacement = redefinitionMap.get(this);
          if (replacement != null)
          {
            newBaseTypeDefinition = (XSDTypeDefinition)replacement;
          }
        }
      }
    }

    if (newBaseTypeDefinition != getBaseTypeDefinition())
    {
      setBaseTypeDefinition(newBaseTypeDefinition);
    }

    return newBaseTypeDefinition;
  }

  @Override
  protected Node getAdoptionParentNode(EReference eReference)
  {
    if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__CONTENT ||
          eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS ||
          eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT)
    {
      Element [] contentElementPair = getContentElementPair();
      if (contentElementPair[1] != null)
      {
        return contentElementPair[1];
      }
    }

    return super.getAdoptionParentNode(eReference);
  }

  @Override
  protected Collection<Element> getContentNodes(Element changedElement)
  {
    Collection<Element> result = new ArrayList<Element>();
    for (Node child = getElement().getFirstChild(); child != null; child = child.getNextSibling())
    {
      switch (XSDConstants.nodeType(child))
      {
        case XSDConstants.SIMPLECONTENT_ELEMENT:
        {
          result.add((Element)child);

          // DROP to case
        }
        case XSDConstants.COMPLEXCONTENT_ELEMENT:
        {
          for (Node grandChild = child.getFirstChild(); grandChild != null; grandChild = grandChild.getNextSibling())
          {
            switch (XSDConstants.nodeType(grandChild))
            {
              case XSDConstants.ANNOTATION_ELEMENT:
              {
                result.add((Element)grandChild);
                break;
              }
              case XSDConstants.EXTENSION_ELEMENT:
              case XSDConstants.RESTRICTION_ELEMENT:
              {
                for (Node greatGrandChild = grandChild.getFirstChild(); 
                     greatGrandChild != null; 
                     greatGrandChild = greatGrandChild.getNextSibling())
                {
                  switch (XSDConstants.nodeType(greatGrandChild))
                  {
                    case XSDConstants.GROUP_ELEMENT:
                    case XSDConstants.ALL_ELEMENT:
                    case XSDConstants.CHOICE_ELEMENT:
                    case XSDConstants.SEQUENCE_ELEMENT:
                    case XSDConstants.ANYATTRIBUTE_ELEMENT:
                    case XSDConstants.ATTRIBUTE_ELEMENT:
                    case XSDConstants.ATTRIBUTEGROUP_ELEMENT:
                    case XSDConstants.ANNOTATION_ELEMENT:
                    {
                      result.add((Element)greatGrandChild);
                      break;
                    }
                  }
                }
                break;
              }
            }
          }
          break;
        }
        case XSDConstants.GROUP_ELEMENT:
        case XSDConstants.ALL_ELEMENT:
        case XSDConstants.CHOICE_ELEMENT:
        case XSDConstants.SEQUENCE_ELEMENT:
        case XSDConstants.ANYATTRIBUTE_ELEMENT:
        case XSDConstants.ATTRIBUTE_ELEMENT:
        case XSDConstants.ATTRIBUTEGROUP_ELEMENT:
        case XSDConstants.ANNOTATION_ELEMENT:
        {
          result.add((Element)child);
          break;
        }
      }
    }
    return result;
  }

  @Override
  protected void handleUnreconciledElement(Element child, List<XSDConcreteComponent> newContents, List<XSDConcreteComponent> remainingContents)
  {
    switch (XSDConstants.nodeType(child))
    {
      case XSDConstants.GROUP_ELEMENT:
      case XSDConstants.ALL_ELEMENT:
      case XSDConstants.CHOICE_ELEMENT:
      case XSDConstants.SEQUENCE_ELEMENT:
      {
        XSDParticle xsdParticle = XSDParticleImpl.createParticle(child);
        if (xsdParticle != null)
        {
          newContents.add(xsdParticle);
        }
        break;
      }
      case XSDConstants.SIMPLECONTENT_ELEMENT:
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition = XSDSimpleTypeDefinitionImpl.createSimpleTypeDefinition(child);
        if (xsdSimpleTypeDefinition != null)
        {
          newContents.add(xsdSimpleTypeDefinition);
        }
        break;
      }
      case XSDConstants.ATTRIBUTE_ELEMENT:
      {
        XSDAttributeUse xsdAttributeUse = XSDAttributeUseImpl.createAttributeUse(child);
        if (xsdAttributeUse != null)
        {
          newContents.add(xsdAttributeUse);
        }
        break;
      }
      case XSDConstants.ATTRIBUTEGROUP_ELEMENT:
      {
        XSDAttributeGroupDefinition xsdAttributeGroupDefinition = XSDAttributeGroupDefinitionImpl.createAttributeGroupDefinition(child);
        if (xsdAttributeGroupDefinition != null)
        {
          newContents.add(xsdAttributeGroupDefinition);
        }
        break;
      }
      case XSDConstants.ANYATTRIBUTE_ELEMENT:
      {
        XSDWildcard xsdWildcard = XSDWildcardImpl.createWildcard(child);
        if (xsdWildcard != null)
        {
          newContents.add(xsdWildcard);
        }
        break;
      }
      case XSDConstants.ANNOTATION_ELEMENT:
      {
        XSDAnnotation xsdAnnotation = XSDAnnotationImpl.createAnnotation(child);
        if (xsdAnnotation != null)
        {
          newContents.add(xsdAnnotation);
        }
        break;
      }
    }
  }

  @Override
  protected void handleReconciliation(List<XSDConcreteComponent> newContents, List<XSDConcreteComponent> remainingContents)
  {
    handleAnnotationReconciliation(XSDPackage.Literals.XSD_TYPE_DEFINITION__ANNOTATION, newContents, remainingContents);
    handleAnnotationReconciliation(XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION, newContents, remainingContents);
    handleAnnotationReconciliation(XSDPackage.Literals.XSD_TYPE_DEFINITION__DERIVATION_ANNOTATION, newContents, remainingContents);

    XSDTypeDefinition newBaseTypeDefinition = null;
    XSDComplexTypeContent newContent =  null;

    if (!newContents.isEmpty() && newContents.get(0) instanceof XSDComplexTypeContent)
    {
      newContent = (XSDComplexTypeContent)newContents.get(0);
      newContents.remove(0);
    }

    if (newContent != getContent())
    {
      remainingContents.remove(getContent());
      setContent(newContent);
    }

    XSDWildcard newAttributeWildcard = null;
    if (!newContents.isEmpty())
    {
      int lastIndex = newContents.size() - 1;
      Object last = newContents.get(lastIndex);
      if (last instanceof XSDWildcard)
      {
        newAttributeWildcard = (XSDWildcard)last;
        if (XSDConstants.nodeType(newAttributeWildcard.getElement()) == XSDConstants.ANYATTRIBUTE_ELEMENT)
        {
          newContents.remove(lastIndex);
        }
        else
        {
          newAttributeWildcard = null;
        }
      }
    }
    if (newAttributeWildcard != getAttributeWildcardContent())
    {
      remainingContents.remove(getAttributeWildcardContent());
      setAttributeWildcardContent(newAttributeWildcard);
    }

    if (!remainingContents.isEmpty())
    {
      getAttributeContents().removeAll(remainingContents);
    }
    if (!newContents.isEmpty())
    {
      for (Iterator<XSDConcreteComponent> i = newContents.iterator(); i.hasNext(); )
      {
        if (!(i.next() instanceof XSDAttributeGroupContent))
        {
          i.remove();
        }
      }
      @SuppressWarnings("unchecked") List<XSDAttributeGroupContent> list = (List<XSDAttributeGroupContent>)(List<?>)newContents;
      setListContentAndOrder(getAttributeContents(), list);
    }

    XSDDerivationMethod newDerivationMethod = null;
    Element theElement = getElement();
    LOOP:
    for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
    {
      int childNodeType = XSDConstants.nodeType(child);
      switch (childNodeType)
      {
        case XSDConstants.SIMPLECONTENT_ELEMENT:
        case XSDConstants.COMPLEXCONTENT_ELEMENT:
        {
          for (Node grandChild = child.getFirstChild(); grandChild != null; grandChild = grandChild.getNextSibling())
          {
            int grandChildNodeType = XSDConstants.nodeType(grandChild);
            switch (grandChildNodeType)
            {
              case XSDConstants.EXTENSION_ELEMENT:
              case XSDConstants.RESTRICTION_ELEMENT:
              {
                newDerivationMethod = 
                  grandChildNodeType == XSDConstants.EXTENSION_ELEMENT ?
                    XSDDerivationMethod.EXTENSION_LITERAL :
                    XSDDerivationMethod.RESTRICTION_LITERAL;

                Element elementGrandChild = (Element)grandChild;
                if (elementGrandChild.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE))
                {
                  newBaseTypeDefinition = 
                    resolveTypeDefinitionURI(XSDConstants.lookupQNameForAttribute(elementGrandChild, XSDConstants.BASE_ATTRIBUTE));
                }
                break LOOP;
              }
            }
          }
          break LOOP;
        }
        case XSDConstants.GROUP_ELEMENT:
        case XSDConstants.ALL_ELEMENT:
        case XSDConstants.CHOICE_ELEMENT:
        case XSDConstants.SEQUENCE_ELEMENT:
        {
          break LOOP;
        }
      }
    }

    handleNewBaseTypeDefinition(newBaseTypeDefinition);

    if (newDerivationMethod == null)
    {
      unsetDerivationMethod();
    }
    else if (!isSetDerivationMethod() || newDerivationMethod != getDerivationMethod())
    {
      setDerivationMethod(newDerivationMethod);
    }
  }

  @Override
  protected void changeAttribute(EAttribute eAttribute)
  {
    super.changeAttribute(eAttribute);
    Element theElement = getElement();
    if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__ABSTRACT)
    {
      if (theElement != null)
      {
        niceSetAttribute(theElement, XSDConstants.ABSTRACT_ATTRIBUTE, isSetAbstract() ? isAbstract() ? "true" : "false" : null);
      }
    }
    if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__MIXED)
    {
      if (theElement != null)
      {
        Element targetElement = theElement;
        if (!theElement.hasAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE))
        {
          Element [] contentElementPair = getContentElementPair();
          if (contentElementPair != null && 
                contentElementPair[0] != null && 
                contentElementPair[0].hasAttributeNS(null, XSDConstants.MIXED_ATTRIBUTE))
          {
            targetElement = contentElementPair[0];
          }
        }
        niceSetAttribute(targetElement, XSDConstants.MIXED_ATTRIBUTE, isSetMixed() ? isMixed() ? "true" : "false" : null);
      }
    }
    if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__LEXICAL_FINAL)
    {
      if (theElement != null)
      {
        niceSetAttribute
          (theElement,
           XSDConstants.FINAL_ATTRIBUTE,
           getStringLexicalFinal());
      }
      if (eAttribute != null)
      {
        traverseToRootForPatching();
      }
    }
    if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__BLOCK)
    {
      if (theElement != null)
      {
        niceSetAttribute
          (theElement,
           XSDConstants.BLOCK_ATTRIBUTE,
           getStringBlock());
      }
      if (eAttribute != null)
      {
        traverseToRootForPatching();
      }
    }
    if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__DERIVATION_METHOD)
    {
      if (theElement != null && !isReconciling && (eAttribute == null || !abbreviate()))
      {
        Element [] contentElementPair = findOrCreateContentElementPair();
        if (contentElementPair[1] != null && 
              isSetDerivationMethod() && 
              !contentElementPair[1].getLocalName().equals(getDerivationMethod().getName()))
        {
          Element newElement = createDerivationElement();
          forceReplace(newElement, contentElementPair[1]);
        }
      }
    }
  }

  @Override
  protected void changeReference(EReference eReference)
  {
    super.changeReference(eReference);
    Element theElement = getElement();
    if (eReference == null || eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__BASE_TYPE_DEFINITION)
    {
      XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
      if (theElement != null && !isReconciling && (eReference == null || !abbreviate()))
      {
        Element [] contentElementPair = findOrCreateContentElementPair();
        if (contentElementPair[1] != null)
        {
          XSDSimpleTypeDefinitionImpl theSimpleType = (XSDSimpleTypeDefinitionImpl)getSimpleType();
          if (theSimpleType != null)
          {
            theSimpleType.updatingDOM = true;
          }
          niceSetAttributeURIValue
            (contentElementPair[1], 
             XSDConstants.BASE_ATTRIBUTE, 
             theBaseTypeDefinition == null ?
               theElement.getNamespaceURI() + "#anyType" :
               theBaseTypeDefinition.getURI());
          if (theSimpleType != null)
          {
            theSimpleType.updatingDOM = false;
          }
        }
      }
    }
  }

  protected boolean abbreviate()
  {
    Element theElement = getElement();
    XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
    if ((theBaseTypeDefinition == null || XSDConstants.isURType(theBaseTypeDefinition)) && 
          XSDDerivationMethod.EXTENSION_LITERAL != getDerivationMethod() &&
          !(getContent() instanceof XSDSimpleTypeDefinition) &&
          getDerivationAnnotation() == null &&
          getContentAnnotation() == null)
    {
      Element [] contentElementPair = getContentElementPair();
      if (contentElementPair[1] != null)
      {
        for (Node child = contentElementPair[1].getFirstChild(); child != null; child = child.getNextSibling())
        {
          switch (XSDConstants.nodeType(child))
          {
            case XSDConstants.GROUP_ELEMENT:
            case XSDConstants.ALL_ELEMENT:
            case XSDConstants.CHOICE_ELEMENT:
            case XSDConstants.SEQUENCE_ELEMENT:
            case XSDConstants.ANYATTRIBUTE_ELEMENT:
            case XSDConstants.ATTRIBUTE_ELEMENT:
            case XSDConstants.ATTRIBUTEGROUP_ELEMENT:
            {
              forceEngulf(child, theElement, null);
              niceRemoveChild(theElement, contentElementPair[0]);
              return true;
            }
          }
        }
      }
    }
    return false;
  }

  protected Element [] findOrCreateContentElementPair()
  {
    Element theElement = getElement();
    if (theElement != null && !isReconciling)
    {
      Element [] contentElementPair = getContentElementPair();
      if (contentElementPair[0] == null || contentElementPair[1] == null)
      {
        XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
        if (((theBaseTypeDefinition != null && !XSDConstants.isURType(theBaseTypeDefinition)) || 
               XSDDerivationMethod.EXTENSION_LITERAL == getDerivationMethod()) && 
              !(getContent() instanceof XSDSimpleTypeDefinition))
        {
          contentElementPair = createContentElementPair();
          Node startingNode = theElement.getFirstChild();
          for (Node child = startingNode; child != null; child = child.getNextSibling())
          {
            if (XSDConstants.nodeType(child) == XSDConstants.ANNOTATION_ELEMENT)
            {
              startingNode = child.getNextSibling();
            }
          }

          forceEngulf(contentElementPair[0], contentElementPair[1], theElement, startingNode);

          changeReference(XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__BASE_TYPE_DEFINITION);
        }
      }

      return contentElementPair;
    }
    else
    {
      return null;
    }
  }

  protected Element [] getContentElementPair()
  {
    Element theElement = getElement();
    if (theElement != null)
    {
      Element [] result = new Element [2];
      LOOP:
      for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
      {
        switch (XSDConstants.nodeType(child))
        {
          case XSDConstants.SIMPLECONTENT_ELEMENT:
          case XSDConstants.COMPLEXCONTENT_ELEMENT:
          {
            result[0] = (Element)child;
            for (Node grandChild = child.getFirstChild(); grandChild != null; grandChild = grandChild.getNextSibling())
            {
              switch (XSDConstants.nodeType(grandChild))
              {
                case XSDConstants.EXTENSION_ELEMENT:
                case XSDConstants.RESTRICTION_ELEMENT:
                {
                  result[1] = (Element)grandChild;
                  break LOOP;
                }
              }
            }
            break LOOP;
          }
        }
      }
      return result;
    }
    else
    {
      return null;
    }
  }

  @Override
  protected void adoptContent(EReference eReference, XSDConcreteComponent xsdConcreteComponent)
  {
    Node firstAdoptee = null;

    if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__CONTENT)
    {
      if (xsdConcreteComponent instanceof XSDSimpleTypeDefinition)
      {
        Element [] contentElementPair = getContentElementPair();
        if (contentElementPair != null)
        {
          if (contentElementPair[0] != null)
          {
            if (XSDConstants.nodeType(contentElementPair[0]) == XSDConstants.COMPLEXCONTENT_ELEMENT)
            {
              niceRemoveChild(getElement(), contentElementPair[0]);
            }
            if (contentElementPair[1] != null)
            {
              for (Node child = contentElementPair[1].getFirstChild(); child != null; child = child.getNextSibling())
              {
                switch (XSDConstants.nodeType(child))
                {
                  case XSDConstants.GROUP_ELEMENT:
                  case XSDConstants.ALL_ELEMENT:
                  case XSDConstants.CHOICE_ELEMENT:
                  case XSDConstants.SEQUENCE_ELEMENT:
                  case XSDConstants.ANYATTRIBUTE_ELEMENT:
                  case XSDConstants.ATTRIBUTE_ELEMENT:
                  case XSDConstants.ATTRIBUTEGROUP_ELEMENT:
                  {
                    firstAdoptee = child;
                    break;
                  }
                }
              }
            }
          }
        }
      }
    }

    super.adoptContent(eReference, xsdConcreteComponent);

    if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__CONTENT)
    {
      Element theElement = getElement();
      if (theElement != null && !isReconciling)
      {
        if (xsdConcreteComponent instanceof XSDSimpleTypeDefinition)
        {
          changeReference(XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__BASE_TYPE_DEFINITION);
        }

        Element [] contentElementPair = getContentElementPair();
        if (contentElementPair != null && contentElementPair[1] != null)
        {
          if (firstAdoptee == null)
          {
            for (Node child = getElement().getFirstChild(); child != null; child = child.getNextSibling())
            {
              switch (XSDConstants.nodeType(child))
              {
                case XSDConstants.GROUP_ELEMENT:
                case XSDConstants.ALL_ELEMENT:
                case XSDConstants.CHOICE_ELEMENT:
                case XSDConstants.SEQUENCE_ELEMENT:
                case XSDConstants.ANYATTRIBUTE_ELEMENT:
                case XSDConstants.ATTRIBUTE_ELEMENT:
                case XSDConstants.ATTRIBUTEGROUP_ELEMENT:
                {
                  firstAdoptee = child;
                  break;
                }
              }
            }
          }

          if (firstAdoptee != null)
          {
            forceEngulf(firstAdoptee, contentElementPair[1], null);
          }
        }
      }

      traverseToRootForPatching();
    }
    else if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS)
    {
      traverseToRootForPatching();
    }
    else if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT)
    {
      traverseToRootForPatching();
    }
    else if (eReference == XSDPackage.Literals.XSD_TYPE_DEFINITION__ANNOTATION)
    {
      getAnnotations().add(0, (XSDAnnotation)xsdConcreteComponent);
    }
    else if (eReference == XSDPackage.Literals.XSD_TYPE_DEFINITION__DERIVATION_ANNOTATION)
    {
      getAnnotations().add(getAnnotation() == null ? 0 : 1, (XSDAnnotation)xsdConcreteComponent);
    }
    else if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION)
    {
      getAnnotations().add((XSDAnnotation)xsdConcreteComponent);
    }
  }

  @Override
  protected void orphanContent(EReference eReference, XSDConcreteComponent xsdConcreteComponent)
  {
    Node firstAdoptee = null;
    if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__CONTENT)
    {
      if (xsdConcreteComponent instanceof XSDSimpleTypeDefinition)
      {
        Element [] contentElementPair = getContentElementPair();
        if (contentElementPair != null)
        {
          if (contentElementPair[1] != null)
          {
            for (Node child = contentElementPair[1].getFirstChild(); child != null; child = child.getNextSibling())
            {
              switch (XSDConstants.nodeType(child))
              {
                case XSDConstants.GROUP_ELEMENT:
                case XSDConstants.ALL_ELEMENT:
                case XSDConstants.CHOICE_ELEMENT:
                case XSDConstants.SEQUENCE_ELEMENT:
                case XSDConstants.ANYATTRIBUTE_ELEMENT:
                case XSDConstants.ATTRIBUTE_ELEMENT:
                case XSDConstants.ATTRIBUTEGROUP_ELEMENT:
                {
                  firstAdoptee = child;
                  break;
                }
              }
            }
          }
        }
      }
    }

    super.orphanContent(eReference, xsdConcreteComponent);

    if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__CONTENT)
    {
      if (firstAdoptee != null)
      {
        Element theElement = getElement();
        if (theElement != null && !isReconciling)
        {
          Element [] contentElementPair = findOrCreateContentElementPair();
          if (contentElementPair != null && contentElementPair[1] != null)
          {
            forceEngulf(firstAdoptee, contentElementPair[1], null);
          }
          else
          {
            forceEngulf(firstAdoptee, theElement, null);
          }
        }
      }

      traverseToRootForPatching();
    }
    else if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS)
    {
      traverseToRootForPatching();
    }
    else if (eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT)
    {
      traverseToRootForPatching();
    }
    else if (eReference == XSDPackage.Literals.XSD_TYPE_DEFINITION__ANNOTATION ||
               eReference == XSDPackage.Literals.XSD_TYPE_DEFINITION__DERIVATION_ANNOTATION ||
               eReference == XSDPackage.Literals.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION)
    {
      getAnnotations().remove(xsdConcreteComponent);
    }
  }

  @Override
  public XSDTypeDefinition getBaseType()
  {
    return getBaseTypeDefinition();
  }

  @Override
  public XSDTypeDefinition getRootType()
  {
    return getRootTypeDefinition();
  }

  public XSDTypeDefinition getRootTypeDefinition()
  {
    XSDTypeDefinition result = this;
    if (!isCircular())
    {
      for (XSDTypeDefinition theBaseType= result.getBaseType();
           theBaseType!= null && !XSDConstants.isURType(theBaseType);
           theBaseType = theBaseType.getBaseType())
      {
        result = theBaseType;
      }
    }
    return result;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDParticle getSyntheticParticle()
  {
    return syntheticParticle;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain basicSetSyntheticParticle(XSDParticle newSyntheticParticle, NotificationChain msgs)
  {
    XSDParticle oldSyntheticParticle = syntheticParticle;
    syntheticParticle = newSyntheticParticle;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE, oldSyntheticParticle, newSyntheticParticle);
      if (msgs == null) msgs = notification; else msgs.add(notification);
    }
    return msgs;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setSyntheticParticle(XSDParticle newSyntheticParticle)
  {
    if (newSyntheticParticle != syntheticParticle)
    {
      NotificationChain msgs = null;
      if (syntheticParticle != null)
        msgs = ((InternalEObject)syntheticParticle).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE, null, msgs);
      if (newSyntheticParticle != null)
        msgs = ((InternalEObject)newSyntheticParticle).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE, null, msgs);
      msgs = basicSetSyntheticParticle(newSyntheticParticle, msgs);
      if (msgs != null) msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE, newSyntheticParticle, newSyntheticParticle));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDWildcard getSyntheticWildcard()
  {
    return syntheticWildcard;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain basicSetSyntheticWildcard(XSDWildcard newSyntheticWildcard, NotificationChain msgs)
  {
    XSDWildcard oldSyntheticWildcard = syntheticWildcard;
    syntheticWildcard = newSyntheticWildcard;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD, oldSyntheticWildcard, newSyntheticWildcard);
      if (msgs == null) msgs = notification; else msgs.add(notification);
    }
    return msgs;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setSyntheticWildcard(XSDWildcard newSyntheticWildcard)
  {
    if (newSyntheticWildcard != syntheticWildcard)
    {
      NotificationChain msgs = null;
      if (syntheticWildcard != null)
        msgs = ((InternalEObject)syntheticWildcard).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD, null, msgs);
      if (newSyntheticWildcard != null)
        msgs = ((InternalEObject)newSyntheticWildcard).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD, null, msgs);
      msgs = basicSetSyntheticWildcard(newSyntheticWildcard, msgs);
      if (msgs != null) msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD, newSyntheticWildcard, newSyntheticWildcard));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION:
        return basicSetContentAnnotation(null, msgs);
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT:
        return basicSetContent(null, msgs);
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS:
        return ((InternalEList<?>)getAttributeContents()).basicRemove(otherEnd, msgs);
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT:
        return basicSetAttributeWildcardContent(null, msgs);
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE:
        return basicSetSyntheticParticle(null, msgs);
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD:
        return basicSetSyntheticWildcard(null, msgs);
    }
    return super.eInverseRemove(otherEnd, featureID, msgs);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public Object eGet(int featureID, boolean resolve, boolean coreType)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__DERIVATION_METHOD:
        return getDerivationMethod();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__FINAL:
        return getFinal();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ABSTRACT:
        return isAbstract();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE_CATEGORY:
        return getContentTypeCategory();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__PROHIBITED_SUBSTITUTIONS:
        return getProhibitedSubstitutions();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__LEXICAL_FINAL:
        return getLexicalFinal();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BLOCK:
        return getBlock();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__MIXED:
        return isMixed();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION:
        return getContentAnnotation();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BASE_TYPE_DEFINITION:
        return getBaseTypeDefinition();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT:
        return getContent();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE:
        return getContentType();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_USES:
        return getAttributeUses();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS:
        return getAttributeContents();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD:
        return getAttributeWildcard();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT:
        return getAttributeWildcardContent();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ROOT_TYPE_DEFINITION:
        return getRootTypeDefinition();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE:
        return getSyntheticParticle();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD:
        return getSyntheticWildcard();
    }
    return super.eGet(featureID, resolve, coreType);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @SuppressWarnings("unchecked")
  @Override
  public void eSet(int featureID, Object newValue)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__DERIVATION_METHOD:
        setDerivationMethod((XSDDerivationMethod)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__FINAL:
        getFinal().clear();
        getFinal().addAll((Collection<? extends XSDComplexFinal>)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ABSTRACT:
        setAbstract((Boolean)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE_CATEGORY:
        setContentTypeCategory((XSDContentTypeCategory)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__PROHIBITED_SUBSTITUTIONS:
        getProhibitedSubstitutions().clear();
        getProhibitedSubstitutions().addAll((Collection<? extends XSDProhibitedSubstitutions>)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__LEXICAL_FINAL:
        getLexicalFinal().clear();
        getLexicalFinal().addAll((Collection<? extends XSDComplexFinal>)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BLOCK:
        getBlock().clear();
        getBlock().addAll((Collection<? extends XSDProhibitedSubstitutions>)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__MIXED:
        setMixed((Boolean)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION:
        setContentAnnotation((XSDAnnotation)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BASE_TYPE_DEFINITION:
        setBaseTypeDefinition((XSDTypeDefinition)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT:
        setContent((XSDComplexTypeContent)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE:
        setContentType((XSDComplexTypeContent)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_USES:
        getAttributeUses().clear();
        getAttributeUses().addAll((Collection<? extends XSDAttributeUse>)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS:
        getAttributeContents().clear();
        getAttributeContents().addAll((Collection<? extends XSDAttributeGroupContent>)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD:
        setAttributeWildcard((XSDWildcard)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT:
        setAttributeWildcardContent((XSDWildcard)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE:
        setSyntheticParticle((XSDParticle)newValue);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD:
        setSyntheticWildcard((XSDWildcard)newValue);
        return;
    }
    super.eSet(featureID, newValue);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public void eUnset(int featureID)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__DERIVATION_METHOD:
        unsetDerivationMethod();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__FINAL:
        getFinal().clear();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ABSTRACT:
        unsetAbstract();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE_CATEGORY:
        setContentTypeCategory(CONTENT_TYPE_CATEGORY_EDEFAULT);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__PROHIBITED_SUBSTITUTIONS:
        getProhibitedSubstitutions().clear();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__LEXICAL_FINAL:
        unsetLexicalFinal();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BLOCK:
        unsetBlock();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__MIXED:
        unsetMixed();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION:
        setContentAnnotation((XSDAnnotation)null);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BASE_TYPE_DEFINITION:
        setBaseTypeDefinition((XSDTypeDefinition)null);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT:
        setContent((XSDComplexTypeContent)null);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE:
        setContentType((XSDComplexTypeContent)null);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_USES:
        getAttributeUses().clear();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS:
        getAttributeContents().clear();
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD:
        setAttributeWildcard((XSDWildcard)null);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT:
        setAttributeWildcardContent((XSDWildcard)null);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE:
        setSyntheticParticle((XSDParticle)null);
        return;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD:
        setSyntheticWildcard((XSDWildcard)null);
        return;
    }
    super.eUnset(featureID);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public boolean eIsSet(int featureID)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__DERIVATION_METHOD:
        return isSetDerivationMethod();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__FINAL:
        return final_ != null && !final_.isEmpty();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ABSTRACT:
        return isSetAbstract();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE_CATEGORY:
        return (eFlags & CONTENT_TYPE_CATEGORY_EFLAG) != CONTENT_TYPE_CATEGORY_EFLAG_DEFAULT;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__PROHIBITED_SUBSTITUTIONS:
        return prohibitedSubstitutions != null && !prohibitedSubstitutions.isEmpty();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__LEXICAL_FINAL:
        return isSetLexicalFinal();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BLOCK:
        return isSetBlock();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__MIXED:
        return isSetMixed();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_ANNOTATION:
        return contentAnnotation != null;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__BASE_TYPE_DEFINITION:
        return baseTypeDefinition != null;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT:
        return content != null;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__CONTENT_TYPE:
        return contentType != null;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_USES:
        return attributeUses != null && !attributeUses.isEmpty();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_CONTENTS:
        return attributeContents != null && !attributeContents.isEmpty();
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD:
        return attributeWildcard != null;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ATTRIBUTE_WILDCARD_CONTENT:
        return attributeWildcardContent != null;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__ROOT_TYPE_DEFINITION:
        return getRootTypeDefinition() != null;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_PARTICLE:
        return syntheticParticle != null;
      case XSDPackage.XSD_COMPLEX_TYPE_DEFINITION__SYNTHETIC_WILDCARD:
        return syntheticWildcard != null;
    }
    return super.eIsSet(featureID);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public String toString()
  {
    if (eIsProxy()) return super.toString();

    StringBuffer result = new StringBuffer(super.toString());
    result.append(" (derivationMethod: ");
    if ((eFlags & DERIVATION_METHOD_ESETFLAG) != 0) result.append(DERIVATION_METHOD_EFLAG_VALUES[(eFlags & DERIVATION_METHOD_EFLAG) >>> DERIVATION_METHOD_EFLAG_OFFSET]); else result.append("<unset>");
    result.append(", final: ");
    result.append(final_);
    result.append(", abstract: ");
    if ((eFlags & ABSTRACT_ESETFLAG) != 0) result.append((eFlags & ABSTRACT_EFLAG) != 0); else result.append("<unset>");
    result.append(", contentTypeCategory: ");
    result.append(CONTENT_TYPE_CATEGORY_EFLAG_VALUES[(eFlags & CONTENT_TYPE_CATEGORY_EFLAG) >>> CONTENT_TYPE_CATEGORY_EFLAG_OFFSET]);
    result.append(", prohibitedSubstitutions: ");
    result.append(prohibitedSubstitutions);
    result.append(", lexicalFinal: ");
    result.append(lexicalFinal);
    result.append(", block: ");
    result.append(block);
    result.append(", mixed: ");
    if ((eFlags & MIXED_ESETFLAG) != 0) result.append((eFlags & MIXED_EFLAG) != 0); else result.append("<unset>");
    result.append(')');
    return result.toString();
  }

  @Override
  public XSDSimpleTypeDefinition getSimpleType()
  {
    return 
      getContentType() instanceof XSDSimpleTypeDefinition ?
        (XSDSimpleTypeDefinition)getContentType() :
        null;
  }

  public String getStringLexicalFinal()
  {
    if (isSetLexicalFinal())
    {
      StringBuffer result = new StringBuffer();
      for (Object literal : getLexicalFinal())
      {
        if (result.length() != 0)
        {
          result.append(' ');
        }
        if (literal.toString().equals("all"))
        {
          result.append("#all");
        }
        else
        {
          result.append(literal);
        }
      }
      return result.toString();
    }
    else
    {
      return null;
    }
  }

  public void setStringLexicalFinal(String finalDefault)
  {
    if (finalDefault == null)
    {
      unsetLexicalFinal();
    }
    else
    {
      List<XSDComplexFinal> newLexicalFinal = new ArrayList<XSDComplexFinal>();
      for (StringTokenizer stringTokenizer = new StringTokenizer(finalDefault); stringTokenizer.hasMoreTokens(); )
      {
        String token = stringTokenizer.nextToken();
        if (token.equals("#all"))
        {
          token = "all";
        }
        XSDComplexFinal literal = XSDComplexFinal.get(token);
        if (literal != null)
        {
          newLexicalFinal.add(literal);
        }
      }
      if (!newLexicalFinal.equals(getLexicalFinal()))
      {
        Collection<XSDComplexFinal> oldContents = new ArrayList<XSDComplexFinal>(getLexicalFinal());
        oldContents.removeAll(newLexicalFinal);
        if (!oldContents.isEmpty())
        {
          getLexicalFinal().removeAll(oldContents);
        }
        setListContentAndOrder(getLexicalFinal(), newLexicalFinal);
      }
      else if (newLexicalFinal.isEmpty() && !isSetLexicalFinal())
      {
        getLexicalFinal().clear();
      }
    }
  }

  public String getStringFinal()
  {
    StringBuffer result = new StringBuffer();
    for (Object literal : getFinal())
    {
      if (result.length() != 0)
      {
        result.append(' ');
      }
      result.append(literal);
    }
    return result.toString();
  }


  public String getStringBlock()
  {
    if (isSetBlock())
    {
      StringBuffer result = new StringBuffer();
      for (Object literal : getBlock())
      {
        if (result.length() != 0)
        {
          result.append(' ');
        }
        if (literal.toString().equals("all"))
        {
          result.append("#all");
        }
        else
        {
          result.append(literal);
        }
      }
      return result.toString();
    }
    else
    {
      return null;
    }
  }

  public void setStringBlock(String block)
  {
    if (block == null)
    {
      unsetBlock();
    }
    else
    {
      List<XSDProhibitedSubstitutions> newBlock = new ArrayList<XSDProhibitedSubstitutions>();
      for (StringTokenizer stringTokenizer = new StringTokenizer(block); stringTokenizer.hasMoreTokens(); )
      {
        String token = stringTokenizer.nextToken();
        if (token.equals("#all"))
        {
          token = "all";
        }
        XSDProhibitedSubstitutions literal = XSDProhibitedSubstitutions.get(token);
        if (literal != null)
        {
          newBlock.add(literal);
        }
      }
      if (!newBlock.equals(getBlock()))
      {
        Collection<XSDProhibitedSubstitutions> oldContents = new ArrayList<XSDProhibitedSubstitutions>(getBlock());
        oldContents.removeAll(newBlock);
        if (!oldContents.isEmpty())
        {
          getBlock().removeAll(oldContents);
        }
        setListContentAndOrder(getBlock(), newBlock);
      }
      else if (newBlock.isEmpty() && !isSetBlock())
      {
        getBlock().clear();
      }
    }
  }

  public String getStringProhibitedSubstitutions()
  {
    StringBuffer result = new StringBuffer();
    for (Object literal :  getProhibitedSubstitutions())
    {
      if (result.length() != 0)
      {
        result.append(' ');
      }
      result.append(literal);
    }
    return result.toString();
  }

  @Override
  public XSDTypeDefinition getBadTypeDerivation(XSDTypeDefinition xsdTypeDefinition, boolean extension, boolean restriction)
  {
    if (xsdTypeDefinition == this || isCircular())
    {
      return null;
    }
    else if (getDerivationMethod() == XSDDerivationMethod.EXTENSION_LITERAL ? !extension : !restriction)
    {
      return this;
    }
    else 
    {
      XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
      if (xsdTypeDefinition == theBaseTypeDefinition)
      {
        return null;
      }
      else if (theBaseTypeDefinition == null)
      {
        return this;
      }
      else if (XSDConstants.isURType(theBaseTypeDefinition))
      {
        return theBaseTypeDefinition;
      }
      else
      {
        return theBaseTypeDefinition.getBadTypeDerivation(xsdTypeDefinition, extension, restriction);
      }
    }
  }

  @Override
  public XSDConcreteComponent cloneConcreteComponent(boolean deep, boolean shareDOM)
  {
    XSDComplexTypeDefinitionImpl clonedComplexTypeDefinition =
      (XSDComplexTypeDefinitionImpl)getXSDFactory().createXSDComplexTypeDefinition();
    clonedComplexTypeDefinition.isReconciling = true;

    if (getName() != null)
    {
      clonedComplexTypeDefinition.setName(getName());
    }
    if (isSetMixed())
    {
      clonedComplexTypeDefinition.setMixed(isMixed());
    }
    if (isSetDerivationMethod())
    {
      clonedComplexTypeDefinition.setDerivationMethod(getDerivationMethod());
    }
    if (isSetAbstract())
    {
      clonedComplexTypeDefinition.setAbstract(isAbstract());
    }
    if (isSetBlock())
    {
      if (!getBlock().isEmpty())
      {
        clonedComplexTypeDefinition.getBlock().addAll(getBlock());
      }
      else
      {
        clonedComplexTypeDefinition.getBlock().clear();
      }
    }
    if (isSetLexicalFinal())
    {
      if (!getLexicalFinal().isEmpty())
      {
        clonedComplexTypeDefinition.getLexicalFinal().addAll(getLexicalFinal());
      }
      else
      {
        clonedComplexTypeDefinition.getLexicalFinal().clear();
      }
    }

    if (getBaseTypeDefinition() != null) 
    {
      XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
      clonedComplexTypeDefinition.setBaseTypeDefinition
        (createUnresolvedTypeDefinition
          (theBaseTypeDefinition.getTargetNamespace(), theBaseTypeDefinition.getName()));
    }

    if (deep)
    {
      if (getAnnotation() != null)
      {
        clonedComplexTypeDefinition.setAnnotation((XSDAnnotation)getAnnotation().cloneConcreteComponent(deep, shareDOM));
      }
      if (getDerivationAnnotation() != null)
      {
        clonedComplexTypeDefinition.setDerivationAnnotation
          ((XSDAnnotation)getDerivationAnnotation().cloneConcreteComponent(deep, shareDOM));
      }
      if (getContentAnnotation() != null)
      {
        clonedComplexTypeDefinition.setContentAnnotation((XSDAnnotation)getContentAnnotation().cloneConcreteComponent(deep, shareDOM));
      }
      if (getContent() != null)
      {
        clonedComplexTypeDefinition.setContent((XSDComplexTypeContent)getContent().cloneConcreteComponent(deep, shareDOM));
      }
      if (!getAttributeContents().isEmpty())
      {
        clonedComplexTypeDefinition.getAttributeContents().addAll(cloneConcreteComponents(getAttributeContents(), deep, shareDOM));
      }
      if (getAttributeWildcardContent() != null)
      {
        clonedComplexTypeDefinition.setAttributeWildcardContent
          ((XSDWildcard)getAttributeWildcardContent().cloneConcreteComponent(deep, shareDOM));
      }
    }

    if (shareDOM && getElement() != null)
    {
      clonedComplexTypeDefinition.setElement(getElement());
    }

    clonedComplexTypeDefinition.isReconciling = shareDOM;
    return clonedComplexTypeDefinition;
  }
}

