/**
 * Copyright (c) 2002-2007 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.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
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.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.UniqueEList;
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.EcoreEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDBoundedFacet;
import org.eclipse.xsd.XSDCardinality;
import org.eclipse.xsd.XSDCardinalityFacet;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDComponent;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDConstrainingFacet;
import org.eclipse.xsd.XSDDerivationMethod;
import org.eclipse.xsd.XSDDiagnostic;
import org.eclipse.xsd.XSDDiagnosticSeverity;
import org.eclipse.xsd.XSDEnumerationFacet;
import org.eclipse.xsd.XSDFacet;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDFeature;
import org.eclipse.xsd.XSDFractionDigitsFacet;
import org.eclipse.xsd.XSDFundamentalFacet;
import org.eclipse.xsd.XSDLengthFacet;
import org.eclipse.xsd.XSDMaxExclusiveFacet;
import org.eclipse.xsd.XSDMaxFacet;
import org.eclipse.xsd.XSDMaxInclusiveFacet;
import org.eclipse.xsd.XSDMaxLengthFacet;
import org.eclipse.xsd.XSDMinExclusiveFacet;
import org.eclipse.xsd.XSDMinFacet;
import org.eclipse.xsd.XSDMinInclusiveFacet;
import org.eclipse.xsd.XSDMinLengthFacet;
import org.eclipse.xsd.XSDNumericFacet;
import org.eclipse.xsd.XSDOrdered;
import org.eclipse.xsd.XSDOrderedFacet;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDPatternFacet;
import org.eclipse.xsd.XSDPlugin;
import org.eclipse.xsd.XSDProhibitedSubstitutions;
import org.eclipse.xsd.XSDRedefine;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleFinal;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTotalDigitsFacet;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.XSDVariety;
import org.eclipse.xsd.XSDWhiteSpaceFacet;
import org.eclipse.xsd.impl.type.XSDAnySimpleType;
import org.eclipse.xsd.impl.type.XSDTypeRegister;
import org.eclipse.xsd.util.XSDConstants;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Simple Type Definition</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getVariety <em>Variety</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getFinal <em>Final</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getLexicalFinal <em>Lexical Final</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getValidFacets <em>Valid Facets</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getContents <em>Contents</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getFacetContents <em>Facet Contents</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getFacets <em>Facets</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMemberTypeDefinitions <em>Member Type Definitions</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getFundamentalFacets <em>Fundamental Facets</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getBaseTypeDefinition <em>Base Type Definition</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getPrimitiveTypeDefinition <em>Primitive Type Definition</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getItemTypeDefinition <em>Item Type Definition</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getRootTypeDefinition <em>Root Type Definition</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMinFacet <em>Min Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMaxFacet <em>Max Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMaxInclusiveFacet <em>Max Inclusive Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMinInclusiveFacet <em>Min Inclusive Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMinExclusiveFacet <em>Min Exclusive Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMaxExclusiveFacet <em>Max Exclusive Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getLengthFacet <em>Length Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getWhiteSpaceFacet <em>White Space Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEnumerationFacets <em>Enumeration Facets</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getPatternFacets <em>Pattern Facets</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getCardinalityFacet <em>Cardinality Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getNumericFacet <em>Numeric Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMaxLengthFacet <em>Max Length Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getMinLengthFacet <em>Min Length Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getTotalDigitsFacet <em>Total Digits Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getFractionDigitsFacet <em>Fraction Digits Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getOrderedFacet <em>Ordered Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getBoundedFacet <em>Bounded Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveMaxFacet <em>Effective Max Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveWhiteSpaceFacet <em>Effective White Space Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveMaxLengthFacet <em>Effective Max Length Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveFractionDigitsFacet <em>Effective Fraction Digits Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectivePatternFacet <em>Effective Pattern Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveEnumerationFacet <em>Effective Enumeration Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveTotalDigitsFacet <em>Effective Total Digits Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveMinLengthFacet <em>Effective Min Length Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveLengthFacet <em>Effective Length Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getEffectiveMinFacet <em>Effective Min Facet</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl#getSyntheticFacets <em>Synthetic Facets</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class XSDSimpleTypeDefinitionImpl 
  extends XSDTypeDefinitionImpl 
  implements XSDSimpleTypeDefinition
{
  /**
   * The default value of the '{@link #getVariety() <em>Variety</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getVariety()
   * @generated
   * @ordered
   */
  protected static final XSDVariety VARIETY_EDEFAULT = XSDVariety.ATOMIC_LITERAL;

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

  /**
   * The flags representing the default value of the '{@link #getVariety() <em>Variety</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int VARIETY_EFLAG_DEFAULT = VARIETY_EDEFAULT.ordinal() << VARIETY_EFLAG_OFFSET;

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

  /**
   * The flags representing the value of the '{@link #getVariety() <em>Variety</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getVariety()
   * @generated
   * @ordered
   */
  protected static final int VARIETY_EFLAG = 0x3 << VARIETY_EFLAG_OFFSET;

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

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

  /**
   * 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<XSDSimpleFinal> lexicalFinal;

  /**
   * The cached value of the '{@link #getValidFacets() <em>Valid Facets</em>}' attribute list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getValidFacets()
   * @generated
   * @ordered
   */
  protected EList<String> validFacets;

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

  /**
   * The cached value of the '{@link #getFacetContents() <em>Facet Contents</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getFacetContents()
   * @generated NOT
   * @ordered
   */
  protected EcoreEList<XSDConstrainingFacet> facetContents = null;

  /**
   * The cached value of the '{@link #getFacets() <em>Facets</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getFacets()
   * @generated NOT
   * @ordered
   */
  protected EcoreEList<XSDConstrainingFacet> facets = null;

  /**
   * The cached value of the '{@link #getMemberTypeDefinitions() <em>Member Type Definitions</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getMemberTypeDefinitions()
   * @generated
   * @ordered
   */
  protected EList<XSDSimpleTypeDefinition> memberTypeDefinitions;

  /**
   * The cached value of the '{@link #getFundamentalFacets() <em>Fundamental Facets</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getFundamentalFacets()
   * @generated
   * @ordered
   */
  protected EList<XSDFundamentalFacet> fundamentalFacets;

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

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

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

  /**
   * The cached value of the '{@link #getSyntheticFacets() <em>Synthetic Facets</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getSyntheticFacets()
   * @generated
   * @ordered
   */
  protected EList<XSDFacet> syntheticFacets;

  public static XSDSimpleTypeDefinition createSimpleTypeDefinition(Node node)
  {
    switch (XSDConstants.nodeType(node))
    {
      case XSDConstants.SIMPLETYPE_ELEMENT:
      case XSDConstants.SIMPLECONTENT_ELEMENT:
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition();
        xsdSimpleTypeDefinition.setElement((Element)node);
        return xsdSimpleTypeDefinition;
      }
    }

    return null;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  protected XSDSimpleTypeDefinitionImpl()
  {
    super();
  }

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDVariety getVariety()
  {
    return VARIETY_EFLAG_VALUES[(eFlags & VARIETY_EFLAG) >>> VARIETY_EFLAG_OFFSET];
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setVariety(XSDVariety newVariety)
  {
    XSDVariety oldVariety = VARIETY_EFLAG_VALUES[(eFlags & VARIETY_EFLAG) >>> VARIETY_EFLAG_OFFSET];
    if (newVariety == null) newVariety = VARIETY_EDEFAULT;
    eFlags = eFlags & ~VARIETY_EFLAG | newVariety.ordinal() << VARIETY_EFLAG_OFFSET;
    boolean oldVarietyESet = (eFlags & VARIETY_ESETFLAG) != 0;
    eFlags |= VARIETY_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VARIETY, oldVariety, newVariety, !oldVarietyESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetVariety()
  {
    XSDVariety oldVariety = VARIETY_EFLAG_VALUES[(eFlags & VARIETY_EFLAG) >>> VARIETY_EFLAG_OFFSET];
    boolean oldVarietyESet = (eFlags & VARIETY_ESETFLAG) != 0;
    eFlags = eFlags & ~VARIETY_EFLAG | VARIETY_EFLAG_DEFAULT;
    eFlags &= ~VARIETY_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.UNSET, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VARIETY, oldVariety, VARIETY_EDEFAULT, oldVarietyESet));
  }

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

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDSimpleFinal> getLexicalFinal()
  {
    if (lexicalFinal == null)
    {
      lexicalFinal = new EDataTypeUniqueEList.Unsettable<XSDSimpleFinal>(XSDSimpleFinal.class, this, XSDPackage.XSD_SIMPLE_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<String> getValidFacets()
  {
    if (validFacets == null)
    {
      validFacets = new EDataTypeUniqueEList<String>(String.class, this, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VALID_FACETS);
    }
    return validFacets;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDSimpleTypeDefinition> getContents()
  {
    if (contents == null)
    {
      contents = new EObjectContainmentEList<XSDSimpleTypeDefinition>(XSDSimpleTypeDefinition.class, this, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS);
    }
    return contents;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDConstrainingFacet> getFacetContents()
  {
    if (facetContents == null)
    {
      facetContents = new EObjectContainmentEList<XSDConstrainingFacet>(XSDConstrainingFacet.class, this, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS);
    }
    return facetContents;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDConstrainingFacet> getFacets()
  {
    if (facets == null)
    {
      facets = new EObjectEList<XSDConstrainingFacet>(XSDConstrainingFacet.class, this, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACETS);
    }
    return facets;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDSimpleTypeDefinition> getMemberTypeDefinitions()
  {
    if (memberTypeDefinitions == null)
    {
      memberTypeDefinitions = new EObjectEList<XSDSimpleTypeDefinition>(XSDSimpleTypeDefinition.class, this, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MEMBER_TYPE_DEFINITIONS);
    }
    return memberTypeDefinitions;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDFundamentalFacet> getFundamentalFacets()
  {
    if (fundamentalFacets == null)
    {
      fundamentalFacets = new EObjectContainmentEList<XSDFundamentalFacet>(XSDFundamentalFacet.class, this, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FUNDAMENTAL_FACETS);
    }
    return fundamentalFacets;
  }

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

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDSimpleTypeDefinition getPrimitiveTypeDefinition()
  {
    return primitiveTypeDefinition;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setPrimitiveTypeDefinition(XSDSimpleTypeDefinition newPrimitiveTypeDefinition)
  {
    XSDSimpleTypeDefinition oldPrimitiveTypeDefinition = primitiveTypeDefinition;
    primitiveTypeDefinition = newPrimitiveTypeDefinition;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__PRIMITIVE_TYPE_DEFINITION, oldPrimitiveTypeDefinition, primitiveTypeDefinition));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDSimpleTypeDefinition getItemTypeDefinition()
  {
    return itemTypeDefinition;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setItemTypeDefinition(XSDSimpleTypeDefinition newItemTypeDefinition)
  {
    XSDSimpleTypeDefinition oldItemTypeDefinition = itemTypeDefinition;
    itemTypeDefinition = newItemTypeDefinition;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ITEM_TYPE_DEFINITION, oldItemTypeDefinition, itemTypeDefinition));
  }

  @Override
  public Element createElement()
  {
    XSDComplexTypeDefinition xsdComplexTypeDefinition =
      getContainer() instanceof XSDComplexTypeDefinition ? 
        (XSDComplexTypeDefinition)getContainer() :
        null;

    Element newElement = 
      createElement
        (xsdComplexTypeDefinition != null ?
           XSDConstants.SIMPLECONTENT_ELEMENT : 
           XSDConstants.SIMPLETYPE_ELEMENT);
    setElement(newElement);

    Element childElement = createChildElement();
    newElement.appendChild(childElement);
    return newElement;
  }

  protected Element createChildElement()
  {
    return createElement(getRequiredChildElementNodeType());
  }

  protected int getRequiredChildElementNodeType()
  {
    XSDComplexTypeDefinition xsdComplexTypeDefinition =
      getContainer() instanceof XSDComplexTypeDefinition ? 
        (XSDComplexTypeDefinition)getContainer() :
        null;

    XSDSimpleTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
    if (getItemTypeDefinition() != null && (theBaseTypeDefinition == null || XSDConstants.isURType(theBaseTypeDefinition)))
    {
      return XSDConstants.LIST_ELEMENT;
    }
    else if (!getMemberTypeDefinitions().isEmpty() && (theBaseTypeDefinition == null || XSDConstants.isURType(theBaseTypeDefinition)))
    {
      return XSDConstants.UNION_ELEMENT;
    }
    else
    {
      return
        xsdComplexTypeDefinition == null || XSDDerivationMethod.EXTENSION_LITERAL != xsdComplexTypeDefinition.getDerivationMethod() ? 
          XSDConstants.RESTRICTION_ELEMENT :
          XSDConstants.EXTENSION_ELEMENT;
    }
  }

  @Override
  protected void patch()
  {
    super.patch();

    if (!(getContainer() instanceof XSDComplexTypeDefinition))
    {
      XSDSimpleTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
      if (theBaseTypeDefinition != null && (forceResolve || theBaseTypeDefinition.getContainer() == null))
      {
        theBaseTypeDefinition = resolveSimpleTypeDefinition(theBaseTypeDefinition.getTargetNamespace(), theBaseTypeDefinition.getName());
      }
      theBaseTypeDefinition = handleNewBaseTypeDefinition(theBaseTypeDefinition);
      if (theBaseTypeDefinition == null || !theBaseTypeDefinition.isSetVariety() || theBaseTypeDefinition.getVariety() != getVariety())
      {
        XSDSimpleTypeDefinition theItemTypeDefinition = getItemTypeDefinition();
        if (theItemTypeDefinition != null)
        {
          if (forceResolve || theItemTypeDefinition.getContainer() == null)
          {
            XSDSimpleTypeDefinition newItemTypeDefinition = 
              resolveSimpleTypeDefinition(theItemTypeDefinition.getTargetNamespace(), theItemTypeDefinition.getName());
            if ((forceResolve || newItemTypeDefinition.getContainer() != null) && newItemTypeDefinition != theItemTypeDefinition)
            {
              setItemTypeDefinition(newItemTypeDefinition);
            }
          }
        }
        else
        {
          for (ListIterator<XSDSimpleTypeDefinition> theMemberTypeDefinitions = getMemberTypeDefinitions().listIterator(); 
               theMemberTypeDefinitions.hasNext(); )
          {
            XSDSimpleTypeDefinition theMemberTypeDefinition = theMemberTypeDefinitions.next();
            if (forceResolve || theMemberTypeDefinition.getContainer() == null)
            {
              XSDSimpleTypeDefinition newMemberTypeDefinition = 
                resolveSimpleTypeDefinition(theMemberTypeDefinition.getTargetNamespace(), theMemberTypeDefinition.getName());
              if ((forceResolve || newMemberTypeDefinition.getContainer() != null) && newMemberTypeDefinition != theMemberTypeDefinition)
              {
                theMemberTypeDefinitions.set(newMemberTypeDefinition);
              }
            }
          }
        }
      }
    }

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

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

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

  protected XSDWhiteSpaceFacet effectiveWhiteSpaceFacet;
  @Override
  protected void handleAnalysis()
  {
    XSDSimpleTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();

    XSDConcreteComponent container = getContainer();
    if (container instanceof XSDComplexTypeDefinition)
    {
      if (!getContents().contains(theBaseTypeDefinition))
      {
        XSDComplexTypeDefinition xsdComplexTypeDefinition = (XSDComplexTypeDefinitionImpl)container;
        XSDTypeDefinition complexBaseTypeDefinition = xsdComplexTypeDefinition.getBaseTypeDefinition();
        if (complexBaseTypeDefinition != null)
        {
          ((XSDConcreteComponentImpl)complexBaseTypeDefinition).analyze();
          theBaseTypeDefinition = handleNewBaseTypeDefinition(complexBaseTypeDefinition.getSimpleType());
        }
      }
    }

    if (getFundamentalFacets().isEmpty())
    {
      createFundamentalFacets();
    }

    List<XSDConstrainingFacet> newFacets = null;
    boolean newBounded = false;
    XSDCardinality newCardinality = XSDCardinality.FINITE_LITERAL;
    boolean newNumeric = false;
    XSDOrdered newOrdered = XSDOrdered.FALSE_LITERAL;
    XSDSimpleTypeDefinition newPrimitiveTypeDefinition = null;
    XSDVariety newVariety = null;
    EList<String> newValidFacets = null;

    if (theBaseTypeDefinition != null && theBaseTypeDefinition.getContainer() != null)
    {
      if (!((XSDConcreteComponentImpl)theBaseTypeDefinition).analyze() && !XSDConstants.isURType(theBaseTypeDefinition) && theBaseTypeDefinition.isCircular())
      {
        analysisState = CIRCULAR;
      }
      if (theBaseTypeDefinition != this)
      {
        if (!XSDConstants.isURType(this))
        {
          newVariety = XSDVariety.ATOMIC_LITERAL;
          newPrimitiveTypeDefinition = this;
        }

        if (!XSDConstants.isURType(theBaseTypeDefinition))
        {
          newVariety = theBaseTypeDefinition.getVariety();
          newPrimitiveTypeDefinition = theBaseTypeDefinition.getPrimitiveTypeDefinition();
          newBounded = theBaseTypeDefinition.getBoundedFacet().isValue();
          newCardinality = theBaseTypeDefinition.getCardinalityFacet().getValue();
          newNumeric = theBaseTypeDefinition.getNumericFacet().isValue();
          newOrdered = theBaseTypeDefinition.getOrderedFacet().getValue();
          newValidFacets = theBaseTypeDefinition.getValidFacets();

          if (XSDVariety.LIST_LITERAL == theBaseTypeDefinition.getVariety())
          {
            XSDSimpleTypeDefinition newItemTypeDefinition = theBaseTypeDefinition.getItemTypeDefinition();
            if (newItemTypeDefinition != getItemTypeDefinition())
            {
              setItemTypeDefinition(newItemTypeDefinition);
            }
          }
          else if (XSDVariety.UNION_LITERAL == theBaseTypeDefinition.getVariety())
          {
            List<XSDSimpleTypeDefinition> newMemberTypeDefinitions = theBaseTypeDefinition.getMemberTypeDefinitions();
            List<XSDSimpleTypeDefinition> remainingMemberTypeDefinitions = new ArrayList<XSDSimpleTypeDefinition>(getMemberTypeDefinitions());
            remainingMemberTypeDefinitions.removeAll(newMemberTypeDefinitions);
            if (!remainingMemberTypeDefinitions.isEmpty())
            {
              getMemberTypeDefinitions().removeAll(remainingMemberTypeDefinitions);
            }
            if (!newMemberTypeDefinitions.isEmpty())
            {
              setListContentAndOrder(getMemberTypeDefinitions(), newMemberTypeDefinitions);
            }
          }
        }
        else
        {
          newFacets = new ArrayList<XSDConstrainingFacet>(getFacetContents());
        }
      }
      else
      {
        newFacets = new ArrayList<XSDConstrainingFacet>(getFacetContents());
      }
    }
    else
    {
      newFacets = new ArrayList<XSDConstrainingFacet>(getFacetContents());
    }

    if (theBaseTypeDefinition == null || XSDConstants.isURType(theBaseTypeDefinition))
    {
      XSDSimpleTypeDefinition theItemTypeDefinition = getItemTypeDefinition();
      if (theItemTypeDefinition != null && theItemTypeDefinition.getContainer() != null)
      {
        newVariety = XSDVariety.LIST_LITERAL;
        newPrimitiveTypeDefinition = null;
        if (!((XSDConcreteComponentImpl)theItemTypeDefinition).analyze() && !XSDConstants.isURType(theItemTypeDefinition) && theItemTypeDefinition.isCircular())
        {
          analysisState = CIRCULAR;
        }
        newValidFacets = getValidFacetsForList();
        if (effectiveWhiteSpaceFacet == null)
        {
          effectiveWhiteSpaceFacet = getXSDFactory().createXSDWhiteSpaceFacet();
          effectiveWhiteSpaceFacet.setLexicalValue("collapse");
          effectiveWhiteSpaceFacet.setFixed(true);
          getSyntheticFacets().add(effectiveWhiteSpaceFacet);
        }
        if (newFacets != null)
        {
          newFacets.add(effectiveWhiteSpaceFacet);
        }
      }
      else if (!getMemberTypeDefinitions().isEmpty())
      {
        newVariety = XSDVariety.UNION_LITERAL;
        newPrimitiveTypeDefinition = null;
        newNumeric = true;
        for (XSDSimpleTypeDefinition theMemberTypeDefinition : getMemberTypeDefinitions())
        {
          if (theMemberTypeDefinition.getContainer() != null)
          {
            if (!((XSDConcreteComponentImpl)theMemberTypeDefinition).analyze() && !XSDConstants.isURType(theMemberTypeDefinition) && theMemberTypeDefinition.isCircular())
            {
              analysisState = CIRCULAR;
            }
            if (!theMemberTypeDefinition.getNumericFacet().isValue())
            {
              newNumeric = false;
            }
          }
        }

        XSDTypeDefinition lowestCommonAncestor = getLowestCommonAncestor(getMemberTypeDefinitions());
        if (lowestCommonAncestor instanceof XSDSimpleTypeDefinition && lowestCommonAncestor.getContainer() != null)
        {
          newOrdered = ((XSDSimpleTypeDefinition)lowestCommonAncestor).getOrderedFacet().getValue();
        }
        newValidFacets = getValidFacetsForUnion();
      }
      else if (getElement() != null)
      {
        LOOP:
        for (Node child = getElement().getFirstChild(); child != null; child = child.getNextSibling())
        {
          switch (XSDConstants.nodeType(child))
          {
            case XSDConstants.UNION_ELEMENT:
            {
              newVariety = XSDVariety.UNION_LITERAL;
              newPrimitiveTypeDefinition = null;
              newValidFacets = getValidFacetsForUnion();
              break LOOP;
            }
            case XSDConstants.LIST_ELEMENT:
            {
              newVariety = XSDVariety.LIST_LITERAL;
              newPrimitiveTypeDefinition = null;
              newValidFacets = getValidFacetsForList();
              break LOOP;
            }
          }
        }
      }
    }

    if (newVariety != null)
    {
      if (!isSetVariety() || newVariety != getVariety())
      {
        setVariety(newVariety);
      }
    }
    else if (isSetVariety())
    {
      unsetVariety();
    }

    if (newPrimitiveTypeDefinition != getPrimitiveTypeDefinition())
    {
      setPrimitiveTypeDefinition(newPrimitiveTypeDefinition);
    }

    // This ensures the the facets are analyzed when the containing type is relatively well-analyzed.
    //
    super.handleAnalysis();

    if (newFacets == null)
    {
      newFacets = mergeFacets();
    }

    XSDAnnotation theAnnotation = getAnnotation();
    if (theAnnotation != null)
    {
      for (Element applicationInformationElement :  theAnnotation.getApplicationInformation())
      {
        for (Node child = applicationInformationElement.getFirstChild(); child != null; child = child.getNextSibling())
        {
          switch (XSDConstants.hfpNodeType(child))
          {
            case XSDConstants.HFP_HASFACET_ELEMENT:
            {
              Element childElement = (Element)child;
              String facetName = childElement.getAttributeNS(null, XSDConstants.HFP_NAME_ATTRIBUTE);
              if (newValidFacets == null)
              {
                newValidFacets = new BasicEList<String>();
              }
              newValidFacets.add(facetName);
              break;
            }
            case XSDConstants.HFP_HASPROPERTY_ELEMENT:
            {
              Element childElement = (Element)child;
              String propertyName = childElement.getAttributeNS(null, XSDConstants.HFP_NAME_ATTRIBUTE);
              String propertyValue = childElement.getAttributeNS(null, XSDConstants.HFP_VALUE_ATTRIBUTE);
              if ("bounded".equals(propertyName))
              {
                newBounded = "true".equals(propertyValue);
              }
              else if ("cardinality".equals(propertyName))
              {
                newCardinality = 
                  "countably infinite".equals(propertyValue) ? 
                    XSDCardinality.COUNTABLY_INFINITE_LITERAL : 
                    XSDCardinality.get(propertyValue);
              }
              else if ("numeric".equals(propertyName))
              {
                newNumeric = "true".equals(propertyValue);
              }
              else if ("ordered".equals(propertyName))
              {
                newOrdered = XSDOrdered.get(propertyValue);
              }
              break;
            }
          }
        }
      }
    }


    if (!XSDConstants.isURType(this))
    {
      if (newBounded != getBoundedFacet().isValue() /* || !getBoundedFacet().isSetValue()*/)
      {
        getBoundedFacet().setValue(newBounded);
      }
      if (newCardinality != getCardinalityFacet().getValue() /* || !getCardinalityFacet().isSetValue()*/)
      {
        getCardinalityFacet().setValue(newCardinality);
      }
      if (newNumeric != getNumericFacet().isValue() /* || !getNumericFacet().isSetValue()*/)
      {
        getNumericFacet().setValue(newNumeric);
      }
      if (newOrdered == null)
      {
        newOrdered = XSDOrdered.FALSE_LITERAL;
      }
      if (newOrdered != getOrderedFacet().getValue() /* || !getOrderedFacet().isSetValue()*/)
      {
        getOrderedFacet().setValue(newOrdered);
      }
    }

    if (newFacets == null)
    {
      if (!getFacets().isEmpty())
      {
        getFacets().clear();
      }
    }
    else
    {
      List<XSDFacet> remainingFacets = new ArrayList<XSDFacet>(getFacets());
      remainingFacets.removeAll(newFacets);
      getFacets().removeAll(remainingFacets);
      if (!newFacets.isEmpty())
      {
        setListContentAndOrder(getFacets(), newFacets);
      }
    }

    if (newValidFacets == null)
    {
      if (!getValidFacets().isEmpty())
      {
        getValidFacets().clear();
      }
    }
    else
    {
      List<String> remainingValidFacets = new ArrayList<String>(getValidFacets());
      remainingValidFacets.removeAll(newValidFacets);
      getValidFacets().removeAll(remainingValidFacets);
      if (!newValidFacets.isEmpty())
      {
        setListContentAndOrder(getValidFacets(), newValidFacets);
      }
    }
  }

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

    Element theElement = getElement();
    Element theRestrictionElement = null;
    if (theElement != null)
    {
      String anchor;
      if (getContainer() instanceof XSDComplexTypeDefinition)
      {
        checkAttributes
          (XSDConstants.PART2,
           anchor = "element-simpleContent",
           theElement,
           new String []
           {
             XSDConstants.ID_ATTRIBUTE
           });

        XSDComplexTypeDefinition xsdComplexTypeDefinition =
           (XSDComplexTypeDefinition)getSchema().getSchemaForSchema().resolveElementDeclaration("simpleContent").getTypeDefinition();

        checkComplexContent(xsdComplexTypeDefinition, XSDConstants.PART2, "element-simpleContent", theElement);
        for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
        {
          switch (XSDConstants.nodeType(child))
          {
            case XSDConstants.RESTRICTION_ELEMENT:
            {
              Element childElement = (Element)child;
              theRestrictionElement = childElement;
  
              checkAttributes
                (XSDConstants.PART2,
                 "element-simpleContent::restriction",
                 childElement,
                 new String []
                 {
                   XSDConstants.ID_ATTRIBUTE,
                   XSDConstants.BASE_ATTRIBUTE
                 });

              checkBuiltInTypeConstraint
                ("ID",
                 null,
                 XSDConstants.PART2,
                 "element-simpleContent::restriction",
                 childElement,
                 XSDConstants.ID_ATTRIBUTE,
                 false);

              checkComplexContent("simpleRestrictionType", XSDConstants.PART2, "element-simpleContent::restriction", childElement);

              // This is allowed https://bugs.eclipse.org/bugs/show_bug.cgi?id=177035
              //
              // if (childElement.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE) && !getContents().isEmpty())
              // {
              //   createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-restriction-base-or-simpleType");
              // }

              break;
            }
            case XSDConstants.EXTENSION_ELEMENT:
            {
              Element childElement = (Element)child;
  
              checkAttributes
                (XSDConstants.PART2,
                 "element-simpleContent::extension",
                 childElement,
                 new String []
                 {
                   XSDConstants.ID_ATTRIBUTE,
                   XSDConstants.BASE_ATTRIBUTE
                 });

              checkBuiltInTypeConstraint
                ("ID",
                 null,
                 XSDConstants.PART2,
                 "element-simpleContent::extension",
                 childElement,
                 XSDConstants.ID_ATTRIBUTE,
                 false);

              checkComplexContent("simpleExtensionType", XSDConstants.PART2, "element-simpleContent::extension", childElement);

              if (childElement.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE) && !getContents().isEmpty())
              {
                createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-restriction-base-or-simpleType");
              }

              break;
            }
          }
        }
      }
      else
      {
        if (getContainer() instanceof XSDFeature || getContainer() instanceof XSDSimpleTypeDefinition)
        {
          checkAttributes
            (XSDConstants.PART2,
             anchor = "element-simpleType",
             theElement,
             new String []
             {
               XSDConstants.ID_ATTRIBUTE,
             });
        }
        else
        {
          checkAttributes
            (XSDConstants.PART2,
             anchor = "element-simpleType",
             theElement,
             new String []
             {
               XSDConstants.FINAL_ATTRIBUTE,
               XSDConstants.ID_ATTRIBUTE,
               XSDConstants.NAME_ATTRIBUTE
             });

          // EATM this is an error in the spec, I believe.
          //
          if (theElement.hasAttributeNS(null, XSDConstants.FINAL_ATTRIBUTE))
          {
            String value = theElement.getAttributeNS(null, XSDConstants.FINAL_ATTRIBUTE);
            for (StringTokenizer values = new StringTokenizer(value, " "); values.hasMoreTokens(); )
            {
              String token = values.nextToken();

              checkBuiltInTypeConstraint
                ("simpleDerivationSet",
                 token,
                 XSDConstants.PART2,
                 anchor,
                 theElement,
                 XSDConstants.FINAL_ATTRIBUTE,
                 false);
            }
          }
        }

        checkComplexContent("simpleType", XSDConstants.PART2, "element-simpleType", theElement);

        for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
        {
          switch (XSDConstants.nodeType(child))
          {
            case XSDConstants.RESTRICTION_ELEMENT:
            {
              Element childElement = (Element)child;
              theRestrictionElement = childElement;
  
              checkAttributes
                (XSDConstants.PART2,
                 "element-restriction",
                 childElement,
                 new String []
                 {
                   XSDConstants.ID_ATTRIBUTE,
                   XSDConstants.BASE_ATTRIBUTE
                 });

              checkBuiltInTypeConstraint
                ("ID",
                 null,
                 XSDConstants.PART2,
                 "element-restriction",
                 childElement,
                 XSDConstants.ID_ATTRIBUTE,
                 false);

              XSDComplexTypeDefinition xsdComplexTypeDefinition =
                 (XSDComplexTypeDefinition)getSchema().getSchemaForSchema().resolveElementDeclaration("restriction").getTypeDefinition();
      
              checkComplexContent(xsdComplexTypeDefinition, XSDConstants.PART2, "element-restriction", childElement);

              if (childElement.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE)) 
              {
                if (!getContents().isEmpty())
                {
                  createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-restriction-base-or-simpleType");
                }
              }
              else if (getContents().isEmpty())
              {
                createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-restriction-base-or-simpleType.0");
              }

              break;
            }
            case XSDConstants.UNION_ELEMENT:
            {
              Element childElement = (Element)child;
  
              checkAttributes
                (XSDConstants.PART2,
                 "element-union",
                 childElement,
                 new String []
                 {
                   XSDConstants.ID_ATTRIBUTE,
                   XSDConstants.MEMBERTYPES_ATTRIBUTE
                 });

              checkBuiltInTypeConstraint
                ("ID",
                 null,
                 XSDConstants.PART2,
                 "element-union",
                 childElement,
                 XSDConstants.ID_ATTRIBUTE,
                 false);

              XSDComplexTypeDefinition xsdComplexTypeDefinition =
                 (XSDComplexTypeDefinition)getSchema().getSchemaForSchema().resolveElementDeclaration("union").getTypeDefinition();
      
              checkComplexContent(xsdComplexTypeDefinition, XSDConstants.PART2, "element-union", childElement);

              if (getMemberTypeDefinitions().isEmpty())
              {
                createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-union-memberTypes-or-simpleTypes");
              }

              break;
            }
            case XSDConstants.LIST_ELEMENT:
            {
              Element childElement = (Element)child;
  
              checkAttributes
                (XSDConstants.PART2,
                 "element-list",
                 childElement,
                 new String []
                 {
                   XSDConstants.ID_ATTRIBUTE,
                   XSDConstants.ITEMTYPE_ATTRIBUTE
                 });

              checkBuiltInTypeConstraint
                ("ID",
                 null,
                 XSDConstants.PART2,
                 "element-list",
                 childElement,
                 XSDConstants.ID_ATTRIBUTE,
                 false);

              XSDComplexTypeDefinition xsdComplexTypeDefinition =
                 (XSDComplexTypeDefinition)getSchema().getSchemaForSchema().resolveElementDeclaration("list").getTypeDefinition();
      
              checkComplexContent(xsdComplexTypeDefinition, XSDConstants.PART2, "element-list", childElement);

              if (childElement.hasAttributeNS(null, XSDConstants.ITEMTYPE_ATTRIBUTE))
              {
                if (!getContents().isEmpty())
                {
                  createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-list-itemType-or-simpleType");
                }
              }
              else
              {
                if (getContents().isEmpty())
                {
                  createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "src-list-itemType-or-simpleType.0");
                }
              }

              break;
            }
          }
        }
      }

      checkBuiltInTypeConstraint
        ("ID",
         null,
         XSDConstants.PART2,
         anchor,
         theElement,
         XSDConstants.ID_ATTRIBUTE,
         false);
    }

    if (!(getContainer() instanceof XSDFeature) && !(getContainer() instanceof XSDTypeDefinition))
    {
      checkBuiltInTypeConstraint
        ("NCName",
         getName(),
         XSDConstants.PART2,
         "element-simpleType",
         theElement,
         XSDConstants.NAME_ATTRIBUTE,
         true);
    }

    XSDSimpleTypeDefinition 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 if (isSetVariety())
    {
      switch (getVariety().getValue())
      {
        case XSDVariety.ATOMIC:
        {
          if (theBaseTypeDefinition.getFinal().contains(XSDSimpleFinal.RESTRICTION_LITERAL))
          {
            createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-st-restricts.1.2", theBaseTypeDefinition.getURI());
          }
          if (isCircular())
          {
            reportConstraintViolation
              (XSDConstants.PART2,
               "st-props-correct.2",
               getElement(),
               XSDConstants.BASE_ATTRIBUTE,
               new Object [] {});
          }
          if (!XSDConstants.isSchemaForSchemaNamespace(getTargetNamespace()) &&
                XSDConstants.isAnySimpleType(theBaseTypeDefinition) &&
                (theElement == null || 
                   theRestrictionElement != null && theRestrictionElement.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE)))
          {
            createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-st-retricts.0.0", theBaseTypeDefinition.getURI());
          }
          break;
        }
        case XSDVariety.LIST:
        {
          if (!XSDConstants.isURType(theBaseTypeDefinition))
          {
            if (theBaseTypeDefinition.getFinal().contains(XSDSimpleFinal.RESTRICTION_LITERAL))
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-st-restricts.1.2", theBaseTypeDefinition.getURI());
            }
          }
          else
          {
            XSDSimpleTypeDefinition theItemTypeDefinition = getItemTypeDefinition();
            if (theItemTypeDefinition == null)
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "_UI_UnresolvedTypeDefinition_message", "");
            }
            else if (theItemTypeDefinition.getContainer() == null)
            {
              createDiagnostic
                (XSDDiagnosticSeverity.ERROR_LITERAL, "_UI_UnresolvedTypeDefinition_message", theItemTypeDefinition.getURI());
            }
            else if (XSDVariety.ATOMIC_LITERAL != theItemTypeDefinition.getVariety() && 
                       XSDVariety.UNION_LITERAL != theItemTypeDefinition.getVariety())
            {
              reportConstraintViolation
                (XSDConstants.PART2,
                 "cos-list-of-atomic",
                 getElement(),
                 XSDConstants.ITEMTYPE_ATTRIBUTE,
                 new Object [] {});
            }
            else if (theItemTypeDefinition.getFinal().contains(XSDSimpleFinal.LIST_LITERAL))
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-st-restricts.2.0", theBaseTypeDefinition.getURI());
            }
            else if (!XSDConstants.isSchemaForSchemaNamespace(getTargetNamespace()) &&
                      XSDConstants.isAnySimpleType(theItemTypeDefinition))
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-st-retricts.0.1", theItemTypeDefinition.getURI());
            }
          }
          if (isCircular())
          {
            reportConstraintViolation
              (XSDConstants.PART2,
               "st-props-correct.2",
               getElement(),
               XSDConstants.ITEMTYPE_ATTRIBUTE,
               new Object [] {});
          }
          break;
        }
        case XSDVariety.UNION:
        {
          if (!XSDConstants.isURType(theBaseTypeDefinition))
          {
            if (theBaseTypeDefinition.getFinal().contains(XSDSimpleFinal.RESTRICTION_LITERAL))
            {
              createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-st-restricts.1.2", theBaseTypeDefinition.getURI());
            }
          }
          else
          {
            for (XSDSimpleTypeDefinition theMemberTypeDefinition : getMemberTypeDefinitions())
            {
              if (theMemberTypeDefinition == null)
              {
                createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "_UI_UnresolvedTypeDefinition_message", "");
              }
              else if (theMemberTypeDefinition.getContainer() == null)
              {
                createDiagnostic
                  (XSDDiagnosticSeverity.ERROR_LITERAL, "_UI_UnresolvedTypeDefinition_message", theMemberTypeDefinition.getURI());
              }
              else if (theMemberTypeDefinition.getFinal().contains(XSDSimpleFinal.UNION_LITERAL))
              {
                createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-st-restricts.3.0", theBaseTypeDefinition.getURI());
              }
              // Apparently this is allowed now.
              // else if (!XSDConstants.isSchemaForSchemaNamespace(getTargetNamespace()) &&
              //           XSDConstants.isAnySimpleType(theMemberTypeDefinition))
              // {
              //   createDiagnostic(XSDDiagnosticSeverity.ERROR_LITERAL, "cos-st-retricts.0.2", theMemberTypeDefinition.getURI());
              // }
            }
          }
          if (isCircular())
          {
            reportConstraintViolation
              (XSDConstants.PART2,
               "cos-no-circular-unions",
               getElement(),
               XSDConstants.MEMBERTYPES_ATTRIBUTE,
               new Object [] {});
          }
          break;
        }
      }
    }
    else if (isCircular())
    {
      reportConstraintViolation
        (XSDConstants.PART2,
         "st-props-correct.2",
         getElement(),
         XSDConstants.BASE_ATTRIBUTE,
         new Object [] {});
    }
  }

  @Override
  protected void reconcileAttributes(Element changedElement)
  {
    switch (XSDConstants.nodeType(changedElement))
    {
      case XSDConstants.EXTENSION_ELEMENT:
      case XSDConstants.RESTRICTION_ELEMENT:
      {
        if (!(getContainer() instanceof XSDComplexTypeDefinition))
        {
          XSDSimpleTypeDefinition newBaseTypeDefinition = null;
          if (changedElement.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE))
          {
            newBaseTypeDefinition =
              resolveSimpleTypeDefinitionURI(XSDConstants.lookupQNameForAttribute(changedElement, XSDConstants.BASE_ATTRIBUTE));
          }
          else if (getContents().contains(getBaseTypeDefinition()))
          {
            newBaseTypeDefinition = getBaseTypeDefinition();
          }

          handleNewBaseTypeDefinition(newBaseTypeDefinition);
        }
        else
        {
          XSDTypeDefinition newBaseTypeDefinition = null;
          if (changedElement.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE))
          {
            newBaseTypeDefinition =
              resolveTypeDefinitionURI(XSDConstants.lookupQNameForAttribute(changedElement, XSDConstants.BASE_ATTRIBUTE));
          }
          else if (getContents().contains(getBaseTypeDefinition()))
          {
            newBaseTypeDefinition = getBaseTypeDefinition();
          }

          handleNewComplexBaseTypeDefinition(newBaseTypeDefinition);
        }

        break;
      }
      case XSDConstants.LIST_ELEMENT:
      {
        XSDSimpleTypeDefinition newItemTypeDefinition = getItemTypeDefinition();
        if (changedElement.hasAttributeNS(null, XSDConstants.ITEMTYPE_ATTRIBUTE))
        {
          newItemTypeDefinition =
            resolveSimpleTypeDefinitionURI(XSDConstants.lookupQNameForAttribute(changedElement, XSDConstants.ITEMTYPE_ATTRIBUTE));
        }
        else if (!getContents().contains(newItemTypeDefinition))
        {
          newItemTypeDefinition = resolveSimpleTypeDefinition(null, "undefined");
        }

        if (newItemTypeDefinition != getItemTypeDefinition())
        {
          setItemTypeDefinition(newItemTypeDefinition);
        }

        handleNewBaseTypeDefinition(null);
        break;
      }
      case XSDConstants.UNION_ELEMENT:
      {
        List<XSDSimpleTypeDefinition> newMemberTypeDefinitions = new ArrayList<XSDSimpleTypeDefinition>();
        if (changedElement.hasAttributeNS(null, XSDConstants.MEMBERTYPES_ATTRIBUTE))
        {
          String memberTypes = changedElement.getAttributeNS(null, XSDConstants.MEMBERTYPES_ATTRIBUTE);
          if (memberTypes != null)
          {
            for (StringTokenizer tokens = new StringTokenizer(memberTypes, " "); tokens.hasMoreTokens(); )
            {
              String memberTypeQName = tokens.nextToken();
              XSDSimpleTypeDefinition newMemberTypeDefinition =
                resolveSimpleTypeDefinitionURI(XSDConstants.lookupQName(changedElement, memberTypeQName));
              newMemberTypeDefinitions.add(newMemberTypeDefinition);
            }
          }
        }

        newMemberTypeDefinitions.addAll(getContents());

        List<XSDSimpleTypeDefinition> remainingMemberTypeDefinitions = new ArrayList<XSDSimpleTypeDefinition>(getMemberTypeDefinitions());
        remainingMemberTypeDefinitions.removeAll(newMemberTypeDefinitions);
        getMemberTypeDefinitions().removeAll(remainingMemberTypeDefinitions);
        if (!newMemberTypeDefinitions.isEmpty())
        {
          setListContentAndOrder(getMemberTypeDefinitions(), newMemberTypeDefinitions);
        }

        handleNewBaseTypeDefinition(null);
        break;
      }
      case XSDConstants.SIMPLETYPE_ELEMENT:
      case XSDConstants.SIMPLECONTENT_ELEMENT:
      {
        super.reconcileAttributes(changedElement);

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

        for (Node child = changedElement.getFirstChild(); child != null; child = child.getNextSibling())
        {
          if (child.getNodeType() == Node.ELEMENT_NODE)
          {
            reconcileAttributes((Element)child);
          }
        }
        break;
      }
    }
  }

  protected void handleNewComplexBaseTypeDefinition(XSDTypeDefinition newComplexBaseTypeDefinition)
  {
    if (getContainer() instanceof XSDComplexTypeDefinition)
    {
      XSDComplexTypeDefinitionImpl xsdComplexTypeDefinition = (XSDComplexTypeDefinitionImpl)getContainer();
      boolean oldIsReconciling = xsdComplexTypeDefinition.isReconciling;
      xsdComplexTypeDefinition.isReconciling = isReconciling;
      xsdComplexTypeDefinition.handleNewBaseTypeDefinition(newComplexBaseTypeDefinition);
      xsdComplexTypeDefinition.isReconciling = oldIsReconciling;
    }
  }

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

    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 = (XSDSimpleTypeDefinition)replacement;
          }
        }
      }
    }

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

    return newBaseTypeDefinition;
  }

  @Override
  protected Node getAdoptionParentNode(EReference eReference)
  {
    if (eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS ||
          eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS ||
          eReference == XSDPackage.Literals.XSD_TYPE_DEFINITION__DERIVATION_ANNOTATION) 
    {
      Element element = getElement();
      if (element == null)
      {
        return null;
      }
      else
      {
        for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling())
        {
          switch (XSDConstants.nodeType(child))
          {
            case XSDConstants.EXTENSION_ELEMENT:
            case XSDConstants.RESTRICTION_ELEMENT:
            case XSDConstants.LIST_ELEMENT:
            case XSDConstants.UNION_ELEMENT:
            {
              return child;
            }
          }
        }
      }
    }

    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.ANNOTATION_ELEMENT:
        {
          result.add((Element)child);
          break;
        }
        case XSDConstants.EXTENSION_ELEMENT:
        case XSDConstants.RESTRICTION_ELEMENT:
        case XSDConstants.LIST_ELEMENT:
        case XSDConstants.UNION_ELEMENT:
        {
          for (Node grandChild = child.getFirstChild(); grandChild != null; grandChild = grandChild.getNextSibling())
          {
            if (grandChild.getNodeType() == Node.ELEMENT_NODE)
            {
              result.add((Element)grandChild);
            }
          }
          break;
        }
      }
    }
    return result;
  }

  @Override
  protected void handleUnreconciledElement(Element child, List<XSDConcreteComponent> newContents, List<XSDConcreteComponent> remainingContents)
  {
    switch (XSDConstants.nodeType(child))
    {
      case XSDConstants.ANNOTATION_ELEMENT:
      {
        XSDAnnotation xsdAnnotation = XSDAnnotationImpl.createAnnotation(child);
        newContents.add(xsdAnnotation);
        break;
      }
      case XSDConstants.SIMPLETYPE_ELEMENT:
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition = XSDSimpleTypeDefinitionImpl.createSimpleTypeDefinition(child);
        if (xsdSimpleTypeDefinition != null)
        {
          newContents.add(xsdSimpleTypeDefinition);
        }
        break;
      }
      default:
      {
        XSDConstrainingFacet xsdConstrainingFacet = XSDConstrainingFacetImpl.createConstrainingFacet(child);
        if (xsdConstrainingFacet != null)
        {
          newContents.add(xsdConstrainingFacet);
        }
      }
    }
  }

  @Override
  protected void handleReconciliation(List<XSDConcreteComponent> newContents, List<XSDConcreteComponent> remainingContents)
  {
    if (!newContents.isEmpty() && newContents.get(0).getElement().getParentNode() == getElement())
    {
      handleAnnotationReconciliation(XSDPackage.Literals.XSD_TYPE_DEFINITION__ANNOTATION, newContents, remainingContents);
    }
    handleAnnotationReconciliation(XSDPackage.Literals.XSD_TYPE_DEFINITION__DERIVATION_ANNOTATION, newContents, remainingContents);

    XSDSimpleTypeDefinition newBaseTypeDefinition = null;
    XSDTypeDefinition newComplexBaseTypeDefinition = null;

    boolean didContents = false;
    Element theElement = getElement();
    LOOP:
    for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
    {
      switch (XSDConstants.nodeType(child))
      {
        case XSDConstants.LIST_ELEMENT:
        {
          Element elementChild = (Element)child;
          XSDSimpleTypeDefinition newTypeContent = null;
          XSDSimpleTypeDefinition newItemTypeDefinition = null;
          if (!newContents.isEmpty())
          {
            XSDConcreteComponent xsdConcreteComponent = newContents.get(0);
            if (xsdConcreteComponent instanceof XSDSimpleTypeDefinition)
            {
              newItemTypeDefinition = (XSDSimpleTypeDefinition)xsdConcreteComponent;
              newTypeContent = newItemTypeDefinition;
              newContents.remove(0);
            }
          }
          if (elementChild.hasAttributeNS(null, XSDConstants.ITEMTYPE_ATTRIBUTE) && newItemTypeDefinition == null)
          {
            newItemTypeDefinition = 
              resolveSimpleTypeDefinitionURI(XSDConstants.lookupQNameForAttribute((Element)child, XSDConstants.ITEMTYPE_ATTRIBUTE));
          }
          if (newItemTypeDefinition == null)
          {
            newItemTypeDefinition = resolveSimpleTypeDefinition(null, "undefined");
          }

          getContents().removeAll(remainingContents);
          if (newTypeContent != null)
          {
            getContents().add(newTypeContent);
          }

          if (newItemTypeDefinition != getItemTypeDefinition())
          {
            setItemTypeDefinition(newItemTypeDefinition);
          }
          
          didContents = true;
          break LOOP;
        }
        case XSDConstants.UNION_ELEMENT:
        {
          Element elementChild = (Element)child;
          List<XSDSimpleTypeDefinition> newMemberTypeDefinitions = new ArrayList<XSDSimpleTypeDefinition>();
          if (elementChild.hasAttributeNS(null, XSDConstants.MEMBERTYPES_ATTRIBUTE))
          {
            String memberTypes = elementChild.getAttributeNS(null, XSDConstants.MEMBERTYPES_ATTRIBUTE);
            if (memberTypes != null)
            {
              for (StringTokenizer tokens = new StringTokenizer(memberTypes, " "); tokens.hasMoreTokens(); )
              {
                String memberTypeQName = tokens.nextToken();
                XSDSimpleTypeDefinition newMemberTypeDefinition =
                  resolveSimpleTypeDefinitionURI(XSDConstants.lookupQName(elementChild, memberTypeQName));
                newMemberTypeDefinitions.add(newMemberTypeDefinition);
              }
            }
          }

          List<XSDSimpleTypeDefinition> newTypeContents = new ArrayList<XSDSimpleTypeDefinition>();
          for (ListIterator<XSDConcreteComponent> i = newContents.listIterator(); i.hasNext(); )
          {
            XSDConcreteComponent xsdConcreteComponent = i.next();
            if (xsdConcreteComponent instanceof XSDSimpleTypeDefinition)
            {
              XSDSimpleTypeDefinition xsdSimpleTypeDefinition = (XSDSimpleTypeDefinition)xsdConcreteComponent;
              newTypeContents.add(xsdSimpleTypeDefinition);
              newMemberTypeDefinitions.add(xsdSimpleTypeDefinition);
              i.remove();
            }
            else
            {
              break;
            }
          }

          getContents().removeAll(remainingContents);
          if (!newTypeContents.isEmpty())
          {
            setListContentAndOrder(getContents(), newTypeContents);
          }

          List<XSDSimpleTypeDefinition> remainingMemberTypeDefinitions = new ArrayList<XSDSimpleTypeDefinition>(getMemberTypeDefinitions());
          remainingMemberTypeDefinitions.removeAll(newMemberTypeDefinitions);
          if (!remainingMemberTypeDefinitions.isEmpty())
          {
            getMemberTypeDefinitions().removeAll(remainingMemberTypeDefinitions);
          }
          if (!newMemberTypeDefinitions.isEmpty())
          {
            setListContentAndOrder(getMemberTypeDefinitions(), newMemberTypeDefinitions);
          }

          didContents = true;
          break LOOP;
        }
        case XSDConstants.EXTENSION_ELEMENT:
        case XSDConstants.RESTRICTION_ELEMENT:
        {
          Element elementChild = (Element)child;
          if (!newContents.isEmpty())
          {
            XSDConcreteComponent xsdConcreteComponent = newContents.get(0);
            if (xsdConcreteComponent instanceof XSDSimpleTypeDefinition)
            {
              XSDSimpleTypeDefinition xsdSimpleTypeDefinition = (XSDSimpleTypeDefinition)xsdConcreteComponent;
              List<XSDSimpleTypeDefinition> theContents = getContents();
              if (theContents.size() != 1 || theContents.get(0) != xsdConcreteComponent)
              {
                if (!theContents.isEmpty())
                {
                  remainingContents.removeAll(theContents);
                  theContents.clear();
                }
                theContents.add(xsdSimpleTypeDefinition);
              }
              newBaseTypeDefinition = xsdSimpleTypeDefinition;
              newContents.remove(0);
            }
          }

          if (!(getContainer() instanceof XSDComplexTypeDefinition))
          {
            if (elementChild.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE) && newBaseTypeDefinition == null)
            {
              newBaseTypeDefinition = 
                resolveSimpleTypeDefinitionURI(XSDConstants.lookupQNameForAttribute(elementChild, XSDConstants.BASE_ATTRIBUTE));
            }
          }
          else
          {
            if (elementChild.hasAttributeNS(null, XSDConstants.BASE_ATTRIBUTE))
            {
              newComplexBaseTypeDefinition = 
                resolveTypeDefinitionURI(XSDConstants.lookupQNameForAttribute(elementChild, XSDConstants.BASE_ATTRIBUTE));
            }
          }

          didContents = true;
          break LOOP;
        }
      }
    }

    if (!didContents && !getContents().isEmpty())
    {
      getContents().clear();
    }

    if (!remainingContents.isEmpty())
    {
      getFacetContents().removeAll(remainingContents);
    }

    if (!newContents.isEmpty())
    {
      for (Iterator<?> i = newContents.iterator(); i.hasNext(); )
      {
        if (!(i.next() instanceof XSDFacet))
        {
          i.remove();
        }
      }
      @SuppressWarnings("unchecked") List<XSDConstrainingFacet> list = (List<XSDConstrainingFacet>)(List<?>)newContents;
      setListContentAndOrder(getFacetContents(), list);
    }

    handleNewBaseTypeDefinition(newBaseTypeDefinition);
    handleNewComplexBaseTypeDefinition(newComplexBaseTypeDefinition);
  }

  @Override
  protected void changeAttribute(EAttribute eAttribute)
  {
    super.changeAttribute(eAttribute);
    Element theElement = getElement();
    if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__LEXICAL_FINAL)
    {
      if (theElement != null)
      {
        niceSetAttribute
          (theElement,
           XSDConstants.FINAL_ATTRIBUTE,
           getStringLexicalFinal());
      }
      if (eAttribute != null)
      {
        traverseToRootForPatching();
      }
    }
    if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__VARIETY)
    {
      if (theElement != null && eAttribute != null) 
      {
        if (analysisState != ANALYZING) 
        {
          LOOP:
          for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
          {
            int childNodeType = XSDConstants.nodeType(child);
            switch (childNodeType)
            {
              case XSDConstants.RESTRICTION_ELEMENT:
              case XSDConstants.EXTENSION_ELEMENT:
              case XSDConstants.UNION_ELEMENT:
              case XSDConstants.LIST_ELEMENT:
              {
                if (childNodeType != getRequiredChildElementNodeType())
                {
                  Element newElement = createChildElement();
                  forceReplace(newElement, (Element)child);
                }
                break LOOP;
              }
            }
          }
          traverseToRootForAnalysis();
        }
      }
    }
  }

  @Override
  protected void changeReference(EReference eReference)
  {
    super.changeReference(eReference);
    Element theElement = getElement();
    if (theElement != null)
    {
      if (eReference == null || eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__BASE_TYPE_DEFINITION)
      {
        if (!isReconciling && eReference != null)
        {
          traverseToRootForPatching();
        }

        if (!isReconciling && !(getContainer() instanceof XSDComplexTypeDefinition))
        {
          XSDSimpleTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
          if (theBaseTypeDefinition != null && !getContents().contains(theBaseTypeDefinition))
          {
            LOOP:
            for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
            {
              switch (XSDConstants.nodeType(child))
              {
                case XSDConstants.EXTENSION_ELEMENT:
                case XSDConstants.RESTRICTION_ELEMENT:
                {
                  niceSetAttributeURIValue((Element)child, XSDConstants.BASE_ATTRIBUTE, theBaseTypeDefinition.getURI());
                  break LOOP;
                }
              }
            }
          }
        }
      }
      if (eReference == null || eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__ITEM_TYPE_DEFINITION)
      {
        if (!isReconciling && eReference != null)
        {
          traverseToRootForPatching();
        }

        XSDSimpleTypeDefinition theItemTypeDefinition = getItemTypeDefinition();
        if (!isReconciling && theItemTypeDefinition != null && !getContents().contains(theItemTypeDefinition))
        {
          LOOP:
          for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
          {
            switch (XSDConstants.nodeType(child))
            {
              case XSDConstants.LIST_ELEMENT:
              {
                niceSetAttributeURIValue((Element)child, XSDConstants.ITEMTYPE_ATTRIBUTE, theItemTypeDefinition.getURI());
                break LOOP;
              }
            }
          }
        }
      }
      if (eReference == null || eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__MEMBER_TYPE_DEFINITIONS)
      {
        if (!isReconciling && eReference != null)
        {
          traverseToRootForPatching();
        }

        if (!isReconciling)
        {
          LOOP:
          for (Node child = theElement.getFirstChild(); child != null; child = child.getNextSibling())
          {
            switch (XSDConstants.nodeType(child))
            {
              case XSDConstants.UNION_ELEMENT:
              {
                StringBuffer newMemberTypeDefinitions = null;
                for (XSDSimpleTypeDefinition theMemberTypeDefinition : getMemberTypeDefinitions())
                {
                  if (getContents().contains(theMemberTypeDefinition))
                  {
                    break;
                  }
                  if (newMemberTypeDefinitions == null)
                  {
                    newMemberTypeDefinitions = new StringBuffer();
                  }
                  else 
                  {
                    newMemberTypeDefinitions.append(' ');
                  }
                  newMemberTypeDefinitions.append(theMemberTypeDefinition.getURI());
                }
                
                niceSetAttributeURIValue
                  ((Element)child, 
                   XSDConstants.MEMBERTYPES_ATTRIBUTE, 
                   newMemberTypeDefinitions == null ? null : newMemberTypeDefinitions.toString());
                break LOOP;
              }
            }
          }
        }
      }
    }
  }

  @Override
  protected void adoptContent(EReference eReference, XSDConcreteComponent xsdConcreteComponent)
  {
    super.adoptContent(eReference, xsdConcreteComponent);
    if (eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS ||
          eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS)
    {
      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((XSDAnnotation)xsdConcreteComponent);
    }
  }

  @Override
  protected void orphanContent(EReference eReference, XSDConcreteComponent xsdConcreteComponent)
  {
    super.orphanContent(eReference, xsdConcreteComponent);
    if (eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS || 
          eReference == XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS)
    {
      traverseToRootForPatching();
    }
    else if (eReference == XSDPackage.Literals.XSD_TYPE_DEFINITION__ANNOTATION ||
               eReference == XSDPackage.Literals.XSD_TYPE_DEFINITION__DERIVATION_ANNOTATION)
    {
      getAnnotations().remove(xsdConcreteComponent);
    }
  }

  public XSDTotalDigitsFacet getTotalDigitsFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDTotalDigitsFacet)
        {
          return (XSDTotalDigitsFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDTotalDigitsFacet getEffectiveTotalDigitsFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDTotalDigitsFacet)
        {
          return (XSDTotalDigitsFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDFractionDigitsFacet getFractionDigitsFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDFractionDigitsFacet)
        {
          return (XSDFractionDigitsFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDFractionDigitsFacet getEffectiveFractionDigitsFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDFractionDigitsFacet)
        {
          return (XSDFractionDigitsFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDLengthFacet getLengthFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDLengthFacet)
        {
          return (XSDLengthFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDLengthFacet getEffectiveLengthFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDLengthFacet)
        {
          return (XSDLengthFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMaxLengthFacet getMaxLengthFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDMaxLengthFacet)
        {
          return (XSDMaxLengthFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMaxLengthFacet getEffectiveMaxLengthFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDMaxLengthFacet)
        {
          return (XSDMaxLengthFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMinLengthFacet getMinLengthFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDMinLengthFacet)
        {
          return (XSDMinLengthFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMinLengthFacet getEffectiveMinLengthFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDMinLengthFacet)
        {
          return (XSDMinLengthFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMaxExclusiveFacet getMaxExclusiveFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDMaxExclusiveFacet)
        {
          return (XSDMaxExclusiveFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMaxInclusiveFacet getMaxInclusiveFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDMaxInclusiveFacet)
        {
          return (XSDMaxInclusiveFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMaxFacet getMaxFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDMaxFacet)
        {
          return (XSDMaxFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMaxFacet getEffectiveMaxFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDMaxFacet)
        {
          return (XSDMaxFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMinExclusiveFacet getMinExclusiveFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDMinExclusiveFacet)
        {
          return (XSDMinExclusiveFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMinInclusiveFacet getMinInclusiveFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDMinInclusiveFacet)
        {
          return (XSDMinInclusiveFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMinFacet getMinFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDMinFacet)
        {
          return (XSDMinFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDMinFacet getEffectiveMinFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDMinFacet)
        {
          return (XSDMinFacet)facet;
        }
      }
    }
    return null;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDFacet> getSyntheticFacets()
  {
    if (syntheticFacets == null)
    {
      syntheticFacets = new EObjectContainmentEList<XSDFacet>(XSDFacet.class, this, XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__SYNTHETIC_FACETS);
    }
    return syntheticFacets;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS:
        return ((InternalEList<?>)getContents()).basicRemove(otherEnd, msgs);
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS:
        return ((InternalEList<?>)getFacetContents()).basicRemove(otherEnd, msgs);
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FUNDAMENTAL_FACETS:
        return ((InternalEList<?>)getFundamentalFacets()).basicRemove(otherEnd, msgs);
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__SYNTHETIC_FACETS:
        return ((InternalEList<?>)getSyntheticFacets()).basicRemove(otherEnd, 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_SIMPLE_TYPE_DEFINITION__VARIETY:
        return getVariety();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FINAL:
        return getFinal();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__LEXICAL_FINAL:
        return getLexicalFinal();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VALID_FACETS:
        return getValidFacets();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS:
        return getContents();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS:
        return getFacetContents();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACETS:
        return getFacets();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MEMBER_TYPE_DEFINITIONS:
        return getMemberTypeDefinitions();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FUNDAMENTAL_FACETS:
        return getFundamentalFacets();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__BASE_TYPE_DEFINITION:
        return getBaseTypeDefinition();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__PRIMITIVE_TYPE_DEFINITION:
        return getPrimitiveTypeDefinition();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ITEM_TYPE_DEFINITION:
        return getItemTypeDefinition();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ROOT_TYPE_DEFINITION:
        return getRootTypeDefinition();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MIN_FACET:
        return getMinFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MAX_FACET:
        return getMaxFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MAX_INCLUSIVE_FACET:
        return getMaxInclusiveFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MIN_INCLUSIVE_FACET:
        return getMinInclusiveFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MIN_EXCLUSIVE_FACET:
        return getMinExclusiveFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MAX_EXCLUSIVE_FACET:
        return getMaxExclusiveFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__LENGTH_FACET:
        return getLengthFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__WHITE_SPACE_FACET:
        return getWhiteSpaceFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ENUMERATION_FACETS:
        return getEnumerationFacets();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__PATTERN_FACETS:
        return getPatternFacets();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__CARDINALITY_FACET:
        return getCardinalityFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__NUMERIC_FACET:
        return getNumericFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MAX_LENGTH_FACET:
        return getMaxLengthFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MIN_LENGTH_FACET:
        return getMinLengthFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__TOTAL_DIGITS_FACET:
        return getTotalDigitsFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FRACTION_DIGITS_FACET:
        return getFractionDigitsFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ORDERED_FACET:
        return getOrderedFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__BOUNDED_FACET:
        return getBoundedFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_MAX_FACET:
        return getEffectiveMaxFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_WHITE_SPACE_FACET:
        return getEffectiveWhiteSpaceFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_MAX_LENGTH_FACET:
        return getEffectiveMaxLengthFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_FRACTION_DIGITS_FACET:
        return getEffectiveFractionDigitsFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_PATTERN_FACET:
        return getEffectivePatternFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_ENUMERATION_FACET:
        return getEffectiveEnumerationFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_TOTAL_DIGITS_FACET:
        return getEffectiveTotalDigitsFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_MIN_LENGTH_FACET:
        return getEffectiveMinLengthFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_LENGTH_FACET:
        return getEffectiveLengthFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_MIN_FACET:
        return getEffectiveMinFacet();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__SYNTHETIC_FACETS:
        return getSyntheticFacets();
    }
    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_SIMPLE_TYPE_DEFINITION__VARIETY:
        setVariety((XSDVariety)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FINAL:
        getFinal().clear();
        getFinal().addAll((Collection<? extends XSDSimpleFinal>)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__LEXICAL_FINAL:
        getLexicalFinal().clear();
        getLexicalFinal().addAll((Collection<? extends XSDSimpleFinal>)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VALID_FACETS:
        getValidFacets().clear();
        getValidFacets().addAll((Collection<? extends String>)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS:
        getContents().clear();
        getContents().addAll((Collection<? extends XSDSimpleTypeDefinition>)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS:
        getFacetContents().clear();
        getFacetContents().addAll((Collection<? extends XSDConstrainingFacet>)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACETS:
        getFacets().clear();
        getFacets().addAll((Collection<? extends XSDConstrainingFacet>)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MEMBER_TYPE_DEFINITIONS:
        getMemberTypeDefinitions().clear();
        getMemberTypeDefinitions().addAll((Collection<? extends XSDSimpleTypeDefinition>)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FUNDAMENTAL_FACETS:
        getFundamentalFacets().clear();
        getFundamentalFacets().addAll((Collection<? extends XSDFundamentalFacet>)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__BASE_TYPE_DEFINITION:
        setBaseTypeDefinition((XSDSimpleTypeDefinition)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__PRIMITIVE_TYPE_DEFINITION:
        setPrimitiveTypeDefinition((XSDSimpleTypeDefinition)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ITEM_TYPE_DEFINITION:
        setItemTypeDefinition((XSDSimpleTypeDefinition)newValue);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__SYNTHETIC_FACETS:
        getSyntheticFacets().clear();
        getSyntheticFacets().addAll((Collection<? extends XSDFacet>)newValue);
        return;
    }
    super.eSet(featureID, newValue);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public void eUnset(int featureID)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VARIETY:
        unsetVariety();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FINAL:
        getFinal().clear();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__LEXICAL_FINAL:
        unsetLexicalFinal();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VALID_FACETS:
        getValidFacets().clear();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS:
        getContents().clear();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS:
        getFacetContents().clear();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACETS:
        getFacets().clear();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MEMBER_TYPE_DEFINITIONS:
        getMemberTypeDefinitions().clear();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FUNDAMENTAL_FACETS:
        getFundamentalFacets().clear();
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__BASE_TYPE_DEFINITION:
        setBaseTypeDefinition((XSDSimpleTypeDefinition)null);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__PRIMITIVE_TYPE_DEFINITION:
        setPrimitiveTypeDefinition((XSDSimpleTypeDefinition)null);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ITEM_TYPE_DEFINITION:
        setItemTypeDefinition((XSDSimpleTypeDefinition)null);
        return;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__SYNTHETIC_FACETS:
        getSyntheticFacets().clear();
        return;
    }
    super.eUnset(featureID);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public boolean eIsSet(int featureID)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VARIETY:
        return isSetVariety();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FINAL:
        return final_ != null && !final_.isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__LEXICAL_FINAL:
        return isSetLexicalFinal();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__VALID_FACETS:
        return validFacets != null && !validFacets.isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__CONTENTS:
        return contents != null && !contents.isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACET_CONTENTS:
        return facetContents != null && !facetContents.isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FACETS:
        return facets != null && !facets.isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MEMBER_TYPE_DEFINITIONS:
        return memberTypeDefinitions != null && !memberTypeDefinitions.isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FUNDAMENTAL_FACETS:
        return fundamentalFacets != null && !fundamentalFacets.isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__BASE_TYPE_DEFINITION:
        return baseTypeDefinition != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__PRIMITIVE_TYPE_DEFINITION:
        return primitiveTypeDefinition != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ITEM_TYPE_DEFINITION:
        return itemTypeDefinition != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ROOT_TYPE_DEFINITION:
        return getRootTypeDefinition() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MIN_FACET:
        return getMinFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MAX_FACET:
        return getMaxFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MAX_INCLUSIVE_FACET:
        return getMaxInclusiveFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MIN_INCLUSIVE_FACET:
        return getMinInclusiveFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MIN_EXCLUSIVE_FACET:
        return getMinExclusiveFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MAX_EXCLUSIVE_FACET:
        return getMaxExclusiveFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__LENGTH_FACET:
        return getLengthFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__WHITE_SPACE_FACET:
        return getWhiteSpaceFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ENUMERATION_FACETS:
        return !getEnumerationFacets().isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__PATTERN_FACETS:
        return !getPatternFacets().isEmpty();
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__CARDINALITY_FACET:
        return getCardinalityFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__NUMERIC_FACET:
        return getNumericFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MAX_LENGTH_FACET:
        return getMaxLengthFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MIN_LENGTH_FACET:
        return getMinLengthFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__TOTAL_DIGITS_FACET:
        return getTotalDigitsFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__FRACTION_DIGITS_FACET:
        return getFractionDigitsFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ORDERED_FACET:
        return getOrderedFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__BOUNDED_FACET:
        return getBoundedFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_MAX_FACET:
        return getEffectiveMaxFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_WHITE_SPACE_FACET:
        return getEffectiveWhiteSpaceFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_MAX_LENGTH_FACET:
        return getEffectiveMaxLengthFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_FRACTION_DIGITS_FACET:
        return getEffectiveFractionDigitsFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_PATTERN_FACET:
        return getEffectivePatternFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_ENUMERATION_FACET:
        return getEffectiveEnumerationFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_TOTAL_DIGITS_FACET:
        return getEffectiveTotalDigitsFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_MIN_LENGTH_FACET:
        return getEffectiveMinLengthFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_LENGTH_FACET:
        return getEffectiveLengthFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__EFFECTIVE_MIN_FACET:
        return getEffectiveMinFacet() != null;
      case XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__SYNTHETIC_FACETS:
        return syntheticFacets != null && !syntheticFacets.isEmpty();
    }
    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(" (variety: ");
    if ((eFlags & VARIETY_ESETFLAG) != 0) result.append(VARIETY_EFLAG_VALUES[(eFlags & VARIETY_EFLAG) >>> VARIETY_EFLAG_OFFSET]); else result.append("<unset>");
    result.append(", final: ");
    result.append(final_);
    result.append(", lexicalFinal: ");
    result.append(lexicalFinal);
    result.append(", validFacets: ");
    result.append(validFacets);
    result.append(')');
    return result.toString();
  }

  public XSDWhiteSpaceFacet getWhiteSpaceFacet()
  {
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDWhiteSpaceFacet)
        {
          return (XSDWhiteSpaceFacet)facet;
        }
      }
    }
    return null;
  }

  public XSDWhiteSpaceFacet getEffectiveWhiteSpaceFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDWhiteSpaceFacet)
        {
          return (XSDWhiteSpaceFacet)facet;
        }
      }
    }
    return null;
  }

  public EList<XSDEnumerationFacet> getEnumerationFacets()
  {
    EList<XSDEnumerationFacet> result = new BasicEList<XSDEnumerationFacet>();
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDEnumerationFacet)
        {
          result.add((XSDEnumerationFacet)facet);
        }
      }
    }
    return 
      new EcoreEList.UnmodifiableEList.FastCompare<XSDEnumerationFacet>
        (this, XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__ENUMERATION_FACETS, result.size(), result.toArray());
  }

  public XSDEnumerationFacet getEffectiveEnumerationFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDEnumerationFacet)
        {
          return (XSDEnumerationFacet)facet;
        }
      }
    }
    return null;
  }

  public EList<XSDPatternFacet> getPatternFacets()
  {
    EList<XSDPatternFacet> result = new BasicEList<XSDPatternFacet>();
    if (facetContents != null)
    {
      Object [] facets = facetContents.data();
      for (int i = 0, size = facetContents.size(); i < size; ++i)
      {
        Object facet = facets[i];
        if (facet instanceof XSDPatternFacet)
        {
          result.add((XSDPatternFacet)facet);
        }
      }
    }
    return 
      new EcoreEList.UnmodifiableEList.FastCompare<XSDPatternFacet>
        (this, XSDPackage.Literals.XSD_SIMPLE_TYPE_DEFINITION__PATTERN_FACETS, result.size(), result.toArray());
  }

  public XSDPatternFacet getEffectivePatternFacet()
  {
    if (facets != null)
    {
      Object [] facetData = facets.data();
      for (int i = 0, size = facets.size(); i < size; ++i)
      {
        Object facet = facetData[i];
        if (facet instanceof XSDPatternFacet)
        {
          return (XSDPatternFacet)facet;
        }
      }
    }
    return null;
  }

  protected XSDBoundedFacet boundedFacet;
  public XSDBoundedFacet getBoundedFacet()
  {
    if (boundedFacet == null)
    {
      createFundamentalFacets();
    }
    return boundedFacet;
  }

  protected XSDCardinalityFacet cardinalityFacet;
  public XSDCardinalityFacet getCardinalityFacet()
  {
    if (cardinalityFacet == null)
    {
      createFundamentalFacets();
    }
    return cardinalityFacet;
  }

  protected XSDNumericFacet numericFacet;
  public XSDNumericFacet getNumericFacet()
  {
    if (numericFacet == null)
    {
      createFundamentalFacets();
    }
    return numericFacet;
  }

  protected XSDOrderedFacet orderedFacet;
  public XSDOrderedFacet getOrderedFacet()
  {
    if (orderedFacet == null)
    {
      createFundamentalFacets();
    }
    return orderedFacet;
  }

  protected void createFundamentalFacets()
  {
    List<XSDFundamentalFacet> theFundamentalFacets = getFundamentalFacets();
    boundedFacet = getXSDFactory().createXSDBoundedFacet();
    cardinalityFacet = getXSDFactory().createXSDCardinalityFacet();
    numericFacet = getXSDFactory().createXSDNumericFacet();
    orderedFacet = getXSDFactory().createXSDOrderedFacet();
    List<XSDFundamentalFacet> list = new ArrayList<XSDFundamentalFacet>(4);
    list.add(boundedFacet);
    list.add(cardinalityFacet);
    list.add(numericFacet);
    list.add(orderedFacet);
    theFundamentalFacets.addAll(list);
  }

  protected static EList<String> validFacetsForList;
  public EList<String> getValidFacetsForList()
  {
    if (validFacetsForList == null)
    {
      validFacetsForList = new BasicEList<String>();
      validFacetsForList.add("length");
      validFacetsForList.add("maxLength");
      validFacetsForList.add("minLength");
      validFacetsForList.add("whiteSpace");
      validFacetsForList.add("enumeration");
      validFacetsForList.add("pattern");
    }
    return validFacetsForList;
  }

  protected static EList<String> validFacetsForUnion;
  public EList<String> getValidFacetsForUnion()
  {
    if (validFacetsForUnion == null)
    {
      validFacetsForUnion = new BasicEList<String>();
      validFacetsForUnion.add("enumeration");
      validFacetsForUnion.add("pattern");
    }
    return validFacetsForUnion;
  }

  @Override
  public XSDTypeDefinition getBaseType()
  {
    XSDTypeDefinition result = getBaseTypeDefinition();
    if (result == this && XSDConstants.isAnyType(this))
    {
      XSDSchema xsdSchema = getSchema();
      if (xsdSchema != null)
      {
        String schemaForSchemaNamespace = xsdSchema.getSchemaForSchemaNamespace();
        XSDSchemaImpl.getSchemaForSchema(schemaForSchemaNamespace).resolveComplexTypeDefinition("anyType");
      }
    }
    return result;
  }

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

  public XSDSimpleTypeDefinition getRootTypeDefinition()
  {
    XSDSimpleTypeDefinition result = this;
    if (!isCircular())
    {
      for (XSDSimpleTypeDefinition theBaseTypeDefinition = result.getBaseTypeDefinition();
           theBaseTypeDefinition != null && !XSDConstants.isURType(theBaseTypeDefinition); 
           theBaseTypeDefinition = theBaseTypeDefinition.getBaseTypeDefinition())
      {
        result = theBaseTypeDefinition;
      }
    }
    return result;
  }

  @Override
  public XSDSimpleTypeDefinition getSimpleType()
  {
    return this;
  }

  @Override
  public XSDParticle getComplexType()
  {
    return null;
  }

  protected XSDEnumerationFacetImpl effectiveEnumerationFacet;
  protected XSDPatternFacetImpl effectivePatternFacet;

  protected List<XSDConstrainingFacet> mergeFacets()
  {
    List<XSDConstrainingFacet> result = new ArrayList<XSDConstrainingFacet>();

    XSDSimpleTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();

    XSDWhiteSpaceFacet xsdWhiteSpaceFacet = getWhiteSpaceFacet();
    if (xsdWhiteSpaceFacet == null)
    {
      xsdWhiteSpaceFacet = theBaseTypeDefinition.getEffectiveWhiteSpaceFacet();
    }
    if (xsdWhiteSpaceFacet != null)
    {
      result.add(xsdWhiteSpaceFacet);
    }

    XSDTotalDigitsFacet xsdTotalDigitsFacet = getTotalDigitsFacet();
    if (xsdTotalDigitsFacet == null)
    {
      xsdTotalDigitsFacet = theBaseTypeDefinition.getEffectiveTotalDigitsFacet();
    }
    if (xsdTotalDigitsFacet != null)
    {
      result.add(xsdTotalDigitsFacet);
    }

    XSDFractionDigitsFacet xsdFractionDigitsFacet = getFractionDigitsFacet();
    if (xsdFractionDigitsFacet == null)
    {
      xsdFractionDigitsFacet = theBaseTypeDefinition.getEffectiveFractionDigitsFacet();
    }
    if (xsdFractionDigitsFacet != null)
    {
      result.add(xsdFractionDigitsFacet);
    }

    XSDLengthFacet xsdLengthFacet = getLengthFacet();
    if (xsdLengthFacet == null)
    {
      xsdLengthFacet = theBaseTypeDefinition.getEffectiveLengthFacet();
    }
    if (xsdLengthFacet != null)
    {
      result.add(xsdLengthFacet);
    }

    XSDMinLengthFacet xsdMinLengthFacet = getMinLengthFacet();
    if (xsdMinLengthFacet == null)
    {
      xsdMinLengthFacet = theBaseTypeDefinition.getEffectiveMinLengthFacet();
    }
    if (xsdMinLengthFacet != null)
    {
      result.add(xsdMinLengthFacet);
    }

    XSDMaxLengthFacet xsdMaxLengthFacet = getMaxLengthFacet();
    if (xsdMaxLengthFacet == null)
    {
      xsdMaxLengthFacet = theBaseTypeDefinition.getEffectiveMaxLengthFacet();
    }
    if (xsdMaxLengthFacet != null)
    {
      result.add(xsdMaxLengthFacet);
    }

    XSDConstrainingFacet maxFacet = getMaxFacet();
    if (maxFacet == null)
    {
      maxFacet = theBaseTypeDefinition.getEffectiveMaxFacet();
    }
    if (maxFacet != null)
    {
      result.add(maxFacet);
    }

    XSDConstrainingFacet minFacet = getMinFacet();
    if (minFacet == null)
    {
      minFacet = theBaseTypeDefinition.getEffectiveMinFacet();
    }
    if (minFacet != null)
    {
      result.add(minFacet);
    }

    List<XSDEnumerationFacet> enumerationFacets = getEnumerationFacets();
    if (enumerationFacets.isEmpty())
    {
      XSDEnumerationFacet baseEnumerationFacet = theBaseTypeDefinition.getEffectiveEnumerationFacet();
      if (baseEnumerationFacet != null)
      {
        result.add(baseEnumerationFacet);
      }
    }
    else
    {
      if (effectiveEnumerationFacet == null)
      {
        effectiveEnumerationFacet = (XSDEnumerationFacetImpl)getXSDFactory().createXSDEnumerationFacet();
        getSyntheticFacets().add(effectiveEnumerationFacet);
      }

      StringBuffer newLexicalValue = new StringBuffer();
      List<Object> newValue = new UniqueEList<Object>();
      List<XSDAnnotation> newAnnotations = new ArrayList<XSDAnnotation>();

      for (XSDEnumerationFacet enumerationFacet : enumerationFacets)
      {
        XSDAnnotation xsdAnnotation = enumerationFacet.getAnnotation();
        if (xsdAnnotation != null)
        {
          newAnnotations.add(xsdAnnotation);
        }

        if (newValue.addAll(enumerationFacet.getValue()))
        {
          if (newLexicalValue.length() != 0)
          {
            newLexicalValue.append(", ");
          }
          newLexicalValue.append(enumerationFacet.getLexicalValue());
        }
      }
      String newLexicalValueString = newLexicalValue.toString();

      List<Object> remainingValues = new ArrayList<Object>(effectiveEnumerationFacet.getValue());
      remainingValues.removeAll(newValue);
      if (!remainingValues.isEmpty())
      {
        effectiveEnumerationFacet.getValue().removeAll(remainingValues);
      }
      if (!newValue.isEmpty())
      {
        setListContentAndOrder(effectiveEnumerationFacet.getValue(), newValue);
      }

      List<XSDAnnotation> remainingAnnotations = new ArrayList<XSDAnnotation>(effectiveEnumerationFacet.getAnnotations());
      remainingAnnotations.removeAll(newAnnotations);
      if (!remainingAnnotations.isEmpty())
      {
        effectiveEnumerationFacet.getAnnotations().removeAll(remainingAnnotations);
      }
      if (!newAnnotations.isEmpty())
      {
        setListContentAndOrder(effectiveEnumerationFacet.getAnnotations(), newAnnotations);
      }

      if (!newLexicalValueString.equals(effectiveEnumerationFacet.getLexicalValue()))
      {
        effectiveEnumerationFacet.isReconciling = true;
        effectiveEnumerationFacet.setLexicalValue(newLexicalValueString);
        effectiveEnumerationFacet.isReconciling = false;
      }

      result.add(effectiveEnumerationFacet);
    }

    List<XSDPatternFacet> patternFacets = getPatternFacets();
    if (patternFacets.isEmpty())
    {
      XSDPatternFacet basePatternFacet = theBaseTypeDefinition.getEffectivePatternFacet();
      if (basePatternFacet != null)
      {
        result.add(basePatternFacet);
      }
    }
    else
    {
      if (effectivePatternFacet == null)
      {
        effectivePatternFacet = (XSDPatternFacetImpl)getXSDFactory().createXSDPatternFacet();
        getSyntheticFacets().add(effectivePatternFacet);
      }

      List<String> newValue = new ArrayList<String>();
      List<XSDAnnotation> newAnnotations = new ArrayList<XSDAnnotation>();
      XSDPatternFacet effectiveBasePatternFacet = theBaseTypeDefinition.getEffectivePatternFacet();
      if (effectiveBasePatternFacet != null)
      {
        newValue.addAll(effectiveBasePatternFacet.getValue());
      }

      StringBuffer combinedPattern = new StringBuffer();
      if (patternFacets.size() == 1)
      {
        XSDPatternFacet xsdPatternFacet = patternFacets.get(0);
        combinedPattern.append(xsdPatternFacet.getLexicalValue());
        XSDAnnotation xsdAnnotation = xsdPatternFacet.getAnnotation();
        if (xsdAnnotation != null)
        {
          newAnnotations.add(xsdAnnotation);
        }
      }
      else
      {
        for (XSDPatternFacet xsdPatternFacet : patternFacets)
        {
          if (combinedPattern.length() != 0)
          {
            combinedPattern.append("|");
          }
          combinedPattern.append("(");
          combinedPattern.append(xsdPatternFacet.getLexicalValue());
          combinedPattern.append(")");
          XSDAnnotation xsdAnnotation = xsdPatternFacet.getAnnotation();
          if (xsdAnnotation != null)
          {
            newAnnotations.add(xsdAnnotation);
          }
        }
      }
      newValue.add(combinedPattern.toString());

      List<String> remainingValues = new ArrayList<String>(effectivePatternFacet.getValue());
      remainingValues.removeAll(newValue);
      if (!remainingValues.isEmpty())
      {
        effectivePatternFacet.getValue().removeAll(remainingValues);
      }
      if (!newValue.isEmpty())
      {
        setListContentAndOrder(effectivePatternFacet.getValue(), newValue);
      }

      List<XSDAnnotation> remainingAnnotations = new ArrayList<XSDAnnotation>(effectivePatternFacet.getAnnotations());
      remainingAnnotations.removeAll(newAnnotations);
      if (!remainingAnnotations.isEmpty())
      {
        effectivePatternFacet.getAnnotations().removeAll(remainingAnnotations);
      }
      if (!newAnnotations.isEmpty())
      {
        setListContentAndOrder(effectivePatternFacet.getAnnotations(), newAnnotations);
      }

      StringBuffer newLexicalValue = new StringBuffer();
      if (newValue.size() == 1)
      {
        newLexicalValue.append(newValue.get(0));
      }
      else
      {
        for (String string : newValue)
        {
          if (newLexicalValue.length() != 0)
          {
            newLexicalValue.append(" & ");
          }
          newLexicalValue.append("(");
          newLexicalValue.append(string);
          newLexicalValue.append(")");
        }
      }
      String newLexicalValueString = newLexicalValue.toString();
      if (!newLexicalValueString.equals(effectivePatternFacet.getLexicalValue()))
      {
        effectivePatternFacet.isReconciling = true;
        effectivePatternFacet.setLexicalValue(newLexicalValueString);
        effectivePatternFacet.isReconciling = false;
      }

      result.add(effectivePatternFacet);
    }

    return result;
  }


  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<XSDSimpleFinal> newLexicalFinal = new ArrayList<XSDSimpleFinal>();
      for (StringTokenizer stringTokenizer = new StringTokenizer(finalDefault); stringTokenizer.hasMoreTokens(); )
      {
        String token = stringTokenizer.nextToken();
        if (token.equals("#all"))
        {
          token = "all";
        }
        XSDSimpleFinal literal = XSDSimpleFinal.get(token);
        if (literal != null)
        {
          newLexicalFinal.add(literal);
        }
      }
      if (!newLexicalFinal.equals(getLexicalFinal()))
      {
        Collection<XSDSimpleFinal> oldContents = new ArrayList<XSDSimpleFinal>(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();
  }

  /**
   * This is used to gather selectively 
   * the information determined when assessing a literal string 
   * with respect to a {@link XSDSimpleTypeDefinition}.
   * It is intended to be very light-weight and flexible.
   *
   * You may begin assessment with a {@link #node}, which handles three cases:
   * if the node is an attribute, it's value is used to determine the literal;
   * if the node is a text node, it's value is used to determine the literal;
   * if the node is an element, it's (one and only) child text node is used to determine the literal in the preceeding case.
   * You may begin assessment with a {@link #literal} by not setting a node.
   * And you may begin assessment with a {@link #normalizedLiteral} by setting neither the node nor the literal.
   *
   * Unless additional {@link #yield} flags are set,
   * assessment will perform but one function:
   * it will set the {@link #diagnostics} to Collections.EMPTY_LIST when the literal fails to assess as valid.
   * Hence, this most-light-weight invocation will only determine validity.
   *
   * You may choose for assessment to yield additional results, 
   * i.e., the {@link #value}, the {@link #canonicalLiteral}, and the {@link #diagnostics},
   * using the flags {@link #YIELD_VALUE}, {@link #YIELD_CANONICAL_LITERAL}, {@link #YIELD_DIAGNOSTICS}.
   */
  public static class AssessmentImpl implements XSDSimpleTypeDefinition.Assessment
  { 
    public static final int YIELD_VALUE             = 0x01;
    public static final int YIELD_CANONICAL_LITERAL = 0x02;
    public static final int YIELD_DIAGNOSTICS       = 0x04;

    /**
     * This is the simple type definition doing the assessment.
     */
    public XSDSimpleTypeDefinitionImpl xsdSimpleTypeDefinition;

    /**
     * This is the simple type definition doing the assessment for an atomic type.
     */
    public XSDAnySimpleType xsdAnySimpleType;

    /**
     * This is the context in which the prefix of QNames are resolved.
     */
    public Element context;

    /**
     * This is the node whose literal is being assessed.
     */
    public Node node;

    /**
     * This is the literal that is being assessed.
     */
    public String literal;

    /**
     * This is the normalized value of the literal being assessed.
     */
    public String normalizedLiteral;

    /**
     *  This determines the results that will be yielded during assessment.
     */
    public int yield;

    /**
     * This is the value of the normalized literal in the Java representation of the value space.
     */
    public Object value;

    /**
     * This is the canonical literal representation of the literal.
     */
    public String canonicalLiteral;

    /**
     * These are the diagnostics that are collected.
     */
    public Collection<XSDDiagnostic> diagnostics;

    /**
     * This records any nested assessments that were performed.
     */
    public Collection<Assessment> assessments;

    /**
     * This creates an empty instance;
     * minimally, the node or literal would need to be set before using this.
     */
    public AssessmentImpl()
    {
      super();
    }

    /**
     * This creates an instance to assess the given node and to yield the specified results.
     */
    public AssessmentImpl(Node node, int yield)
    {
      this.yield = yield;
      this.node = node;
    }

    /**
     * This creates an instance to assess the given node and to yield the specified results.
     */
    public AssessmentImpl(Element context, Node node, int yield)
    {
      this.context = context;
      this.yield = yield;
      this.node = node;
    }

    /**
     * This creates an instance to assess the given literal and to yield the specified results.
     */
    public AssessmentImpl(String literal, int yield)
    {
      this.yield = yield;
      this.literal = literal;
    }

    /**
     * This creates an instance to assess the given literal and to yield the specified results.
     */
    public AssessmentImpl(Element context, String literal, int yield)
    {
      this.context = context;
      this.yield = yield;
      this.literal = literal;
    }

    public XSDSimpleTypeDefinition getTypeDefinition()
    {
      return xsdSimpleTypeDefinition;
    }

    public Element getContext()
    {
      return context;
    }

    public Node getNode()
    {
      return node;
    }

    public String getLiteral()
    {
      return literal;
    }

    public String getNormalizedLiteral()
    {
      return normalizedLiteral;
    }

    public Object getValue()
    {
      return value;
    }

    public String getCanonicalLiteral()
    {
      return normalizedLiteral;
    }

    public XSDSimpleTypeDefinition getMemberTypeDefinition()
    {
      return null;
    }

    public Collection<XSDDiagnostic> getLocalDiagnostics()
    {
      return diagnostics == null ? Collections.<XSDDiagnostic>emptyList() : diagnostics;
    }

    public Collection<Assessment> getAssessments()
    {
      return assessments;
    }

    public Collection<XSDDiagnostic> getDiagnostics()
    {
      Collection<XSDDiagnostic> result = new ArrayList<XSDDiagnostic>();
      getAllDiagnostics(result);
      return result;
    }

    protected void getAllDiagnostics(Collection<XSDDiagnostic> result)
    {
      if (diagnostics != null)
      {
        result.addAll(diagnostics);
      }
      if (assessments != null)
      {
        for (Assessment assessment : assessments)
        {
          ((AssessmentImpl)assessment).getAllDiagnostics(result);
        }
      }
    }

    public void format(String noun, String name)
    {
      if (diagnostics != null)
      {
        for (XSDDiagnostic xsdDiagnostic : diagnostics)
        {
          xsdDiagnostic.setMessage(MessageFormat.format(xsdDiagnostic.getMessage(), new Object [] { noun, name }));
        }
      }
      if (assessments != null)
      {
        for (Assessment assessment :  assessments)
        {
          assessment.format(noun, name);
        }
      }
    }

    public void assignDiagnostics(XSDConcreteComponent xsdConcreteComponent, Element element, String attributeName)
    {
      Collection<XSDDiagnostic> allDiagnostics = getDiagnostics();
      if (!allDiagnostics.isEmpty())
      {
        Node theNode = element;
        if (element != null && element.hasAttributeNS(null, attributeName))
        {
          theNode = element.getAttributeNodeNS(null, attributeName);
        }

        Object [] substitutions = new Object [] { XSDPlugin.INSTANCE.getString("attribute_noun"), attributeName };
        for (XSDDiagnostic xsdDiagnostic : allDiagnostics)
        {
          xsdDiagnostic.setMessage(MessageFormat.format(xsdDiagnostic.getMessage(), substitutions));
          xsdDiagnostic.getComponents().add(0, xsdConcreteComponent);
          xsdDiagnostic.setNode(theNode);
        }
      }
    }

    public void validate(XSDConstrainingFacet xsdConstrainingFacet)
    {
      if (xsdConstrainingFacet != null &&
            !(xsdConstrainingFacet instanceof XSDPatternFacet ?
                ((XSDPatternFacet)xsdConstrainingFacet).isConstraintSatisfied(normalizedLiteral) :
                xsdConstrainingFacet.isConstraintSatisfied(value)))
      {
        XSDDiagnostic result = ((XSDConcreteComponentImpl)xsdConstrainingFacet).getXSDFactory().createXSDDiagnostic();
        result.setSeverity(XSDDiagnosticSeverity.ERROR_LITERAL);
        Object [] substitutions =  createSubstitutions(5);
        substitutions[3] = xsdConstrainingFacet.getLexicalValue();
        substitutions[4] = xsdConstrainingFacet.getSimpleTypeDefinition().getURI();

        String message = populateDiagnostic(result, "cvc-" + xsdConstrainingFacet.getFacetName() + "-valid", substitutions);
        if (node == null || node.getNodeType() == Node.TEXT_NODE)
        {
          message = requote(message);
        }
        result.setMessage(XSDPlugin.INSTANCE.getString("_UI_XSDError_message", new Object [] { message}));
        result.setAnnotationURI(XSDConstants.PART2 + "#" + xsdConstrainingFacet.getFacetName());
        result.setPrimaryComponent(xsdConstrainingFacet);
        result.setNode(node);

        if (diagnostics == null)
        {
          diagnostics = new ArrayList<XSDDiagnostic>();
        }
        diagnostics.add(result);
      }
    }

    protected Object [] createSubstitutions(int length)
    {
      Object [] substitutions =  new Object [length];
      if (normalizedLiteral != null)
      {
        substitutions[0] = normalizedLiteral;
      }
      else if (literal != null)
      {
        substitutions[0] = literal;
      }
      else 
      {
        substitutions[0] = value;
      }

      if (node == null || node.getNodeType() == Node.TEXT_NODE)
      {
        substitutions[1] = "\000";
        substitutions[2] = "\001";
      }
      else if (node.getNodeType() == Node.ATTRIBUTE_NODE)
      {
        substitutions[1] =  XSDPlugin.INSTANCE.getString("attribute_noun");
        substitutions[2] = node.getLocalName();
      }
      else if (node.getNodeType() == Node.ELEMENT_NODE)
      {
        substitutions[1] =  XSDPlugin.INSTANCE.getString("element_noun");
        substitutions[2] = node.getLocalName();
      }

      return substitutions;
    }

    protected static String requote(String message)
    {
      StringBuffer stringBuffer = new StringBuffer(message);
      for (int i = stringBuffer.length() - 1;  i > 0; --i)
      {
        switch (stringBuffer.charAt(i))
        {
          case 0:
          {
            stringBuffer.replace(i, i + 1, "{0}");
            break;
          }
          case 1:
          {
            stringBuffer.replace(i, i + 1, "{1}");
            break;
          }
          case '\'':
          {
            stringBuffer.insert(i, '\'');
            break;
          }
          case '{': // }
          {
            stringBuffer.replace(i, i + 1, "'{'"); // }
            break;
          }
        }
      }
      return stringBuffer.toString();
    }

    public void reportDatatypeDiagnostic()
    {
      XSDDiagnostic result = xsdSimpleTypeDefinition.getXSDFactory().createXSDDiagnostic();
      result.setSeverity(XSDDiagnosticSeverity.ERROR_LITERAL);
      Object [] substitutions =  createSubstitutions(4);
      substitutions[3] = xsdSimpleTypeDefinition.getURI();
      XSDSimpleTypeDefinition primitiveTypeDefinition = xsdSimpleTypeDefinition.getPrimitiveTypeDefinition();
      String message = 
        populateDiagnostic
          (result,
           primitiveTypeDefinition == null ? 
             "cvc-datatype-valid.1.2.3" : 
             "cvc-datatype-valid.1.2.1", 
           substitutions);
      if (node == null || node.getNodeType() == Node.TEXT_NODE)
      {
        message = requote(message);
      }
      result.setMessage(XSDPlugin.INSTANCE.getString("_UI_XSDError_message", new Object [] { message }));
      if (primitiveTypeDefinition != null)
      {
        result.setAnnotationURI(XSDConstants.PART2 + "#" + primitiveTypeDefinition.getName());
      }
      result.setPrimaryComponent(primitiveTypeDefinition);
      result.setNode(node);

      if (diagnostics == null)
      {
        diagnostics = new ArrayList<XSDDiagnostic>();
      }
      diagnostics.add(result);
    }
  }

  public XSDSimpleTypeDefinition.Assessment assess(Node node)
  {
    return assess(null, node);
  }

  public XSDSimpleTypeDefinition.Assessment assess(Element context, Node node)
  {
    AssessmentImpl assessment = new AssessmentImpl(context, node, 0);
    return assess(assessment);
  }

  public XSDSimpleTypeDefinition.Assessment assess(String literal)
  {
    return assess(null, literal);
  }

  public XSDSimpleTypeDefinition.Assessment assess(Element context, String literal)
  {
    AssessmentImpl assessment = new AssessmentImpl(context, literal, 0);
    return assess(assessment);
  }

  public AssessmentImpl assess(AssessmentImpl assessment)
  {
    return assess(assessment, true);
  }

  public AssessmentImpl assess(AssessmentImpl assessment, boolean validate)
  {
    assessment.xsdSimpleTypeDefinition = this;

    // Determine the literal from the node.
    //
    if (assessment.literal == null && assessment.node != null)
    {
      switch (assessment.node.getNodeType())
      {
        case Node.ATTRIBUTE_NODE:
        {
          assessment.literal = assessment.node.getNodeValue();
          break;
        }
        case Node.ELEMENT_NODE:
        {
          Element element = (Element)assessment.node;
          StringBuffer text = new StringBuffer();
          for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling())
          {
            switch (child.getNodeType())
            {
              case Node.TEXT_NODE:
              case Node.CDATA_SECTION_NODE:
              {
                text.append(child.getNodeValue());
                break;
              }
            }
          }
          assessment.literal = text.toString();
          break;
        }
        case Node.TEXT_NODE:
        case Node.CDATA_SECTION_NODE:
        {
          assessment.literal = assessment.node.getNodeValue();
          break;
        }
      }
    }

    // Determine the normalized literal from the literal.
    //
    if (assessment.normalizedLiteral == null && assessment.literal != null)
    {
      assessment.normalizedLiteral = assessment.literal;
      XSDWhiteSpaceFacet effectiveWhiteSpaceFacet = getEffectiveWhiteSpaceFacet();
      if (effectiveWhiteSpaceFacet != null)
      {
        assessment.normalizedLiteral = effectiveWhiteSpaceFacet.getNormalizedLiteral(assessment.literal);
      }
    }

    if (!isCircular())
    {
      if (validate)
      {
        assessment.validate(getEffectivePatternFacet());
      }

      switch (getVariety().getValue())
      {
        case XSDVariety.ATOMIC:
        {
          XSDSimpleTypeDefinition thePrimitiveTypeDefinition = getPrimitiveTypeDefinition();
          if (thePrimitiveTypeDefinition != null)
          {
            XSDAnySimpleType xsdAnySimpleType = XSDTypeRegister.getTypeImplementer(thePrimitiveTypeDefinition.getName());
            xsdAnySimpleType.assess(assessment);
            if (validate && assessment.diagnostics == null)
            {
              assessment.validate(getEffectiveLengthFacet());
              assessment.validate(getEffectiveMinLengthFacet());
              assessment.validate(getEffectiveMaxLengthFacet());

              assessment.validate(getEffectiveTotalDigitsFacet());
              assessment.validate(getEffectiveFractionDigitsFacet());

              if (XSDOrdered.FALSE_LITERAL != getOrderedFacet().getValue())
              {
                assessment.validate(getEffectiveMinFacet());
                assessment.validate(getEffectiveMaxFacet());
              }
            }
          }
          break;
        }
        case XSDVariety.UNION:
        {
          boolean good = false;
          for (XSDSimpleTypeDefinition memberTypeDefinition : getMemberTypeDefinitions())
          {
            AssessmentImpl nestedAssessment = new AssessmentImpl(assessment.context, assessment.node, assessment.yield);
            nestedAssessment.literal = nestedAssessment.normalizedLiteral = assessment.normalizedLiteral;

            ((XSDSimpleTypeDefinitionImpl)memberTypeDefinition).assess(nestedAssessment);

            if (nestedAssessment.diagnostics == null)
            {
              if (assessment.assessments == null)
              {
                assessment.assessments = new ArrayList<Assessment>();
              }
              assessment.assessments.add(nestedAssessment);
              assessment.value = nestedAssessment.value;
              good = true;
              break;
            }
          }

          if (validate && !good)
          {
            assessment.reportDatatypeDiagnostic();
          }

          break;
        }
        case XSDVariety.LIST:
        {
          XSDSimpleTypeDefinition theItemTypeDefinition = getItemTypeDefinition();
          if (theItemTypeDefinition != null)
          {
            List<Object> list = new ArrayList<Object>();
            assessment.value = list;
            for (StringTokenizer tokens = new StringTokenizer(assessment.normalizedLiteral, " "); 
                 tokens.hasMoreTokens();  )
            {
              AssessmentImpl nestedAssessment = new AssessmentImpl(assessment.context, assessment.node, assessment.yield);
              nestedAssessment.literal = nestedAssessment.normalizedLiteral = tokens.nextToken();
              ((XSDSimpleTypeDefinitionImpl)getItemTypeDefinition()).assess(nestedAssessment, validate);
              if (nestedAssessment.value != null)
              {
                list.add(nestedAssessment.value);
              }
              if (assessment.assessments == null)
              {
                assessment.assessments = new ArrayList<Assessment>();
              }
              assessment.assessments.add(nestedAssessment);
            }

            if (validate)
            {
              assessment.validate(getEffectiveLengthFacet());
              assessment.validate(getEffectiveMinLengthFacet());
              assessment.validate(getEffectiveMaxLengthFacet());
            }
          }
          break;
        }
      }

      if (validate)
      {
        assessment.validate(getEffectiveEnumerationFacet());
      }
    }

    return assessment;
  }

  public boolean isValidLiteral(String literal)
  {
    return isValidLiteral(null, literal);
  }

  public boolean isValidLiteral(Element context, String literal)
  {
    AssessmentImpl assessment = new AssessmentImpl(context, literal, 0);
    assess(assessment);
    return assessment.diagnostics == null;
  }

  public Object getValue(String literal)
  {
    return getValue(null, literal);
    
  }

  public Object getValue(Element context, String literal)
  {
    AssessmentImpl assessment = new AssessmentImpl(context, literal, 0);
    assess(assessment, false);
    return assessment.value;
  }

  public String getCanonicalLiteral(String literal)
  {
    AssessmentImpl assessment = new AssessmentImpl(null, literal, 0);
    assess(assessment, false);
    return assessment.normalizedLiteral;
  }

  public String getNormalizedLiteral(String literal)
  {
    String result = literal;
    XSDWhiteSpaceFacet effectiveWhiteSpaceFacet = getEffectiveWhiteSpaceFacet();
    if (effectiveWhiteSpaceFacet != null)
    {
      result = effectiveWhiteSpaceFacet.getNormalizedLiteral(result);
    }
    return result;
  }

  public boolean equalValues(Object value1, Object value2)
  {
    return value1 == null ? value2 == null : value1.equals(value2);
  }

  public boolean equalLiterals(String literal1, String literal2)
  {
    return equalLiterals(null, literal1, null, literal2);
  }

  public boolean equalLiterals(Element context1, String literal1, Element context2, String literal2)
  {
    return equalValues(getValue(context1, literal1), getValue(context2, literal2));
  }

  public int compareValues(Object value1, Object value2)
  {
    if (XSDOrdered.FALSE_LITERAL != getOrderedFacet().getValue())
    {
      XSDSimpleTypeDefinition thePrimitiveTypeDefinition = getPrimitiveTypeDefinition();
      if (thePrimitiveTypeDefinition != null)
      {
        XSDAnySimpleType xsdAnySimpleType = 
          XSDTypeRegister.getTypeImplementer(thePrimitiveTypeDefinition.getName());
        return 
          value1 == null ?
             value2 == null ? 
               0 : 
               -1 :
             value2 == null ? 
               1 :
               xsdAnySimpleType.compareValues(value1, value2);
      }
    }
    return 0;
  }

  public int compareLiterals(String literal1, String literal2)
  {
    return compareLiterals(null, literal1, null, literal2);
  }

  public int compareLiterals(Element context1, String literal1, Element context2, String literal2)
  {
    return compareValues(getValue(context1, literal1), getValue(context2, literal2));
  }

  @Override
  public XSDTypeDefinition getBadTypeDerivation(XSDTypeDefinition xsdTypeDefinition, boolean extension, boolean restriction)
  {
    if (xsdTypeDefinition == this)
    {
      return null;
    }
    else if (!restriction || 
               getBaseTypeDefinition() == null || 
               getBaseTypeDefinition().getFinal().contains(XSDSimpleFinal.RESTRICTION_LITERAL))
    {
      return this;
    }
    else
    {
      XSDTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();
      XSDTypeDefinition result = theBaseTypeDefinition;
      if (theBaseTypeDefinition == xsdTypeDefinition)
      {
        return null;
      }
      else if (!XSDConstants.isURType(theBaseTypeDefinition))
      {
        result = theBaseTypeDefinition.getBadTypeDerivation(xsdTypeDefinition, extension, restriction);
        if (result == null)
        {
          return null;
        }
      }

      switch (getVariety().getValue())
      {
        case XSDVariety.LIST:
        case XSDVariety.UNION:
        {
          if (XSDConstants.isURType(xsdTypeDefinition))
          {
            return null;
          }
        }
      }

      if (xsdTypeDefinition instanceof XSDSimpleTypeDefinition)
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition = (XSDSimpleTypeDefinition)xsdTypeDefinition;
        if (xsdSimpleTypeDefinition.getVariety() == XSDVariety.UNION_LITERAL)
        {
          for (XSDSimpleTypeDefinition memberTypeDefinition : xsdSimpleTypeDefinition.getMemberTypeDefinitions())
          {
            XSDTypeDefinition memberResult = getBadTypeDerivation(memberTypeDefinition, extension, restriction);
            if (memberResult == null)
            {
              return null;
            }
          }
        }
      }
      else if (XSDConstants.isAnyType(xsdTypeDefinition))
      {
        return null;
      }

      return result;
    }
  }

  @Override
  public XSDConcreteComponent cloneConcreteComponent(boolean deep, boolean shareDOM)
  {
    XSDSimpleTypeDefinitionImpl clonedSimpleTypeDefinition =
      (XSDSimpleTypeDefinitionImpl)getXSDFactory().createXSDSimpleTypeDefinition();
    clonedSimpleTypeDefinition.isReconciling = true;

    XSDSimpleTypeDefinition theBaseTypeDefinition = getBaseTypeDefinition();

    if (getName() != null)
    {
      clonedSimpleTypeDefinition.setName(getName());
    }
    if (isSetLexicalFinal())
    {
      if (!getLexicalFinal().isEmpty())
      {
        clonedSimpleTypeDefinition.getLexicalFinal().addAll(getLexicalFinal());
      }
      else
      {
        clonedSimpleTypeDefinition.getLexicalFinal().clear();
      }
    }

    if (!(getContainer() instanceof XSDComplexTypeDefinition))
    {
      if (getItemTypeDefinition() != null && (theBaseTypeDefinition == null || XSDConstants.isURType(theBaseTypeDefinition)))
      {
        if (!getContents().contains(getItemTypeDefinition()))
        {
          XSDSimpleTypeDefinition theItemTypeDefinition = getItemTypeDefinition();
          clonedSimpleTypeDefinition.setItemTypeDefinition
            (createUnresolvedSimpleTypeDefinition
              (theItemTypeDefinition.getTargetNamespace(), theItemTypeDefinition.getName()));
        }
      }
      else if (!getMemberTypeDefinitions().isEmpty() && (theBaseTypeDefinition == null || XSDConstants.isURType(theBaseTypeDefinition)))
      {
        List<XSDSimpleTypeDefinition> unresolvedMembers = new ArrayList<XSDSimpleTypeDefinition>(getMemberTypeDefinitions().size());
        for (XSDSimpleTypeDefinition memberTypeDefinition : getMemberTypeDefinitions())
        {
          if (getContents().contains(memberTypeDefinition))
          {
            break;
          }
          else
          {
            unresolvedMembers.add
              (createUnresolvedSimpleTypeDefinition
                (memberTypeDefinition.getTargetNamespace(), memberTypeDefinition.getName()));
          }
        }
        if (!unresolvedMembers.isEmpty())
        {
          clonedSimpleTypeDefinition.getMemberTypeDefinitions().addAll(unresolvedMembers);
        }
      }
      else
      {
        if (getBaseTypeDefinition() != null && !getContents().contains(getBaseTypeDefinition()))
        {
          clonedSimpleTypeDefinition.setBaseTypeDefinition
            (createUnresolvedSimpleTypeDefinition
              (theBaseTypeDefinition.getTargetNamespace(), theBaseTypeDefinition.getName()));
        }
      }
    }

    if (deep)
    {
      if (getAnnotation() != null)
      {
        clonedSimpleTypeDefinition.setAnnotation((XSDAnnotation)getAnnotation().cloneConcreteComponent(deep, shareDOM));
      }
      if (getDerivationAnnotation() != null)
      {
        clonedSimpleTypeDefinition.setDerivationAnnotation((XSDAnnotation)getDerivationAnnotation().cloneConcreteComponent(deep, shareDOM));
      }
      if (!getContents().isEmpty())
      {
        clonedSimpleTypeDefinition.getContents().addAll(cloneConcreteComponents(getContents(), deep, shareDOM));
        if (getItemTypeDefinition() != null && (theBaseTypeDefinition == null || XSDConstants.isURType(theBaseTypeDefinition)))
        {
          clonedSimpleTypeDefinition.setItemTypeDefinition(clonedSimpleTypeDefinition.getContents().get(0));
        }
        else if (!getMemberTypeDefinitions().isEmpty() && (theBaseTypeDefinition == null || XSDConstants.isURType(theBaseTypeDefinition)))
        {
          clonedSimpleTypeDefinition.getMemberTypeDefinitions().addAll(clonedSimpleTypeDefinition.getContents());
        }
        else
        {
          clonedSimpleTypeDefinition.setBaseTypeDefinition(clonedSimpleTypeDefinition.getContents().get(0));
        }
      }
      if (!getFacetContents().isEmpty())
      {
        clonedSimpleTypeDefinition.getFacetContents().addAll(cloneConcreteComponents(getFacetContents(), deep, shareDOM));
      }
    }

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

    clonedSimpleTypeDefinition.isReconciling = shareDOM;
    return clonedSimpleTypeDefinition;
  }
}
