/**
 * 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 v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 */
package org.eclipse.xsd.impl;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.StringTokenizer;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.MutationEvent;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.common.util.URI;
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.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeGroupDefinition;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDComponent;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDDiagnostic;
import org.eclipse.xsd.XSDDiagnosticSeverity;
import org.eclipse.xsd.XSDDisallowedSubstitutions;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDForm;
import org.eclipse.xsd.XSDIdentityConstraintDefinition;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDInclude;
import org.eclipse.xsd.XSDModelGroupDefinition;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDNotationDeclaration;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDPlugin;
import org.eclipse.xsd.XSDProhibitedSubstitutions;
import org.eclipse.xsd.XSDRedefine;
import org.eclipse.xsd.XSDRedefineContent;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaCompositor;
import org.eclipse.xsd.XSDSchemaContent;
import org.eclipse.xsd.XSDSchemaDirective;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.util.XSDConstants;
import org.eclipse.xsd.util.XSDParser;
import org.eclipse.xsd.util.XSDResourceFactoryImpl;
import org.eclipse.xsd.util.XSDResourceImpl;
import org.eclipse.xsd.util.XSDSwitch;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Schema</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getDocument <em>Document</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getSchemaLocation <em>Schema Location</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getTargetNamespace <em>Target Namespace</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getAttributeFormDefault <em>Attribute Form Default</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getElementFormDefault <em>Element Form Default</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getFinalDefault <em>Final Default</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getBlockDefault <em>Block Default</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getVersion <em>Version</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getContents <em>Contents</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getElementDeclarations <em>Element Declarations</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getAttributeDeclarations <em>Attribute Declarations</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getAttributeGroupDefinitions <em>Attribute Group Definitions</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getTypeDefinitions <em>Type Definitions</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getModelGroupDefinitions <em>Model Group Definitions</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getIdentityConstraintDefinitions <em>Identity Constraint Definitions</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getNotationDeclarations <em>Notation Declarations</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getAnnotations <em>Annotations</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getAllDiagnostics <em>All Diagnostics</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getReferencingDirectives <em>Referencing Directives</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getRootVersion <em>Root Version</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getOriginalVersion <em>Original Version</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getIncorporatedVersions <em>Incorporated Versions</em>}</li>
 *   <li>{@link org.eclipse.xsd.impl.XSDSchemaImpl#getSchemaForSchema <em>Schema For Schema</em>}</li>
 * </ul>
 *
 * @generated
 */
public class XSDSchemaImpl 
  extends XSDScopeImpl 
  implements XSDSchema
{
  /**
   * The default value of the '{@link #getDocument() <em>Document</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getDocument()
   * @generated
   * @ordered
   */
  protected static final Document DOCUMENT_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getDocument() <em>Document</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getDocument()
   * @generated
   * @ordered
   */
  protected Document document = DOCUMENT_EDEFAULT;

  /**
   * The default value of the '{@link #getSchemaLocation() <em>Schema Location</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getSchemaLocation()
   * @generated
   * @ordered
   */
  protected static final String SCHEMA_LOCATION_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getSchemaLocation() <em>Schema Location</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getSchemaLocation()
   * @generated
   * @ordered
   */
  protected String schemaLocation = SCHEMA_LOCATION_EDEFAULT;

  /**
   * The default value of the '{@link #getTargetNamespace() <em>Target Namespace</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getTargetNamespace()
   * @generated
   * @ordered
   */
  protected static final String TARGET_NAMESPACE_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getTargetNamespace() <em>Target Namespace</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getTargetNamespace()
   * @generated
   * @ordered
   */
  protected String targetNamespace = TARGET_NAMESPACE_EDEFAULT;

  /**
   * The default value of the '{@link #getAttributeFormDefault() <em>Attribute Form Default</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAttributeFormDefault()
   * @generated
   * @ordered
   */
  protected static final XSDForm ATTRIBUTE_FORM_DEFAULT_EDEFAULT = XSDForm.UNQUALIFIED_LITERAL;

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

  /**
   * The flags representing the default value of the '{@link #getAttributeFormDefault() <em>Attribute Form Default</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int ATTRIBUTE_FORM_DEFAULT_EFLAG_DEFAULT = ATTRIBUTE_FORM_DEFAULT_EDEFAULT.ordinal() << ATTRIBUTE_FORM_DEFAULT_EFLAG_OFFSET;

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

  /**
   * The flag representing the value of the '{@link #getAttributeFormDefault() <em>Attribute Form Default</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAttributeFormDefault()
   * @generated
   * @ordered
   */
  protected static final int ATTRIBUTE_FORM_DEFAULT_EFLAG = 1 << ATTRIBUTE_FORM_DEFAULT_EFLAG_OFFSET;

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

  /**
   * The default value of the '{@link #getElementFormDefault() <em>Element Form Default</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getElementFormDefault()
   * @generated
   * @ordered
   */
  protected static final XSDForm ELEMENT_FORM_DEFAULT_EDEFAULT = XSDForm.UNQUALIFIED_LITERAL;

  /**
   * The offset of the flags representing the value of the '{@link #getElementFormDefault() <em>Element Form Default</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int ELEMENT_FORM_DEFAULT_EFLAG_OFFSET = 10;

  /**
   * The flags representing the default value of the '{@link #getElementFormDefault() <em>Element Form Default</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   * @ordered
   */
  protected static final int ELEMENT_FORM_DEFAULT_EFLAG_DEFAULT = ELEMENT_FORM_DEFAULT_EDEFAULT.ordinal() << ELEMENT_FORM_DEFAULT_EFLAG_OFFSET;

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

  /**
   * The flag representing the value of the '{@link #getElementFormDefault() <em>Element Form Default</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getElementFormDefault()
   * @generated
   * @ordered
   */
  protected static final int ELEMENT_FORM_DEFAULT_EFLAG = 1 << ELEMENT_FORM_DEFAULT_EFLAG_OFFSET;

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

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

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

  /**
   * The default value of the '{@link #getVersion() <em>Version</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getVersion()
   * @generated
   * @ordered
   */
  protected static final String VERSION_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getVersion() <em>Version</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getVersion()
   * @generated
   * @ordered
   */
  protected String version = VERSION_EDEFAULT;

  /**
   * 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<XSDSchemaContent> contents;

  /**
   * The cached value of the '{@link #getElementDeclarations() <em>Element Declarations</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getElementDeclarations()
   * @generated
   * @ordered
   */
  protected EList<XSDElementDeclaration> elementDeclarations;

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

  /**
   * The cached value of the '{@link #getAttributeGroupDefinitions() <em>Attribute Group Definitions</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAttributeGroupDefinitions()
   * @generated
   * @ordered
   */
  protected EList<XSDAttributeGroupDefinition> attributeGroupDefinitions;

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

  /**
   * The cached value of the '{@link #getModelGroupDefinitions() <em>Model Group Definitions</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getModelGroupDefinitions()
   * @generated
   * @ordered
   */
  protected EList<XSDModelGroupDefinition> modelGroupDefinitions;

  /**
   * The cached value of the '{@link #getIdentityConstraintDefinitions() <em>Identity Constraint Definitions</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getIdentityConstraintDefinitions()
   * @generated
   * @ordered
   */
  protected EList<XSDIdentityConstraintDefinition> identityConstraintDefinitions;

  /**
   * The cached value of the '{@link #getNotationDeclarations() <em>Notation Declarations</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getNotationDeclarations()
   * @generated
   * @ordered
   */
  protected EList<XSDNotationDeclaration> notationDeclarations;

  /**
   * The cached value of the '{@link #getAnnotations() <em>Annotations</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAnnotations()
   * @generated
   * @ordered
   */
  protected EList<XSDAnnotation> annotations;

  /**
   * The cached value of the '{@link #getAllDiagnostics() <em>All Diagnostics</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getAllDiagnostics()
   * @generated
   * @ordered
   */
  protected EList<XSDDiagnostic> allDiagnostics;

  /**
   * The cached value of the '{@link #getReferencingDirectives() <em>Referencing Directives</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getReferencingDirectives()
   * @generated
   * @ordered
   */
  protected EList<XSDSchemaDirective> referencingDirectives;

  /**
   * The cached value of the '{@link #getIncorporatedVersions() <em>Incorporated Versions</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getIncorporatedVersions()
   * @generated
   * @ordered
   */
  protected EList<XSDSchema> incorporatedVersions;

  public static XSDSchema createSchema(Node node)
  {
    XSDSchema xsdSchema = XSDFactory.eINSTANCE.createXSDSchema();

    // if (XSDConstants.nodeType(node) == XSDConstants.SCHEMA_ELEMENT)
    {
      // Force the loading of the "meta" schema for schema instance instance.
      //
      String schemaForSchemaNamespace = node.getNamespaceURI();
      getSchemaForSchema(schemaForSchemaNamespace);

      xsdSchema.setElement((Element)node);
    }

    return xsdSchema;
  }

  public static synchronized XSDSchema createMetaSchema(Node node)
  {
    if (XSDConstants.nodeType(node) == XSDConstants.SCHEMA_ELEMENT)
    {
      XSDSchema xsdSchema = XSDFactory.eINSTANCE.createXSDSchema();

      String schemaForSchemaNamespace = node.getNamespaceURI();
      if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001.equals(schemaForSchemaNamespace))
      {
        if (xsdMagicSchemaForSchema2001 == null)
        {
          xsdMagicSchemaForSchema2001 = xsdSchema;
        }
        else if (xsdSchemaForSchema2001 == null)
        {
          xsdSchemaForSchema2001 = xsdSchema;
        }
        else
        {
          // System.out.println("Bad meta loading.");
        }
      }
      else if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_2000_10.equals(schemaForSchemaNamespace))
      {
        if (xsdMagicSchemaForSchema2000_10 == null)
        {
          xsdMagicSchemaForSchema2000_10 = xsdSchema;
        }
        else if (xsdSchemaForSchema2000_10 == null)
        {
          xsdSchemaForSchema2000_10 = xsdSchema;
        }
        else
        {
          // System.out.println("Bad meta loading.");
        }
      }
      else if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_1999.equals(schemaForSchemaNamespace))
      {
        if (xsdMagicSchemaForSchema1999 == null)
        {
          xsdMagicSchemaForSchema1999 = xsdSchema;
        }
        else if (xsdSchemaForSchema1999 == null)
        {
          xsdSchemaForSchema1999 = xsdSchema;
        }
        else
        {
          // System.out.println("Bad meta loading.");
        }
      }


      xsdSchema.setElement((Element)node);
      return xsdSchema;
    }

    return null;
  }

  protected static ResourceSet globalResourceSet;

  protected static XSDSchema xsdMagicSchemaForSchema2001;
  protected static XSDSchema xsdSchemaForSchema2001;
  protected static XSDSchema xsdSchemaInstance2001;

  protected static XSDSchema xsdMagicSchemaForSchema2000_10;
  protected static XSDSchema xsdSchemaForSchema2000_10;

  protected static XSDSchema xsdMagicSchemaForSchema1999;
  protected static XSDSchema xsdSchemaForSchema1999;

  public static synchronized ResourceSet getGlobalResourceSet()
  {
    if (globalResourceSet == null)
    {
      globalResourceSet = createResourceSet();

      String baseURL = XSDPlugin.INSTANCE.getBaseURL().toString();
      globalResourceSet.getURIConverter().getURIMap().put
        (URI.createURI("http://www.w3.org/2001/xml.xsd"), 
         URI.createURI(baseURL + "cache/www.w3.org/2001/xml.xsd"));
    }

    return globalResourceSet;
  }

  public static ResourceSet createResourceSet()
  {
    ResourceSet result = new ResourceSetImpl();
    result.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xsd", new XSDResourceFactoryImpl());
    return result;
  }

  public static synchronized XSDSchema getMagicSchemaForSchema(String namespace)
  {
    if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001.equals(namespace))
    {
      if (xsdMagicSchemaForSchema2001 == null)
      {
        try
        {
          String baseURL = XSDPlugin.INSTANCE.getBaseURL().toString();
          getGlobalResourceSet().getLoadOptions().put("XSD_MAGIC_XML_SCHEMA", XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);
          getGlobalResourceSet().getResource
            (URI.createURI(baseURL + "cache/www.w3.org/2001/MagicXMLSchema.xsd"), true);
        }
        catch (Exception exception)
        {
          exception.printStackTrace();
        }
        finally
        {
          getGlobalResourceSet().getLoadOptions().remove("XSD_MAGIC_XML_SCHEMA");
        }
      }

      return xsdMagicSchemaForSchema2001;
    }
    else if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_2000_10.equals(namespace))
    {
      if (xsdMagicSchemaForSchema2000_10 == null)
      {
        try
        {
          String baseURL = XSDPlugin.INSTANCE.getBaseURL().toString();
          getGlobalResourceSet().getLoadOptions().put("XSD_MAGIC_XML_SCHEMA", XSDConstants.SCHEMA_FOR_SCHEMA_URI_2000_10);
          getGlobalResourceSet().getResource
            (URI.createURI(baseURL + "cache/www.w3.org/2000/10/MagicXMLSchema.xsd"), true);
        }
        catch (Exception exception)
        {
          exception.printStackTrace();
        }
        finally
        {
          getGlobalResourceSet().getLoadOptions().remove("XSD_MAGIC_XML_SCHEMA");
        }
      }

      return xsdMagicSchemaForSchema2000_10;
    }
    else if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_1999.equals(namespace))
    {
      if (xsdMagicSchemaForSchema1999 == null)
      {
        try
        {
          String baseURL = XSDPlugin.INSTANCE.getBaseURL().toString();
          getGlobalResourceSet().getLoadOptions().put("XSD_MAGIC_XML_SCHEMA", XSDConstants.SCHEMA_FOR_SCHEMA_URI_1999);
          getGlobalResourceSet().getResource
            (URI.createURI(baseURL + "cache/www.w3.org/1999/MagicXMLSchema.xsd"), true);
        }
        catch (Exception exception)
        {
          exception.printStackTrace();
        }
        finally
        {
          getGlobalResourceSet().getLoadOptions().remove("XSD_MAGIC_XML_SCHEMA");
        }
      }

      return xsdMagicSchemaForSchema1999;
    }

    return null;
  }

  public static synchronized XSDSchema getSchemaForSchema(String namespace)
  {
    if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001.equals(namespace))
    {
      if (xsdSchemaForSchema2001 == null)
      {
        try
        {
          String baseURL = XSDPlugin.INSTANCE.getBaseURL().toString();
          getMagicSchemaForSchema(namespace);
          getGlobalResourceSet().getLoadOptions().put("XSD_XML_SCHEMA", XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);
          getGlobalResourceSet().getResource
            (URI.createURI(baseURL + "cache/www.w3.org/2001/XMLSchema.xsd"), true);
        }
        catch (Exception exception)
        {
          exception.printStackTrace();
        }
        finally
        {
          getGlobalResourceSet().getLoadOptions().remove("XSD_XML_SCHEMA");
        }
      }
      return xsdSchemaForSchema2001;
    }
    else if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_2000_10.equals(namespace))
    {
      if (xsdSchemaForSchema2000_10 == null)
      {
        try
        {
          String baseURL = XSDPlugin.INSTANCE.getBaseURL().toString();
          getMagicSchemaForSchema(namespace);
          getGlobalResourceSet().getLoadOptions().put("XSD_XML_SCHEMA", XSDConstants.SCHEMA_FOR_SCHEMA_URI_2000_10);
          getGlobalResourceSet().getResource
            (URI.createURI(baseURL + "cache/www.w3.org/2000/10/XMLSchema.xsd"), true);
        }
        catch (Exception exception)
        {
          exception.printStackTrace();
        }
        finally
        {
          getGlobalResourceSet().getLoadOptions().remove("XSD_XML_SCHEMA");
        }
      }
      return xsdSchemaForSchema2000_10;
    }
    else if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_1999.equals(namespace))
    {
      if (xsdSchemaForSchema1999 == null)
      {
        try
        {
          String baseURL = XSDPlugin.INSTANCE.getBaseURL().toString();
          getMagicSchemaForSchema(namespace);
          getGlobalResourceSet().getLoadOptions().put("XSD_XML_SCHEMA", XSDConstants.SCHEMA_FOR_SCHEMA_URI_1999);
          getGlobalResourceSet().getResource
            (URI.createURI(baseURL + "cache/www.w3.org/1999/XMLSchema.xsd"), true);
        }
        catch (Exception exception)
        {
          exception.printStackTrace();
        }
        finally
        {
          getGlobalResourceSet().getLoadOptions().remove("XSD_XML_SCHEMA");
        }
      }
      return xsdSchemaForSchema1999;
    }
    return null;
  }

  public static synchronized XSDSchema getSchemaInstance(String namespace)
  {
    if (XSDConstants.SCHEMA_INSTANCE_URI_2001.equals(namespace))
    {
      if (xsdSchemaInstance2001 == null)
      {
        try
        {
          String baseURL = XSDPlugin.INSTANCE.getBaseURL().toString();
          getSchemaForSchema(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);
          getGlobalResourceSet().getLoadOptions().put("XSD_SCHEMA_INSTANCE", XSDConstants.SCHEMA_INSTANCE_URI_2001);
          Resource schemaInstance2001Resource = 
            getGlobalResourceSet().getResource
              (URI.createURI(baseURL + "cache/www.w3.org/2001/XMLSchema-instance.xsd"), true);
          xsdSchemaInstance2001 = ((XSDResourceImpl)schemaInstance2001Resource).getSchema();
        }
        catch (Exception exception)
        {
          exception.printStackTrace();
        }
        finally
        {
          getGlobalResourceSet().getLoadOptions().remove("XSD_SCHEMA_INSTANCE");
        }
      }
      return xsdSchemaInstance2001;
    }
    return null;
  }

  protected Map<String, String> qNamePrefixToNamespaceMap = 
    new HashMap<String, String>()
    {
      private static final long serialVersionUID = 1L;

      @Override
      public String put(String key, String value)
      {
        if ("".equals(key))
        {
          throw new IllegalArgumentException("The default prefix should represented as null rather than as a zero length String");
        }

        if (value == null)
        {
          value = "";
        }
        String result = super.put(key, value);
        if (!isReconciling)
        {
          Element theElement = getElement();
          if (theElement != null)
          {
              String xmlnsAttribute = "xmlns";
              if (key != null)
              {
                xmlnsAttribute += ":" + key;
              }
              theElement.setAttributeNS(XSDConstants.XMLNS_URI_2000, xmlnsAttribute, value);
          }
        }
        return result;
      }

      @Override
      public String get(Object key) 
      {
        String result = super.get(key);
        return "".equals(result) ? null : result;
      }

      @Override
      public String remove(Object key) 
      {
        String result = super.remove(key);
        if (!isReconciling)
        {
          if (result != null)
          {
            if (key == null)
            {
              key = "xmlns";
            }
            Element theElement = getElement();
            if (theElement != null &&
                  theElement.hasAttributeNS(XSDConstants.XMLNS_URI_2000, (String)key))
            {
              theElement.removeAttributeNS(XSDConstants.XMLNS_URI_2000, (String)key);
            }
          }
        }
        return result;
      }
    };

  protected String schemaForSchemaQNamePrefix;

  protected boolean hasRetargetedNamespace = false;

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

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Document getDocument()
  {
    return document;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setDocument(Document newDocument)
  {
    Document oldDocument = document;
    document = newDocument;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SCHEMA__DOCUMENT, oldDocument, document));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public String getSchemaLocation()
  {
    return schemaLocation;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setSchemaLocation(String newSchemaLocation)
  {
    String oldSchemaLocation = schemaLocation;
    schemaLocation = newSchemaLocation;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SCHEMA__SCHEMA_LOCATION, oldSchemaLocation, schemaLocation));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public String getTargetNamespace()
  {
    return targetNamespace;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setTargetNamespace(String newTargetNamespace)
  {
    String oldTargetNamespace = targetNamespace;
    targetNamespace = newTargetNamespace;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SCHEMA__TARGET_NAMESPACE, oldTargetNamespace, targetNamespace));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDForm getAttributeFormDefault()
  {
    return ATTRIBUTE_FORM_DEFAULT_EFLAG_VALUES[(eFlags & ATTRIBUTE_FORM_DEFAULT_EFLAG) >>> ATTRIBUTE_FORM_DEFAULT_EFLAG_OFFSET];
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setAttributeFormDefault(XSDForm newAttributeFormDefault)
  {
    XSDForm oldAttributeFormDefault = ATTRIBUTE_FORM_DEFAULT_EFLAG_VALUES[(eFlags & ATTRIBUTE_FORM_DEFAULT_EFLAG) >>> ATTRIBUTE_FORM_DEFAULT_EFLAG_OFFSET];
    if (newAttributeFormDefault == null) newAttributeFormDefault = ATTRIBUTE_FORM_DEFAULT_EDEFAULT;
    eFlags = eFlags & ~ATTRIBUTE_FORM_DEFAULT_EFLAG | newAttributeFormDefault.ordinal() << ATTRIBUTE_FORM_DEFAULT_EFLAG_OFFSET;
    boolean oldAttributeFormDefaultESet = (eFlags & ATTRIBUTE_FORM_DEFAULT_ESETFLAG) != 0;
    eFlags |= ATTRIBUTE_FORM_DEFAULT_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SCHEMA__ATTRIBUTE_FORM_DEFAULT, oldAttributeFormDefault, newAttributeFormDefault, !oldAttributeFormDefaultESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetAttributeFormDefault()
  {
    XSDForm oldAttributeFormDefault = ATTRIBUTE_FORM_DEFAULT_EFLAG_VALUES[(eFlags & ATTRIBUTE_FORM_DEFAULT_EFLAG) >>> ATTRIBUTE_FORM_DEFAULT_EFLAG_OFFSET];
    boolean oldAttributeFormDefaultESet = (eFlags & ATTRIBUTE_FORM_DEFAULT_ESETFLAG) != 0;
    eFlags = eFlags & ~ATTRIBUTE_FORM_DEFAULT_EFLAG | ATTRIBUTE_FORM_DEFAULT_EFLAG_DEFAULT;
    eFlags &= ~ATTRIBUTE_FORM_DEFAULT_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.UNSET, XSDPackage.XSD_SCHEMA__ATTRIBUTE_FORM_DEFAULT, oldAttributeFormDefault, ATTRIBUTE_FORM_DEFAULT_EDEFAULT, oldAttributeFormDefaultESet));
  }

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public XSDForm getElementFormDefault()
  {
    return ELEMENT_FORM_DEFAULT_EFLAG_VALUES[(eFlags & ELEMENT_FORM_DEFAULT_EFLAG) >>> ELEMENT_FORM_DEFAULT_EFLAG_OFFSET];
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setElementFormDefault(XSDForm newElementFormDefault)
  {
    XSDForm oldElementFormDefault = ELEMENT_FORM_DEFAULT_EFLAG_VALUES[(eFlags & ELEMENT_FORM_DEFAULT_EFLAG) >>> ELEMENT_FORM_DEFAULT_EFLAG_OFFSET];
    if (newElementFormDefault == null) newElementFormDefault = ELEMENT_FORM_DEFAULT_EDEFAULT;
    eFlags = eFlags & ~ELEMENT_FORM_DEFAULT_EFLAG | newElementFormDefault.ordinal() << ELEMENT_FORM_DEFAULT_EFLAG_OFFSET;
    boolean oldElementFormDefaultESet = (eFlags & ELEMENT_FORM_DEFAULT_ESETFLAG) != 0;
    eFlags |= ELEMENT_FORM_DEFAULT_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SCHEMA__ELEMENT_FORM_DEFAULT, oldElementFormDefault, newElementFormDefault, !oldElementFormDefaultESet));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetElementFormDefault()
  {
    XSDForm oldElementFormDefault = ELEMENT_FORM_DEFAULT_EFLAG_VALUES[(eFlags & ELEMENT_FORM_DEFAULT_EFLAG) >>> ELEMENT_FORM_DEFAULT_EFLAG_OFFSET];
    boolean oldElementFormDefaultESet = (eFlags & ELEMENT_FORM_DEFAULT_ESETFLAG) != 0;
    eFlags = eFlags & ~ELEMENT_FORM_DEFAULT_EFLAG | ELEMENT_FORM_DEFAULT_EFLAG_DEFAULT;
    eFlags &= ~ELEMENT_FORM_DEFAULT_ESETFLAG;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.UNSET, XSDPackage.XSD_SCHEMA__ELEMENT_FORM_DEFAULT, oldElementFormDefault, ELEMENT_FORM_DEFAULT_EDEFAULT, oldElementFormDefaultESet));
  }

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

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

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

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDDisallowedSubstitutions> getBlockDefault()
  {
    if (blockDefault == null)
    {
      blockDefault = new EDataTypeUniqueEList.Unsettable<XSDDisallowedSubstitutions>(XSDDisallowedSubstitutions.class, this, XSDPackage.XSD_SCHEMA__BLOCK_DEFAULT);
    }
    return blockDefault;
  }

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

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public String getVersion()
  {
    return version;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setVersion(String newVersion)
  {
    String oldVersion = version;
    version = newVersion;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SCHEMA__VERSION, oldVersion, version));
  }

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public EList<XSDElementDeclaration> getElementDeclarations()
  {
    if (elementDeclarations == null)
    {
      elementDeclarations = new XSDNamedComponentImpl.XSDNamedComponentList<XSDElementDeclaration>(XSDElementDeclaration.class, this, XSDPackage.XSD_SCHEMA__ELEMENT_DECLARATIONS);
    }
    return elementDeclarations;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public EList<XSDAttributeDeclaration> getAttributeDeclarations()
  {
    if (attributeDeclarations == null)
    {
      attributeDeclarations = new XSDNamedComponentImpl.XSDNamedComponentList<XSDAttributeDeclaration>(XSDAttributeDeclaration.class, this, XSDPackage.XSD_SCHEMA__ATTRIBUTE_DECLARATIONS);
    }
    return attributeDeclarations;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public EList<XSDAttributeGroupDefinition> getAttributeGroupDefinitions()
  {
    if (attributeGroupDefinitions == null)
    {
      attributeGroupDefinitions = new XSDNamedComponentImpl.XSDNamedComponentList<XSDAttributeGroupDefinition>(XSDAttributeGroupDefinition.class, this, XSDPackage.XSD_SCHEMA__ATTRIBUTE_GROUP_DEFINITIONS);
    }
    return attributeGroupDefinitions;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public EList<XSDTypeDefinition> getTypeDefinitions()
  {
    if (typeDefinitions == null)
    {
      typeDefinitions = new XSDNamedComponentImpl.XSDNamedComponentList<XSDTypeDefinition>(XSDTypeDefinition.class, this, XSDPackage.XSD_SCHEMA__TYPE_DEFINITIONS);
    }
    return typeDefinitions;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public EList<XSDModelGroupDefinition> getModelGroupDefinitions()
  {
    if (modelGroupDefinitions == null)
    {
      modelGroupDefinitions = new XSDNamedComponentImpl.XSDNamedComponentList<XSDModelGroupDefinition>(XSDModelGroupDefinition.class, this, XSDPackage.XSD_SCHEMA__MODEL_GROUP_DEFINITIONS);
    }
    return modelGroupDefinitions;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public EList<XSDIdentityConstraintDefinition> getIdentityConstraintDefinitions()
  {
    if (identityConstraintDefinitions == null)
    {
      identityConstraintDefinitions = new XSDNamedComponentImpl.XSDNamedComponentList<XSDIdentityConstraintDefinition>(XSDIdentityConstraintDefinition.class, this, XSDPackage.XSD_SCHEMA__IDENTITY_CONSTRAINT_DEFINITIONS);
    }
    return identityConstraintDefinitions;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public EList<XSDNotationDeclaration> getNotationDeclarations()
  {
    if (notationDeclarations == null)
    {
      notationDeclarations = new XSDNamedComponentImpl.XSDNamedComponentList<XSDNotationDeclaration>(XSDNotationDeclaration.class, this, XSDPackage.XSD_SCHEMA__NOTATION_DECLARATIONS);
    }
    return notationDeclarations;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDAnnotation> getAnnotations()
  {
    if (annotations == null)
    {
      annotations = new EObjectEList<XSDAnnotation>(XSDAnnotation.class, this, XSDPackage.XSD_SCHEMA__ANNOTATIONS);
    }
    return annotations;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDDiagnostic> getAllDiagnostics()
  {
    if (allDiagnostics == null)
    {
      allDiagnostics = new EObjectEList<XSDDiagnostic>(XSDDiagnostic.class, this, XSDPackage.XSD_SCHEMA__ALL_DIAGNOSTICS);
    }
    return allDiagnostics;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDSchemaDirective> getReferencingDirectives()
  {
    if (referencingDirectives == null)
    {
      referencingDirectives = new EObjectEList<XSDSchemaDirective>(XSDSchemaDirective.class, this, XSDPackage.XSD_SCHEMA__REFERENCING_DIRECTIVES);
    }
    return referencingDirectives;
  }

  public boolean hasRetargetedNamespace()
  {
    return hasRetargetedNamespace;
  }

  public XSDSchema getOriginalVersion()
  {
    for (XSDSchemaDirective xsdSchemaDirective : getReferencingDirectives())
    {
      if (xsdSchemaDirective instanceof XSDSchemaCompositor)
      {
        XSDSchemaCompositor xsdSchemaCompositor = (XSDSchemaCompositor)xsdSchemaDirective;
        if (xsdSchemaCompositor.getResolvedSchema() != xsdSchemaCompositor.getIncorporatedSchema())
        {
          return xsdSchemaCompositor.getResolvedSchema();
        }
      }
    }
    return this;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<XSDSchema> getIncorporatedVersions()
  {
    if (incorporatedVersions == null)
    {
      incorporatedVersions = new EObjectContainmentEList<XSDSchema>(XSDSchema.class, this, XSDPackage.XSD_SCHEMA__INCORPORATED_VERSIONS);
    }
    return incorporatedVersions;
  }

/*
  public Set getIncorporatedVersions()
  {
    Set result = new HashSet();
    for (Iterator i = getReferencingDirectives().iterator(); i.hasNext(); )
    {
      XSDSchemaDirective xsdSchemaDirective = (XSDSchemaDirective)i.next();
      if (xsdSchemaDirective instanceof XSDSchemaCompositor)
      {
        XSDSchemaCompositor xsdSchemaCompositor = (XSDSchemaCompositor)xsdSchemaDirective;
        if (xsdSchemaCompositor.getResolvedSchema() != xsdSchemaCompositor.getIncorporatedSchema())
        {
          result.add(xsdSchemaCompositor.getIncorporatedSchema());
        }
      }
    }
    return result;
  }
*/

  public XSDSchema getRootVersion()
  {
    XSDSchema result = this;
    for (XSDSchema originalVersion = result.getOriginalVersion(); 
         result != originalVersion;
         originalVersion = result.getOriginalVersion())
    {
      result = originalVersion;
    }
    return result;
  }

  /**
   * This returns the map defined by the xmlns attributes of the underlying XML representation.
   */
  public Map<String, String> getQNamePrefixToNamespaceMap()
  {
    return qNamePrefixToNamespaceMap;
  }

  /**
   * This returns the QName prefix used to reference the schema for schema;
   * it must be a key in {@link #getQNamePrefixToNamespaceMap}.
   */
  public String getSchemaForSchemaQNamePrefix()
  {
    return schemaForSchemaQNamePrefix;
  }

  /**
   * This sets the QName prefix used to reference the schema for schema;
   * it must be a key in {@link #getQNamePrefixToNamespaceMap} that maps to a valid schema for schema namespace.
   * It can also be used to rename the prefix, one it's established.
   */
  public void setSchemaForSchemaQNamePrefix(String qNamePrefix)
  {
    String oldSchemaForSchemaQNamePrefix = schemaForSchemaQNamePrefix;
    String oldSchemaForSchemaNamespace = getSchemaForSchemaNamespace();
    this.schemaForSchemaQNamePrefix = qNamePrefix;
    String newSchemaForSchemaNamespace = getSchemaForSchemaNamespace();

    // Rename it if there was an old one but no new one.
    //
    if (XSDConstants.isSchemaForSchemaNamespace(oldSchemaForSchemaNamespace) && 
        !XSDConstants.isSchemaForSchemaNamespace(newSchemaForSchemaNamespace))
    {
      getQNamePrefixToNamespaceMap().remove(oldSchemaForSchemaQNamePrefix);
      getQNamePrefixToNamespaceMap().put(qNamePrefix, oldSchemaForSchemaNamespace);

      if (getElement() != null && XSDConstants.isSchemaForSchemaNamespace(getSchemaForSchemaNamespace()))
      {
        updatePrefix(getElement(), getSchemaForSchemaNamespace(), oldSchemaForSchemaQNamePrefix, qNamePrefix);
        updateElement();
      }
    }
  }

  /**
   * This returns (String)getQNamePrefixToNamespaceMap().get(getSchemaForSchemaQNamePrefix());
   * you can't set this directly.
   */
  public String getSchemaForSchemaNamespace()
  {
    return getQNamePrefixToNamespaceMap().get(getSchemaForSchemaQNamePrefix());
  }

  public String getStringBlockDefault()
  {
    if (isSetBlockDefault())
    {
      StringBuffer result = new StringBuffer();
      for (Object literal  : getBlockDefault())
      {
        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 setStringBlockDefault(String blockDefault)
  {
    if (blockDefault == null)
    {
      unsetBlockDefault();
    }
    else
    {
      List<XSDDisallowedSubstitutions> newBlockDefault = new ArrayList<XSDDisallowedSubstitutions>();
      for (StringTokenizer stringTokenizer = new StringTokenizer(blockDefault); stringTokenizer.hasMoreTokens(); )
      {
        String token = stringTokenizer.nextToken();
        if (token.equals("#all"))
        {
          token = "all";
        }
        XSDDisallowedSubstitutions literal = XSDDisallowedSubstitutions.get(token);
        if (literal != null)
        {
          newBlockDefault.add(literal);
        }
      }
      if (!newBlockDefault.equals(getBlockDefault()))
      {
        Collection<XSDDisallowedSubstitutions> oldContents = new ArrayList<XSDDisallowedSubstitutions>(getBlockDefault());
        oldContents.removeAll(newBlockDefault);
        getBlockDefault().removeAll(oldContents);
        setListContentAndOrder(getBlockDefault(), newBlockDefault);
      }
      else if (newBlockDefault.isEmpty() && !isSetBlockDefault())
      {
        getBlockDefault().clear();
      }
    }
  }

  public String getStringFinalDefault()
  {
    if (isSetFinalDefault())
    {
      StringBuffer result = new StringBuffer();
      for (Object literal : getFinalDefault())
      {
        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 setStringFinalDefault(String finalDefault)
  {
    if (finalDefault == null)
    {
      unsetFinalDefault();
    }
    else
    {
      List<XSDProhibitedSubstitutions> newFinalDefault = new ArrayList<XSDProhibitedSubstitutions>();
      for (StringTokenizer stringTokenizer = new StringTokenizer(finalDefault); stringTokenizer.hasMoreTokens(); )
      {
        String token = stringTokenizer.nextToken();
        if (token.equals("#all"))
        {
          token = "all";
        }
        XSDProhibitedSubstitutions literal = XSDProhibitedSubstitutions.get(token);
        if (literal != null)
        {
          newFinalDefault.add(literal);
        }
      }
      if (!newFinalDefault.equals(getFinalDefault()))
      {
        Collection<XSDProhibitedSubstitutions> oldContents = new ArrayList<XSDProhibitedSubstitutions>(getFinalDefault());
        oldContents.removeAll(newFinalDefault);
        getFinalDefault().removeAll(oldContents);
        setListContentAndOrder(getFinalDefault(), newFinalDefault);
      }
      else if (newFinalDefault.isEmpty() && !isSetFinalDefault())
      {
        getFinalDefault().clear();
      }
    }
  }

  @Override
  public Element createElement()
  {
    Element newElement = createElement(XSDConstants.SCHEMA_ELEMENT);
    setElement(newElement);
    return newElement;
  }

  @Override
  protected void traverseToRootForPatching()
  {
    if (!isReconciling && isIncrementalUpdate)
    {
      isReconciling = true;
      patch();
      isReconciling = false;
    }
  }

  protected Collection<XSDSchemaImpl> circularResolveDependencies;

  protected void computeSchemasToPatch(XSDSchema root, List<XSDSchema> schemasToPatch)
  {
    schemasToPatch.add(root);
    for (int i = 0; i < schemasToPatch.size(); ++i)
    {
      XSDSchema xsdSchema = schemasToPatch.get(i); 
      for (XSDSchemaContent content :  xsdSchema.getContents())
      {
        if (content instanceof XSDSchemaDirective)
        {
          if (content instanceof XSDSchemaCompositor)
          {
            XSDSchemaCompositor xsdSchemaCompositor = (XSDSchemaCompositor)content;
            XSDSchemaImpl xsdIncorporatedSchema =  (XSDSchemaImpl)xsdSchemaCompositor.getIncorporatedSchema();
            if (xsdIncorporatedSchema != null && !schemasToPatch.contains(xsdIncorporatedSchema))
            {
              xsdIncorporatedSchema.patchContents();
              schemasToPatch.add(xsdIncorporatedSchema);
            }
          }
        }
        else if (!(content instanceof XSDAnnotation))
        {
          break;
        }
      }
    }
  }

  @Override
  protected void patch()
  {
    circularResolveDependencies = new HashSet<XSDSchemaImpl>();
    
    if (XSDConstants.isSchemaForSchemaNamespace(getTargetNamespace()))
    {
      XSDSchema magicSchemaForSchema = getMagicSchemaForSchema(getTargetNamespace());
      if (magicSchemaForSchema != this)
      {
        XSDNamedComponentImpl.addToSortedList
          (getTypeDefinitions(), magicSchemaForSchema.getTypeDefinitions().get(0));
      }
    }
    else
    {
      Collection<XSDSchema> xsiSchemas = resolveSchema(XSDConstants.SCHEMA_INSTANCE_URI_2001);
      if (xsiSchemas.size() == 1)
      {
        XSDNamedComponentImpl.mergeToSortedList
          (getAttributeDeclarations(), 
           xsiSchemas.iterator().next().getAttributeDeclarations());
      }
    }

    for (Iterator<XSDSchemaDirective> i = getReferencingDirectives().iterator(); i.hasNext(); )
    {
      XSDSchemaDirective xsdSchemaDirective = i.next();
      if (xsdSchemaDirective.getContainer() == null ||
            xsdSchemaDirective.getResolvedSchema() != this &&
            (!(xsdSchemaDirective instanceof XSDSchemaCompositor) ||
                ((XSDSchemaCompositor)xsdSchemaDirective).getIncorporatedSchema() != this))
      {
        i.remove();
      }
    }

    super.patch();
    
    List<XSDSchema> schemasToPatch = new ArrayList<XSDSchema>();
    computeSchemasToPatch(this, schemasToPatch);
    
    if (circularResolveDependencies != null)
    {
      Collection<XSDSchemaImpl> localCircularResolveDependencies = circularResolveDependencies;
      circularResolveDependencies = null;
      for (XSDSchemaImpl circularSchema : localCircularResolveDependencies)
      {
        if (circularSchema != this)
        {
          circularSchema.patch();
        }
      }
    }

    if (schemaLocation != null)
    {
      for (int i = 0, size = schemasToPatch.size(); i < size; ++i)
      {
        XSDSchemaImpl xsdSchema = (XSDSchemaImpl)schemasToPatch.get(i); 
        xsdSchema.analyze();
      }
    }
  }
  
  protected void patchContents()
  {
    incorporatingSchemas = null;
    super.patch();
  }

  @Override
  protected void traverseToRootForAnalysis()
  {
    if (!isReconciling && isIncrementalUpdate)
    {
      isReconciling = true;
      analyze();
      isReconciling = false;
    }
  }

  @Override
  protected boolean analyze()
  {
    return super.analyze();
  }

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

    Element theElement = getElement();
    if (theElement != null)
    {
      if (XSDConstants.nodeType(element) != XSDConstants.SCHEMA_ELEMENT)
      {
        createDiagnostic
          (XSDDiagnosticSeverity.ERROR_LITERAL, 
           "content-valid.1",
           (element.getNamespaceURI() == null ? "" : element.getNamespaceURI()) + "#" + element.getLocalName(),
           XSDPlugin.INSTANCE.getString("_UI_XML_SCHEMA_name"),
           "schema");
      }
      else
      {
        if (getContainer() == null || !eContainmentFeature().isTransient())
        {
          checkAttributes
            (XSDConstants.PART1,
             "element-complexType",
             theElement,
             new String []
             {
               XSDConstants.ATTRIBUTEFORMDEFAULT_ATTRIBUTE,
               XSDConstants.BLOCKDEFAULT_ATTRIBUTE,
               XSDConstants.ELEMENTFORMDEFAULT_ATTRIBUTE,
               XSDConstants.FINALDEFAULT_ATTRIBUTE,
               XSDConstants.ID_ATTRIBUTE,
               XSDConstants.TARGETNAMESPACE_ATTRIBUTE,
               XSDConstants.VERSION_ATTRIBUTE
             });

          XSDComplexTypeDefinition xsdComplexTypeDefinition = 
            (XSDComplexTypeDefinition)getSchemaForSchema().resolveElementDeclaration("schema").getTypeDefinition();

          checkComplexContent
            (xsdComplexTypeDefinition,
             XSDConstants.PART1, 
             "element-schema", 
             theElement);

          checkAttributeTypeConstraint
            (xsdComplexTypeDefinition,
             "attributeFormDefault",
             null,
             XSDConstants.PART1,
             "element-schema",
             theElement,
             XSDConstants.ATTRIBUTEFORMDEFAULT_ATTRIBUTE,
             false);

          checkAttributeTypeConstraint
            (xsdComplexTypeDefinition,
             "blockDefault",
             null,
             XSDConstants.PART1,
             "element-schema",
             theElement,
             XSDConstants.BLOCKDEFAULT_ATTRIBUTE,
             false);

          checkAttributeTypeConstraint
            (xsdComplexTypeDefinition,
             "elementFormDefault",
             null,
             XSDConstants.PART1,
             "element-schema",
             theElement,
             XSDConstants.ELEMENTFORMDEFAULT_ATTRIBUTE,
             false);

          checkAttributeTypeConstraint
            (xsdComplexTypeDefinition,
             "finalDefault",
             null,
             XSDConstants.PART1,
             "element-schema",
             theElement,
             XSDConstants.FINALDEFAULT_ATTRIBUTE,
             false);

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

    if (getSchemaForSchema() != null)
    {
      checkBuiltInTypeConstraint
        ("anyURI",
         getTargetNamespace(),
         XSDConstants.PART1,
         "element-schema",
         theElement,
         XSDConstants.TARGETNAMESPACE_ATTRIBUTE,
         false);
  
      checkBuiltInTypeConstraint
        ("token",
         getVersion(),
         XSDConstants.PART1,
         "element-schema",
         theElement,
         XSDConstants.VERSION_ATTRIBUTE,
         false);
  
      validateNoDuplicates("attribute_noun", getAttributeDeclarations());
      validateNoDuplicates("attributeGroup_noun", getAttributeGroupDefinitions());
      validateNoDuplicates("modelGroup_noun", getModelGroupDefinitions());
      validateNoDuplicates("element_noun", getElementDeclarations());
      validateNoDuplicates("type_noun", getTypeDefinitions());
      validateNoDuplicates("identityConstraint_noun", getIdentityConstraintDefinitions());
      validateNoDuplicates("notation_noun", getNotationDeclarations());
    }
  }

  public void validateNoDuplicates(String componentNoun, EList<? extends XSDNamedComponent> xsdNamedComponents)
  {
    String name = null;
    String targetNamespace = null;


    for (XSDNamedComponent xsdNamedComponent :  xsdNamedComponents)
    {
      if (xsdNamedComponent.hasNameAndTargetNamespace(name, targetNamespace))
      {
        getDiagnosticTarget(xsdNamedComponent).createDiagnostic
          (XSDDiagnosticSeverity.ERROR_LITERAL, 
           "coss-schema.2",
           XSDPlugin.INSTANCE.getString(componentNoun),
           xsdNamedComponent.getURI());
      }

      name = xsdNamedComponent.getName();
      targetNamespace = xsdNamedComponent.getTargetNamespace();
    }
  }

  protected void updateSortedList(XSDNamedComponent xsdNamedComponent)
  {
    new XSDSwitch<Object>()
    {
      @Override
      public Object caseXSDElementDeclaration(XSDElementDeclaration xsdElementDeclaration)
      {
        if (getElementDeclarations().remove(xsdElementDeclaration))
        {
          XSDNamedComponentImpl.addToSortedList(getElementDeclarations(), xsdElementDeclaration);
        }
        return this;
      }
      @Override
      public Object caseXSDAttributeDeclaration(XSDAttributeDeclaration xsdAttributeDeclaration)
      {
        if (getAttributeDeclarations().remove(xsdAttributeDeclaration))
        {
          XSDNamedComponentImpl.addToSortedList(getAttributeDeclarations(), xsdAttributeDeclaration);
        }
        return this;
      }
      @Override
      public Object caseXSDAttributeGroupDefinition(XSDAttributeGroupDefinition xsdAttributeGroupDefinition)
      {
        if (getAttributeGroupDefinitions().remove(xsdAttributeGroupDefinition))
        {
          XSDNamedComponentImpl.addToSortedList(getAttributeGroupDefinitions(), xsdAttributeGroupDefinition);
        }
        return this;
      }
      @Override
      public Object caseXSDTypeDefinition(XSDTypeDefinition xsdTypeDefinition)
      {
        if (getTypeDefinitions().remove(xsdTypeDefinition))
        {
          XSDNamedComponentImpl.addToSortedList(getTypeDefinitions(), xsdTypeDefinition);
        }
        return this;
      }
      @Override
      public Object caseXSDModelGroupDefinition(XSDModelGroupDefinition xsdModelGroupDefinition)
      {
        if (getModelGroupDefinitions().remove(xsdModelGroupDefinition))
        {
          XSDNamedComponentImpl.addToSortedList(getModelGroupDefinitions(), xsdModelGroupDefinition);
        }
        return this;
      }
      @Override
      public Object caseXSDNotationDeclaration(XSDNotationDeclaration xsdNotationDeclaration)
      {
        if (getNotationDeclarations().remove(xsdNotationDeclaration))
        {
          XSDNamedComponentImpl.addToSortedList(getNotationDeclarations(), xsdNotationDeclaration);
        }
        return this;
      }
      @Override
      public Object caseXSDIdentityConstraintDefinition(XSDIdentityConstraintDefinition xsdIdentityConstraintDefinition)
      {
        if (getIdentityConstraintDefinitions().remove(xsdIdentityConstraintDefinition))
        {
          XSDNamedComponentImpl.addToSortedList(getIdentityConstraintDefinitions(), xsdIdentityConstraintDefinition);
        }
        return this;
      }
    }.doSwitch(xsdNamedComponent);
  }

  @Override
  protected void adoptContent(EReference eReference, XSDConcreteComponent xsdConcreteComponent)
  {
    super.adoptContent(eReference, xsdConcreteComponent);
    if (eReference == XSDPackage.Literals.XSD_SCHEMA__CONTENTS)
    {
      new XSDSwitch<Object>()
      {
        @Override
        public Object caseXSDElementDeclaration(XSDElementDeclaration xsdElementDeclaration)
        {
          XSDNamedComponentImpl.addToSortedList(getElementDeclarations(), xsdElementDeclaration);
          return this;
        }
        @Override
        public Object caseXSDAttributeDeclaration(XSDAttributeDeclaration xsdAttributeDeclaration)
        {
          XSDNamedComponentImpl.addToSortedList(getAttributeDeclarations(), xsdAttributeDeclaration);
          return this;
        }
        @Override
        public Object caseXSDAttributeGroupDefinition(XSDAttributeGroupDefinition xsdAttributeGroupDefinition)
        {
          XSDNamedComponentImpl.addToSortedList(getAttributeGroupDefinitions(), xsdAttributeGroupDefinition);
          return this;
        }
        @Override
        public Object caseXSDTypeDefinition(XSDTypeDefinition xsdTypeDefinition)
        {
          XSDNamedComponentImpl.addToSortedList(getTypeDefinitions(), xsdTypeDefinition);
          return this;
        }
        @Override
        public Object caseXSDModelGroupDefinition(XSDModelGroupDefinition xsdModelGroupDefinition)
        {
          XSDNamedComponentImpl.addToSortedList(getModelGroupDefinitions(), xsdModelGroupDefinition);
          return this;
        }
        @Override
        public Object caseXSDNotationDeclaration(XSDNotationDeclaration xsdNotationDeclaration)
        {
          XSDNamedComponentImpl.addToSortedList(getNotationDeclarations(), xsdNotationDeclaration);
          return this;
        }
        @Override
        public Object caseXSDAnnotation(XSDAnnotation xsdAnnotation)
        {
          getAnnotations().add(xsdAnnotation);
          return this;
        }
      }.doSwitch(xsdConcreteComponent);

      traverseToRootForPatching();
    }
  }

  @Override
  protected void orphanContent(EReference eReference, XSDConcreteComponent xsdConcreteComponent)
  {
    super.orphanContent(eReference, xsdConcreteComponent);
    if (eReference == XSDPackage.Literals.XSD_SCHEMA__CONTENTS)
    {
      new XSDSwitch<Object>()
      {
        @Override
        public Object caseXSDElementDeclaration(XSDElementDeclaration xsdElementDeclaration)
        {
          getElementDeclarations().remove(xsdElementDeclaration);
          return this;
        }
        @Override
        public Object caseXSDAttributeDeclaration(XSDAttributeDeclaration xsdAttributeDeclaration)
        {
          getAttributeDeclarations().remove(xsdAttributeDeclaration);
          return this;
        }
        @Override
        public Object caseXSDAttributeGroupDefinition(XSDAttributeGroupDefinition xsdAttributeGroupDefinition)
        {
          getAttributeGroupDefinitions().remove(xsdAttributeGroupDefinition);
          return this;
        }
        @Override
        public Object caseXSDTypeDefinition(XSDTypeDefinition xsdTypeDefinition)
        {
          getTypeDefinitions().remove(xsdTypeDefinition);
          return this;
        }
        @Override
        public Object caseXSDModelGroupDefinition(XSDModelGroupDefinition xsdModelGroupDefinition)
        {
          getModelGroupDefinitions().remove(xsdModelGroupDefinition);
          return this;
        }
        @Override
        public Object caseXSDNotationDeclaration(XSDNotationDeclaration xsdNotationDeclaration)
        {
          getNotationDeclarations().remove(xsdNotationDeclaration);
          return this;
        }
        @Override
        public Object caseXSDAnnotation(XSDAnnotation xsdAnnotation)
        {
          getAnnotations().remove(xsdAnnotation);
          return this;
        }
      }.doSwitch(xsdConcreteComponent);

      traverseToRootForPatching();
    }
  }

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

    if (changedElement == getElement())
    {
      if (changedElement.hasAttributeNS(null, XSDConstants.VERSION_ATTRIBUTE))
      {
        String newVersion = changedElement.getAttributeNS(null, XSDConstants.VERSION_ATTRIBUTE);
        if (!newVersion.equals(getVersion()))
        {
          setVersion(newVersion);
        }
      }
      else if (getVersion() != null)
      {
        setVersion(null);
      }

      if (changedElement.hasAttributeNS(null, XSDConstants.TARGETNAMESPACE_ATTRIBUTE))
      {
        String newTargetNamespace = changedElement.getAttributeNS(null, XSDConstants.TARGETNAMESPACE_ATTRIBUTE);
        if (!newTargetNamespace.equals(getTargetNamespace()))
        {
          setTargetNamespace(newTargetNamespace);
        }
      }
      else if (getTargetNamespace() != null)
      {
        setTargetNamespace(null);
      }

      if (changedElement.hasAttributeNS(null, XSDConstants.ATTRIBUTEFORMDEFAULT_ATTRIBUTE))
      {
        XSDForm newAttributeFormDefault = XSDForm.get(changedElement.getAttributeNS(null, XSDConstants.ATTRIBUTEFORMDEFAULT_ATTRIBUTE));
        if (!isSetAttributeFormDefault() || newAttributeFormDefault != getAttributeFormDefault())
        {
          setAttributeFormDefault(newAttributeFormDefault);
        }
      }
      else if (isSetAttributeFormDefault())
      {
        unsetAttributeFormDefault();
      }
      if (changedElement.hasAttributeNS(null, XSDConstants.ELEMENTFORMDEFAULT_ATTRIBUTE))
      {
        XSDForm newElementFormDefault = XSDForm.get(changedElement.getAttributeNS(null, XSDConstants.ELEMENTFORMDEFAULT_ATTRIBUTE));
        if (!isSetElementFormDefault() || newElementFormDefault != getElementFormDefault())
        {
          setElementFormDefault(newElementFormDefault);
        }
      }
      else if (isSetElementFormDefault())
      {
        unsetElementFormDefault();
      }

      if (changedElement.hasAttributeNS(null, XSDConstants.BLOCKDEFAULT_ATTRIBUTE))
      {
        setStringBlockDefault(changedElement.getAttributeNS(null, XSDConstants.BLOCKDEFAULT_ATTRIBUTE));
      }
      else if (isSetBlockDefault())
      {
        unsetBlockDefault();
      }

      if (changedElement.hasAttributeNS(null, XSDConstants.FINALDEFAULT_ATTRIBUTE))
      {
        setStringFinalDefault(changedElement.getAttributeNS(null, XSDConstants.FINALDEFAULT_ATTRIBUTE));
      }
      else if (isSetFinalDefault())
      {
        unsetFinalDefault();
      }

      Map<String, String> theQNamePrefixToNamespaceMap = getQNamePrefixToNamespaceMap();
      theQNamePrefixToNamespaceMap.clear();
      for (Element currentElement = changedElement; ; ) 
      {
        NamedNodeMap attributes = currentElement.getAttributes(); 
        for (int i = 0, size = attributes.getLength(); i < size; ++i)
        {
          Attr attr = (Attr)attributes.item(i);
          String name = attr.getNodeName();
          if (name.startsWith("xmlns"))
          {
            String value = attr.getNodeValue();
            int index = name.indexOf(":");
            String key = index == -1 || index == name.length() - 1? null : name.substring(index + 1);
            if (!theQNamePrefixToNamespaceMap.containsKey(key)) 
            {
              theQNamePrefixToNamespaceMap.put(key, value);
            }
          }
        }
        Node parent = currentElement.getParentNode(); 
        if (parent instanceof Element)
        {
          currentElement = (Element)parent;
        }
        else
        {
          break;
        }
      } 

      String nodeName =  changedElement.getNodeName();
      int index = nodeName.indexOf(":");
      setSchemaForSchemaQNamePrefix(index == -1 ? null : nodeName.substring(0, index));
    }
  }

  @Override
  protected void handleUnreconciledElement(Element child, List<XSDConcreteComponent> newContents, List<XSDConcreteComponent> remainingContents)
  {
    XSDSchemaContent xsdSchemaContent = XSDSchemaContentImpl.createSchemaContent(child);
    if (xsdSchemaContent != null)
    {
      newContents.add(xsdSchemaContent);
    }
  }

  @Override
  protected void handleReconciliation(List<XSDConcreteComponent> newContents, List<XSDConcreteComponent> remainingContents)
  {
    if (!remainingContents.isEmpty())
    {
      getContents().removeAll(remainingContents);
    }

    @SuppressWarnings("unchecked") List<XSDSchemaContent> list = (List<XSDSchemaContent>)(List<?>)newContents;
    setListContentAndOrder(getContents(), list);
  }

  public XSDConcreteComponent getCorrespondingComponent(Node node)
  {
    // We consider all parents so that they can handle other contained nodes that otherwise don't correspond to a component.
    //
    List<Element> parents = new ArrayList<Element>();
  
    if (node.getNodeType() == Node.ATTRIBUTE_NODE)
    {
      node = ((Attr)node).getOwnerElement();
    }
    else
    {
      // Skip ahead to an element.
      //
      for (Node scanNode = node; scanNode != null; scanNode = scanNode.getNextSibling())
      {
        if (scanNode.getNodeType() == Node.ELEMENT_NODE)
        {
          node = scanNode;
          break;
        }
      }
  
      // Skip back to an element.
      //
      for (Node scanNode = node; scanNode != null; scanNode = scanNode.getPreviousSibling())
      {
        if (scanNode.getNodeType() == Node.ELEMENT_NODE)
        {
          node = scanNode;
          break;
        }
      }
    }
  
    // Navigate out through the elements.
    //
    for (Node parent = node; parent != null; parent = parent.getParentNode())
    {
      if (parent.getNodeType() == Node.ELEMENT_NODE)
      {
        parents.add((Element)parent);
      }
    }

    XSDConcreteComponent bestXSDConcreteComponent = getBestConcreteComponent(parents);
    return bestXSDConcreteComponent;
  }

  protected Map<String, XSDSimpleTypeDefinition> simpleTypeIdMap;
  public Map<String, XSDSimpleTypeDefinition> getSimpleTypeIdMap()
  {
    if (simpleTypeIdMap == null)
    {
      simpleTypeIdMap = new HashMap<String, XSDSimpleTypeDefinition>();
      for (XSDTypeDefinition xsdTypeDefinition : getTypeDefinitions())
      {
        if (xsdTypeDefinition  instanceof XSDSimpleTypeDefinition)
        {
          Element theElement = xsdTypeDefinition.getElement();
          if (theElement != null)
          {
            if (theElement.hasAttributeNS(null, XSDConstants.ID_ATTRIBUTE) && xsdTypeDefinition instanceof XSDSimpleTypeDefinition)
            {
              simpleTypeIdMap.put(theElement.getAttributeNS(null, XSDConstants.ID_ATTRIBUTE), (XSDSimpleTypeDefinition)xsdTypeDefinition);
            }
          }
        }
      }
    }
    return simpleTypeIdMap;
  }

  protected List<XSDSchema> incorporatingSchemas;

  protected List<XSDSchema> getIncorporatingSchemas()
  {
    if (incorporatingSchemas == null)
    {
      List<XSDSchema> visited = new UniqueEList.FastCompare<XSDSchema>();
      visited.add(this);
      incorporatingSchemas = new ArrayList<XSDSchema>();
      for (int i = 0; i < visited.size(); ++i)
      {
        XSDSchemaImpl xsdSchema = (XSDSchemaImpl)visited.get(i);
        incorporatingSchemas.add(xsdSchema);
        for (XSDSchemaDirective xsdSchemaDirective : xsdSchema.getReferencingDirectives())
        {
          if (xsdSchemaDirective instanceof XSDSchemaCompositor && ((XSDSchemaCompositor)xsdSchemaDirective).getIncorporatedSchema() == xsdSchema)
          {
            XSDSchemaImpl incorporatingSchema = (XSDSchemaImpl)xsdSchemaDirective.getSchema();
            if (incorporatingSchema != null && visited.add(incorporatingSchema))
            {
              incorporatingSchemas.add(incorporatingSchema);
              visited.addAll(incorporatingSchema.getIncorporatingSchemas());
            }
          }
        }
      }
    }
    return incorporatingSchemas;
  }
  
  /**
   * This returns set of schemas with the given namespace as it's target namespace.
   */
  public Collection<XSDSchema> resolveSchema(String namespace)
  {
    if ("".equals(namespace))
    {
      namespace = null;
    }

    if (namespace == null ? getTargetNamespace() == null || "".equals(getTargetNamespace()) || hasRetargetedNamespace() : namespace.equals(getTargetNamespace()))
    {
      return getIncorporatingSchemas();
    }
    else if (XSDConstants.isSchemaInstanceNamespace(namespace))
    {
      return Collections.singleton(getSchemaInstance(namespace));
    }
    else
    {
      Collection<XSDSchema> result = new ArrayList<XSDSchema>();
      for (XSDSchemaContent xsdSchemaContent : getContents())
      {
        if (xsdSchemaContent instanceof XSDSchemaDirective)
        {
          if (xsdSchemaContent instanceof XSDImport)
          {
            XSDImport xsdImport = (XSDImport)xsdSchemaContent;
            String importNamespace = xsdImport.getNamespace();
            if (namespace == null ? importNamespace == null || "".equals(importNamespace): namespace.equals(importNamespace))
            {
              XSDSchema importedSchema = ((XSDImportImpl)xsdImport).importSchema();
              if (importedSchema != null)
              {
                result.add(importedSchema);
                Collection<XSDSchemaImpl> circular = ((XSDSchemaImpl)importedSchema).circularResolveDependencies;
                if (circular != null)
                {
                  circular.add(this);
                }
              }
            }
          }
        }
        else if (!(xsdSchemaContent instanceof XSDAnnotation))
        {
          break;
        }
      }

      return result;
    }
  }

  /**
   * This is a helper method for searching for a name in one of the schemas named component relations.
   */
  protected XSDNamedComponent resolveNamedComponent(EReference namedComponentsRefReference, String namespace, String localName)
  {
    if ("".equals(namespace))
    {
      namespace = null;
    }

    Collection<XSDSchema> resolvedSchemas = resolveSchema(namespace);
    for (XSDSchema resolvedSchema : resolvedSchemas)
    {
      @SuppressWarnings("unchecked") List<XSDNamedComponent> list = (List<XSDNamedComponent>)resolvedSchema.eGet(namedComponentsRefReference);
      XSDNamedComponent xsdNamedComponent = XSDNamedComponentImpl.findInSortedList(list, namespace, localName);
      if (xsdNamedComponent == null && namespace == null && resolvedSchemas.contains(this) && resolvedSchema.getTargetNamespace() != null)
      {
        xsdNamedComponent = XSDNamedComponentImpl.findInSortedList(list, getTargetNamespace(), localName);
        
      }
      if (xsdNamedComponent != null)
      {
        return xsdNamedComponent;
      }
    }
    return null;
  }

  @Override
  public XSDAttributeDeclaration resolveAttributeDeclaration(String namespace, String localName)
  {
    XSDAttributeDeclaration result = 
      (XSDAttributeDeclaration)resolveNamedComponent(XSDPackage.Literals.XSD_SCHEMA__ATTRIBUTE_DECLARATIONS, namespace, localName);
    if (result == null)
    {
      result = createUnresolvedAttributeDeclaration(namespace, localName);
    }
    return result;
  }

  @Override
  public XSDAttributeGroupDefinition resolveAttributeGroupDefinition(String namespace, String localName)
  {
    XSDAttributeGroupDefinition result = 
      (XSDAttributeGroupDefinition)resolveNamedComponent
        (XSDPackage.Literals.XSD_SCHEMA__ATTRIBUTE_GROUP_DEFINITIONS, namespace, localName);
    if (result == null)
    {
      result = createUnresolvedAttributeGroupDefinition(namespace, localName);
    }
    return result;
  }

  @Override
  public XSDElementDeclaration resolveElementDeclaration(String namespace, String localName)
  {
    XSDElementDeclaration result = 
      (XSDElementDeclaration)resolveNamedComponent(XSDPackage.Literals.XSD_SCHEMA__ELEMENT_DECLARATIONS, namespace, localName);
    if (result == null)
    {
      result = createUnresolvedElementDeclaration(namespace, localName);
    }
    return result;
  }

  @Override
  public XSDTypeDefinition resolveTypeDefinition(String namespace, String localName)
  {
    XSDTypeDefinition result = 
      (XSDTypeDefinition)resolveNamedComponent(XSDPackage.Literals.XSD_SCHEMA__TYPE_DEFINITIONS, namespace, localName);
    if (result == null && 
          XSDConstants.isSchemaForSchemaNamespace(namespace) &&
          !XSDConstants.isSchemaForSchemaNamespace(getTargetNamespace()))
    {
      result = getSchemaForSchema(namespace).resolveTypeDefinition(namespace, localName);
    }
    if (result == null)
    {
      result =  createUnresolvedTypeDefinition(namespace, localName);
    }
    return result;
  }

  @Override
  public XSDSimpleTypeDefinition resolveSimpleTypeDefinition(String namespace, String localName)
  {
    XSDTypeDefinition xsdTypeDefinition = 
      (XSDTypeDefinition)resolveNamedComponent(XSDPackage.Literals.XSD_SCHEMA__TYPE_DEFINITIONS, namespace, localName);
    XSDSimpleTypeDefinition result =
      xsdTypeDefinition instanceof XSDSimpleTypeDefinition ? (XSDSimpleTypeDefinition)xsdTypeDefinition : null;
    if (result == null)
    {
      if (XSDConstants.isSchemaForSchemaNamespace(namespace))
      {
        if  ("anyType".equals(localName) || "anySimpleType".equals(localName))
        {
          XSDSchema magicSchemaForSchema = getMagicSchemaForSchema(namespace);
          if (magicSchemaForSchema == this)
          {
            EList<XSDTypeDefinition> typeDefinitions = magicSchemaForSchema.getTypeDefinitions();
            if (typeDefinitions.size() > 0)
            {
              result = (XSDSimpleTypeDefinition)typeDefinitions.get(0);
            }
          }
          else 
          {
            result = magicSchemaForSchema.resolveSimpleTypeDefinition(namespace, localName);
          }
        }
        else if (!XSDConstants.isSchemaForSchemaNamespace(getTargetNamespace()))
        {
          XSDSchema schemaForSchema = getSchemaForSchema(namespace);
          result = schemaForSchema.resolveSimpleTypeDefinition(namespace, localName);
        }
      }
    }

    if (result == null)
    {
      result =  createUnresolvedSimpleTypeDefinition(namespace, localName);
    }
    return result;
  }

  @Override
  public XSDComplexTypeDefinition resolveComplexTypeDefinition(String namespace, String localName)
  {
    XSDTypeDefinition xsdTypeDefinition = 
      (XSDTypeDefinition)resolveNamedComponent(XSDPackage.Literals.XSD_SCHEMA__TYPE_DEFINITIONS, namespace, localName);
    XSDComplexTypeDefinition result =
      xsdTypeDefinition instanceof XSDComplexTypeDefinition ? (XSDComplexTypeDefinition)xsdTypeDefinition : null;
    if (result == null &&
          XSDConstants.isSchemaForSchemaNamespace(namespace) && 
          !XSDConstants.isSchemaForSchemaNamespace(getTargetNamespace()))
    {
      result = getSchemaForSchema(namespace).resolveComplexTypeDefinition(namespace, localName);
    }
    if (result == null)
    {
      result =  createUnresolvedComplexTypeDefinition(namespace, localName);
    }
    return result;
  }

  @Override
  public XSDModelGroupDefinition resolveModelGroupDefinition(String namespace, String localName)
  {
    XSDModelGroupDefinition result = 
      (XSDModelGroupDefinition)resolveNamedComponent(XSDPackage.Literals.XSD_SCHEMA__MODEL_GROUP_DEFINITIONS, namespace, localName);
    if (result == null)
    {
      result = createUnresolvedModelGroupDefinition(namespace, localName);
    }

    return result;
  }

  @Override
  public XSDIdentityConstraintDefinition resolveIdentityConstraintDefinition(String namespace, String localName)
  {
    XSDIdentityConstraintDefinition result = 
      (XSDIdentityConstraintDefinition)resolveNamedComponent(XSDPackage.Literals.XSD_SCHEMA__IDENTITY_CONSTRAINT_DEFINITIONS, namespace, localName);
    if (result == null)
    {
      result = createUnresolvedIdentityConstraintDefinition(namespace, localName);
    }
    return result;
  }

  @Override
  public XSDNotationDeclaration resolveNotationDeclaration(String namespace, String localName)
  {
    XSDNotationDeclaration result =
      (XSDNotationDeclaration) resolveNamedComponent(XSDPackage.Literals.XSD_SCHEMA__NOTATION_DECLARATIONS, namespace, localName);
    if (result == null)
    {
      result = createUnresolvedNotationDeclaration(namespace, localName);
    }
    return result;
  }

  @Override
  protected void changeAttribute(EAttribute eAttribute)
  {
    if (eAttribute == XSDPackage.Literals.XSD_SCHEMA__SCHEMA_LOCATION)
    {
      patch();
    }
    else
    {
      super.changeAttribute(eAttribute);
      Element theElement = getElement();
      if (theElement != null)
      {
        if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SCHEMA__VERSION)
        {
          niceSetAttribute
            (theElement, 
             XSDConstants.VERSION_ATTRIBUTE, 
             getVersion());
          if (eAttribute != null)
          {
            traverseToRootForPatching();
          }
        }
        if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SCHEMA__TARGET_NAMESPACE)
        {
          niceSetAttribute
            (theElement, 
             XSDConstants.TARGETNAMESPACE_ATTRIBUTE, 
             getTargetNamespace());
          if (eAttribute != null)
          {
            if (!isReconciling && isIncrementalUpdate)
            {
              for (Object content : getContents())
              {
                if (content instanceof XSDNamedComponentImpl)
                {
                  ((XSDNamedComponentImpl)content).patchTargetNamespaceAttribute();
                }
              }
              reset();
            }
          }
        }
        if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SCHEMA__ATTRIBUTE_FORM_DEFAULT)
        {
          niceSetAttribute
            (theElement, 
             XSDConstants.ATTRIBUTEFORMDEFAULT_ATTRIBUTE, 
             isSetAttributeFormDefault() ? getAttributeFormDefault().getName() : null);
          if (eAttribute != null)
          {
            traverseToRootForPatching();
          }
        }
        if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SCHEMA__ELEMENT_FORM_DEFAULT)
        {
          niceSetAttribute
            (theElement, 
             XSDConstants.ELEMENTFORMDEFAULT_ATTRIBUTE, 
             isSetElementFormDefault() ? getElementFormDefault().getName() : null);
          if (eAttribute != null)
          {
            traverseToRootForPatching();
          }
        }
        if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SCHEMA__BLOCK_DEFAULT)
        {
          niceSetAttribute
            (theElement, 
             XSDConstants.BLOCKDEFAULT_ATTRIBUTE, 
             getStringBlockDefault());
          if (eAttribute != null)
          {
            traverseToRootForPatching();
          }
        }
        if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SCHEMA__FINAL_DEFAULT)
        {
          niceSetAttribute
            (theElement, 
             XSDConstants.FINALDEFAULT_ATTRIBUTE, 
             getStringFinalDefault());
          if (eAttribute != null)
          {
            traverseToRootForPatching();
          }
        }
      }
    }
  }

  @Override
  protected void changeReference(EReference eReference)
  {
    super.changeReference(eReference);
    if (eReference == XSDPackage.Literals.XSD_SCHEMA__REFERENCING_DIRECTIVES)
    {
      boolean newHasRetargetedNamespace = false;
      for (XSDSchemaDirective xsdSchemaDirective : getReferencingDirectives())
      {
        if (xsdSchemaDirective instanceof XSDSchemaCompositor)
        {
          XSDSchemaCompositor xsdSchemaCompositor = (XSDSchemaCompositor)xsdSchemaDirective;
          if (xsdSchemaCompositor.getResolvedSchema() != xsdSchemaCompositor.getIncorporatedSchema() &&
                xsdSchemaCompositor.getResolvedSchema().getTargetNamespace() == null)
          {
            newHasRetargetedNamespace = true;
            break;
          }
        }
      }
      hasRetargetedNamespace = newHasRetargetedNamespace;
    }
  }

/*
  public void unsetElement()
  {
    Element oldElement = getElement();
    if (oldElement instanceof EventTarget)
    {
      EventTarget oldEventTarget = ((EventTarget)oldElement);
      oldEventTarget.removeEventListener("DOMNodeInserted", getEventListener(), true);
      oldEventTarget.removeEventListener("DOMNodeRemoved", getEventListener(), true);
      oldEventTarget.removeEventListener("DOMAttrModified", getEventListener(), true);
    }
    super.unsetElement();
  }
*/

  @Override
  public void setElement(Element element)
  {
    Element oldElement = getElement();
    if (oldElement instanceof EventTarget)
    {
      EventTarget oldEventTarget = ((EventTarget)oldElement);
      oldEventTarget.removeEventListener("DOMNodeInserted", getEventListener(), true);
      oldEventTarget.removeEventListener("DOMNodeRemoved", getEventListener(), true);
      oldEventTarget.removeEventListener("DOMAttrModified", getEventListener(), true);
    }
    super.setElement(element);
    if (element instanceof EventTarget)
    {
      EventTarget eventTarget = ((EventTarget)element);
      eventTarget.addEventListener("DOMNodeInserted", getEventListener(), true);
      eventTarget.addEventListener("DOMNodeRemoved", getEventListener(), true);
      eventTarget.addEventListener("DOMAttrModified", getEventListener(), true);
    }
    if (element != null)
    {
      document = element.getOwnerDocument();
    }
  }

  public XSDSchema getSchemaForSchema()
  {
    return getSchemaForSchema(getSchemaForSchemaNamespace());
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_SCHEMA__CONTENTS:
        return ((InternalEList<?>)getContents()).basicRemove(otherEnd, msgs);
      case XSDPackage.XSD_SCHEMA__INCORPORATED_VERSIONS:
        return ((InternalEList<?>)getIncorporatedVersions()).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_SCHEMA__DOCUMENT:
        return getDocument();
      case XSDPackage.XSD_SCHEMA__SCHEMA_LOCATION:
        return getSchemaLocation();
      case XSDPackage.XSD_SCHEMA__TARGET_NAMESPACE:
        return getTargetNamespace();
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_FORM_DEFAULT:
        return getAttributeFormDefault();
      case XSDPackage.XSD_SCHEMA__ELEMENT_FORM_DEFAULT:
        return getElementFormDefault();
      case XSDPackage.XSD_SCHEMA__FINAL_DEFAULT:
        return getFinalDefault();
      case XSDPackage.XSD_SCHEMA__BLOCK_DEFAULT:
        return getBlockDefault();
      case XSDPackage.XSD_SCHEMA__VERSION:
        return getVersion();
      case XSDPackage.XSD_SCHEMA__CONTENTS:
        return getContents();
      case XSDPackage.XSD_SCHEMA__ELEMENT_DECLARATIONS:
        return getElementDeclarations();
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_DECLARATIONS:
        return getAttributeDeclarations();
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_GROUP_DEFINITIONS:
        return getAttributeGroupDefinitions();
      case XSDPackage.XSD_SCHEMA__TYPE_DEFINITIONS:
        return getTypeDefinitions();
      case XSDPackage.XSD_SCHEMA__MODEL_GROUP_DEFINITIONS:
        return getModelGroupDefinitions();
      case XSDPackage.XSD_SCHEMA__IDENTITY_CONSTRAINT_DEFINITIONS:
        return getIdentityConstraintDefinitions();
      case XSDPackage.XSD_SCHEMA__NOTATION_DECLARATIONS:
        return getNotationDeclarations();
      case XSDPackage.XSD_SCHEMA__ANNOTATIONS:
        return getAnnotations();
      case XSDPackage.XSD_SCHEMA__ALL_DIAGNOSTICS:
        return getAllDiagnostics();
      case XSDPackage.XSD_SCHEMA__REFERENCING_DIRECTIVES:
        return getReferencingDirectives();
      case XSDPackage.XSD_SCHEMA__ROOT_VERSION:
        return getRootVersion();
      case XSDPackage.XSD_SCHEMA__ORIGINAL_VERSION:
        return getOriginalVersion();
      case XSDPackage.XSD_SCHEMA__INCORPORATED_VERSIONS:
        return getIncorporatedVersions();
      case XSDPackage.XSD_SCHEMA__SCHEMA_FOR_SCHEMA:
        return getSchemaForSchema();
    }
    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_SCHEMA__DOCUMENT:
        setDocument((Document)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__SCHEMA_LOCATION:
        setSchemaLocation((String)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__TARGET_NAMESPACE:
        setTargetNamespace((String)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_FORM_DEFAULT:
        setAttributeFormDefault((XSDForm)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__ELEMENT_FORM_DEFAULT:
        setElementFormDefault((XSDForm)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__FINAL_DEFAULT:
        getFinalDefault().clear();
        getFinalDefault().addAll((Collection<? extends XSDProhibitedSubstitutions>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__BLOCK_DEFAULT:
        getBlockDefault().clear();
        getBlockDefault().addAll((Collection<? extends XSDDisallowedSubstitutions>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__VERSION:
        setVersion((String)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__CONTENTS:
        getContents().clear();
        getContents().addAll((Collection<? extends XSDSchemaContent>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__ELEMENT_DECLARATIONS:
        getElementDeclarations().clear();
        getElementDeclarations().addAll((Collection<? extends XSDElementDeclaration>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_DECLARATIONS:
        getAttributeDeclarations().clear();
        getAttributeDeclarations().addAll((Collection<? extends XSDAttributeDeclaration>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_GROUP_DEFINITIONS:
        getAttributeGroupDefinitions().clear();
        getAttributeGroupDefinitions().addAll((Collection<? extends XSDAttributeGroupDefinition>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__TYPE_DEFINITIONS:
        getTypeDefinitions().clear();
        getTypeDefinitions().addAll((Collection<? extends XSDTypeDefinition>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__MODEL_GROUP_DEFINITIONS:
        getModelGroupDefinitions().clear();
        getModelGroupDefinitions().addAll((Collection<? extends XSDModelGroupDefinition>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__IDENTITY_CONSTRAINT_DEFINITIONS:
        getIdentityConstraintDefinitions().clear();
        getIdentityConstraintDefinitions().addAll((Collection<? extends XSDIdentityConstraintDefinition>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__NOTATION_DECLARATIONS:
        getNotationDeclarations().clear();
        getNotationDeclarations().addAll((Collection<? extends XSDNotationDeclaration>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__ANNOTATIONS:
        getAnnotations().clear();
        getAnnotations().addAll((Collection<? extends XSDAnnotation>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__ALL_DIAGNOSTICS:
        getAllDiagnostics().clear();
        getAllDiagnostics().addAll((Collection<? extends XSDDiagnostic>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__REFERENCING_DIRECTIVES:
        getReferencingDirectives().clear();
        getReferencingDirectives().addAll((Collection<? extends XSDSchemaDirective>)newValue);
        return;
      case XSDPackage.XSD_SCHEMA__INCORPORATED_VERSIONS:
        getIncorporatedVersions().clear();
        getIncorporatedVersions().addAll((Collection<? extends XSDSchema>)newValue);
        return;
    }
    super.eSet(featureID, newValue);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public void eUnset(int featureID)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_SCHEMA__DOCUMENT:
        setDocument(DOCUMENT_EDEFAULT);
        return;
      case XSDPackage.XSD_SCHEMA__SCHEMA_LOCATION:
        setSchemaLocation(SCHEMA_LOCATION_EDEFAULT);
        return;
      case XSDPackage.XSD_SCHEMA__TARGET_NAMESPACE:
        setTargetNamespace(TARGET_NAMESPACE_EDEFAULT);
        return;
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_FORM_DEFAULT:
        unsetAttributeFormDefault();
        return;
      case XSDPackage.XSD_SCHEMA__ELEMENT_FORM_DEFAULT:
        unsetElementFormDefault();
        return;
      case XSDPackage.XSD_SCHEMA__FINAL_DEFAULT:
        unsetFinalDefault();
        return;
      case XSDPackage.XSD_SCHEMA__BLOCK_DEFAULT:
        unsetBlockDefault();
        return;
      case XSDPackage.XSD_SCHEMA__VERSION:
        setVersion(VERSION_EDEFAULT);
        return;
      case XSDPackage.XSD_SCHEMA__CONTENTS:
        getContents().clear();
        return;
      case XSDPackage.XSD_SCHEMA__ELEMENT_DECLARATIONS:
        getElementDeclarations().clear();
        return;
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_DECLARATIONS:
        getAttributeDeclarations().clear();
        return;
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_GROUP_DEFINITIONS:
        getAttributeGroupDefinitions().clear();
        return;
      case XSDPackage.XSD_SCHEMA__TYPE_DEFINITIONS:
        getTypeDefinitions().clear();
        return;
      case XSDPackage.XSD_SCHEMA__MODEL_GROUP_DEFINITIONS:
        getModelGroupDefinitions().clear();
        return;
      case XSDPackage.XSD_SCHEMA__IDENTITY_CONSTRAINT_DEFINITIONS:
        getIdentityConstraintDefinitions().clear();
        return;
      case XSDPackage.XSD_SCHEMA__NOTATION_DECLARATIONS:
        getNotationDeclarations().clear();
        return;
      case XSDPackage.XSD_SCHEMA__ANNOTATIONS:
        getAnnotations().clear();
        return;
      case XSDPackage.XSD_SCHEMA__ALL_DIAGNOSTICS:
        getAllDiagnostics().clear();
        return;
      case XSDPackage.XSD_SCHEMA__REFERENCING_DIRECTIVES:
        getReferencingDirectives().clear();
        return;
      case XSDPackage.XSD_SCHEMA__INCORPORATED_VERSIONS:
        getIncorporatedVersions().clear();
        return;
    }
    super.eUnset(featureID);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public boolean eIsSet(int featureID)
  {
    switch (featureID)
    {
      case XSDPackage.XSD_SCHEMA__DOCUMENT:
        return DOCUMENT_EDEFAULT == null ? document != null : !DOCUMENT_EDEFAULT.equals(document);
      case XSDPackage.XSD_SCHEMA__SCHEMA_LOCATION:
        return SCHEMA_LOCATION_EDEFAULT == null ? schemaLocation != null : !SCHEMA_LOCATION_EDEFAULT.equals(schemaLocation);
      case XSDPackage.XSD_SCHEMA__TARGET_NAMESPACE:
        return TARGET_NAMESPACE_EDEFAULT == null ? targetNamespace != null : !TARGET_NAMESPACE_EDEFAULT.equals(targetNamespace);
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_FORM_DEFAULT:
        return isSetAttributeFormDefault();
      case XSDPackage.XSD_SCHEMA__ELEMENT_FORM_DEFAULT:
        return isSetElementFormDefault();
      case XSDPackage.XSD_SCHEMA__FINAL_DEFAULT:
        return isSetFinalDefault();
      case XSDPackage.XSD_SCHEMA__BLOCK_DEFAULT:
        return isSetBlockDefault();
      case XSDPackage.XSD_SCHEMA__VERSION:
        return VERSION_EDEFAULT == null ? version != null : !VERSION_EDEFAULT.equals(version);
      case XSDPackage.XSD_SCHEMA__CONTENTS:
        return contents != null && !contents.isEmpty();
      case XSDPackage.XSD_SCHEMA__ELEMENT_DECLARATIONS:
        return elementDeclarations != null && !elementDeclarations.isEmpty();
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_DECLARATIONS:
        return attributeDeclarations != null && !attributeDeclarations.isEmpty();
      case XSDPackage.XSD_SCHEMA__ATTRIBUTE_GROUP_DEFINITIONS:
        return attributeGroupDefinitions != null && !attributeGroupDefinitions.isEmpty();
      case XSDPackage.XSD_SCHEMA__TYPE_DEFINITIONS:
        return typeDefinitions != null && !typeDefinitions.isEmpty();
      case XSDPackage.XSD_SCHEMA__MODEL_GROUP_DEFINITIONS:
        return modelGroupDefinitions != null && !modelGroupDefinitions.isEmpty();
      case XSDPackage.XSD_SCHEMA__IDENTITY_CONSTRAINT_DEFINITIONS:
        return identityConstraintDefinitions != null && !identityConstraintDefinitions.isEmpty();
      case XSDPackage.XSD_SCHEMA__NOTATION_DECLARATIONS:
        return notationDeclarations != null && !notationDeclarations.isEmpty();
      case XSDPackage.XSD_SCHEMA__ANNOTATIONS:
        return annotations != null && !annotations.isEmpty();
      case XSDPackage.XSD_SCHEMA__ALL_DIAGNOSTICS:
        return allDiagnostics != null && !allDiagnostics.isEmpty();
      case XSDPackage.XSD_SCHEMA__REFERENCING_DIRECTIVES:
        return referencingDirectives != null && !referencingDirectives.isEmpty();
      case XSDPackage.XSD_SCHEMA__ROOT_VERSION:
        return getRootVersion() != null;
      case XSDPackage.XSD_SCHEMA__ORIGINAL_VERSION:
        return getOriginalVersion() != null;
      case XSDPackage.XSD_SCHEMA__INCORPORATED_VERSIONS:
        return incorporatedVersions != null && !incorporatedVersions.isEmpty();
      case XSDPackage.XSD_SCHEMA__SCHEMA_FOR_SCHEMA:
        return getSchemaForSchema() != null;
    }
    return super.eIsSet(featureID);
  }

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

    StringBuffer result = new StringBuffer(super.toString());
    result.append(" (document: ");
    result.append(document);
    result.append(", schemaLocation: ");
    result.append(schemaLocation);
    result.append(", targetNamespace: ");
    result.append(targetNamespace);
    result.append(", attributeFormDefault: ");
    if ((eFlags & ATTRIBUTE_FORM_DEFAULT_ESETFLAG) != 0) result.append(ATTRIBUTE_FORM_DEFAULT_EFLAG_VALUES[(eFlags & ATTRIBUTE_FORM_DEFAULT_EFLAG) >>> ATTRIBUTE_FORM_DEFAULT_EFLAG_OFFSET]); else result.append("<unset>");
    result.append(", elementFormDefault: ");
    if ((eFlags & ELEMENT_FORM_DEFAULT_ESETFLAG) != 0) result.append(ELEMENT_FORM_DEFAULT_EFLAG_VALUES[(eFlags & ELEMENT_FORM_DEFAULT_EFLAG) >>> ELEMENT_FORM_DEFAULT_EFLAG_OFFSET]); else result.append("<unset>");
    result.append(", finalDefault: ");
    result.append(finalDefault);
    result.append(", blockDefault: ");
    result.append(blockDefault);
    result.append(", version: ");
    result.append(version);
    result.append(')');
    return result.toString();
  }

  public XSDSchema getMagicSchemaForSchema()
  {
    return getMagicSchemaForSchema(getSchemaForSchemaNamespace());
  }

  protected EventListener eventListener;
  protected Node deletionNode;

  public Node getDeletionNode()
  {
    return deletionNode;
  }

  private static class DummyEventListener implements EventListener, Serializable
  {
    private static final long serialVersionUID = 1L;

    public void handleEvent(Event arg0)
    {
      // Ignore.
    }
  }

  protected EventListener getEventListener()
  {
    if (eventListener == null)
    {
      class XSDSchemaEventListener implements EventListener, Serializable
      {
        private static final long serialVersionUID = 1L;

        public void handleEvent(Event event) 
        {
          if (event instanceof MutationEvent)
          {
            MutationEvent mutationEvent = (MutationEvent)event;
            if (mutationEvent.getTarget() instanceof Node)
            {
              Node node = (Node)mutationEvent.getTarget();
              while (node.getNodeType() != Node.ELEMENT_NODE)
              {
                node = node.getParentNode();
              }
              if (mutationEvent.getAttrChange() == 0)
              {
                XSDConcreteComponent listener = getCorrespondingComponent(node.getParentNode());
                if (listener != null)
                {
                  if (event.getType().equals("DOMNodeRemoved"))
                  {
                    deletionNode = (Node)event.getTarget();
                  }
                  Node parent = node.getParentNode();
                  if (parent.getNodeType() == Node.ELEMENT_NODE)
                  {
                    listener.elementContentsChanged((Element)parent);
                  }
                  deletionNode = null;
                }
              }
              else
              {
                XSDConcreteComponent listener = getCorrespondingComponent(node);
                if (listener != null)
                {
                  listener.elementAttributesChanged((Element)node);
                }
              }
            }
          }
        }

        public Object writeReplace()
        {
          return new DummyEventListener();
        }
      }
      eventListener = new XSDSchemaEventListener();
    }
    return eventListener;
  }

  public Document updateDocument()
  {
    document = XSDParser.createDocument(); 
    return document;
  }

  protected boolean isIncrementalUpdate = true;

  public void setIncrementalUpdate(boolean isIncrementalUpdate)
  {
    this.isIncrementalUpdate = isIncrementalUpdate;
    traverseToRootForPatching();
  }

  public boolean isIncrementalUpdate()
  {
    return isIncrementalUpdate;
  }

  public void update()
  {
    boolean oldIsIncrementalUpdate = isIncrementalUpdate;
    isIncrementalUpdate = true;
    traverseToRootForPatching();
    isIncrementalUpdate = oldIsIncrementalUpdate;
  }

  public void update(boolean force)
  {
    forceResolve = force;
    update();
    forceResolve = false;
  }

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

    redefinitionMap.clear();

    reset(getAttributeDeclarations());
    reset(getAttributeGroupDefinitions());
    reset(getElementDeclarations());
    reset(getModelGroupDefinitions());
    reset(getTypeDefinitions());
    reset(getNotationDeclarations());
    reset(getIdentityConstraintDefinitions());

    forceResolve = true;
    update();
    forceResolve = false;
  }

  protected void reset(List<? extends XSDConcreteComponent> components)
  {
    for (Iterator<? extends XSDConcreteComponent> i = components.iterator(); i.hasNext(); )
    {
      XSDConcreteComponent xsdConcreteComponent = i.next();
      if (xsdConcreteComponent.getSchema() != this)
      {
        i.remove();
      }
    }
  }

  protected String pendingSchemaLocation;
  public String getPendingSchemaLocation()
  {
    return pendingSchemaLocation;
  }

  protected List<XSDSchemaImpl> schemasToRedefine;
  public List<XSDSchemaImpl> getSchemasToRedefine()
  {
    if (schemasToRedefine == null)
    {
      schemasToRedefine = new UniqueEList<XSDSchemaImpl>();
      schemasToRedefine.add(this);
    }
    return schemasToRedefine;
  }

  protected Map<XSDComponent, XSDComponent> redefinitionMap = new HashMap<XSDComponent, XSDComponent>();
  public Map<XSDComponent, XSDComponent> getRedefinitionMap()
  {
    return redefinitionMap;
  }

  public XSDSchema imported(XSDImport xsdImport)
  {
    xsdImport.setResolvedSchema(this);
    getReferencingDirectives().add(xsdImport);
    propogateComponents(xsdImport.getSchema());

    return this;
  }

  public void propogateComponents(XSDSchema otherXSDSchema)
  {
    otherXSDSchema.getAnnotations().addAll(getAnnotations());

    XSDNamedComponentImpl.mergeToSortedList
      (otherXSDSchema.getAttributeDeclarations(), getAttributeDeclarations());
    XSDNamedComponentImpl.mergeToSortedList
      (otherXSDSchema.getAttributeGroupDefinitions(), getAttributeGroupDefinitions());
    XSDNamedComponentImpl.mergeToSortedList
      (otherXSDSchema.getElementDeclarations(), getElementDeclarations());
    XSDNamedComponentImpl.mergeToSortedList
      (otherXSDSchema.getModelGroupDefinitions(), getModelGroupDefinitions());
    XSDNamedComponentImpl.mergeToSortedList
      (otherXSDSchema.getTypeDefinitions(), getTypeDefinitions());
    XSDNamedComponentImpl.mergeToSortedList
      (otherXSDSchema.getNotationDeclarations(), getNotationDeclarations());
    XSDNamedComponentImpl.mergeToSortedList
      (otherXSDSchema.getIdentityConstraintDefinitions(), getIdentityConstraintDefinitions());
  }

  public XSDSchema redefined(XSDRedefine xsdRedefine)
  {
    XSDSchema redefiningSchema = xsdRedefine.getSchema();
    xsdRedefine.setResolvedSchema(this);
    getReferencingDirectives().add(xsdRedefine);
    if (redefiningSchema != this &&
          (getTargetNamespace() == null || getTargetNamespace().equals(redefiningSchema.getTargetNamespace())))
    {
      for (XSDSchema incorporatedVersion : getIncorporatedVersions())
      {
        if (incorporatedVersion.getTargetNamespace() == null ? 
              redefiningSchema.getTargetNamespace() == null :
              incorporatedVersion.getTargetNamespace().equals(redefiningSchema.getTargetNamespace()))
        {
          for (ListIterator<XSDSchemaDirective> i = incorporatedVersion.getReferencingDirectives().listIterator(); i.hasNext(); )
          {
            XSDSchemaDirective xsdSchemaDirective = i.next();
            // This was commented out to fix 72109, i.e., to prevent stack overflow.
            // There really does need to be some kind of guard here in the general case.
            // But it's very challenging to fix this, so it's better to not overflow 
            // and to have some other unreported corner case be wrong.
            // Returning a previous results in the same thing being redefined multiple times, which is also no good.
            // I'll add a guard to avoid overflow.
            if (xsdRedefine.getSchema() == xsdSchemaDirective.getSchema() || getIncorporatedVersions().size() > 10)
            {
              ((XSDSchemaImpl)incorporatedVersion).incorporate(xsdRedefine);
              return incorporatedVersion;
            }
          }
        }
      }

      XSDSchemaImpl redefinedSchema = (XSDSchemaImpl)cloneConcreteComponent(true, true);

      if (redefinedSchema.getTargetNamespace() == null && redefiningSchema.getTargetNamespace() != null)
      {
        redefinedSchema.patch();
        redefinedSchema.setTargetNamespace(redefiningSchema.getTargetNamespace());
        redefinedSchema.patch();
      }

      // Change includes to redefines so that clones are created.
      //
      for (ListIterator<XSDSchemaContent> i = redefinedSchema.getContents().listIterator(); i.hasNext(); )
      {
        Object component = i.next();
        if (component instanceof XSDInclude)
        {
          redefinedSchema.isReconciling = true;
          i.remove();
          XSDRedefine xsdRedefineReplaced = XSDFactory.eINSTANCE.createXSDRedefine();
          xsdRedefineReplaced.setSchemaLocation(((XSDInclude)component).getSchemaLocation());
          i.add(xsdRedefineReplaced);
          redefinedSchema.isReconciling = false;
        }
      }

      redefinedSchema.pendingSchemaLocation = getSchemaLocation();
      getIncorporatedVersions().add(redefinedSchema);
      redefinedSchema.incorporate(xsdRedefine);
      return redefinedSchema;
    }

    return this;
  }

  public XSDSchema included(XSDInclude xsdInclude)
  {
    XSDSchema includingSchema = xsdInclude.getSchema();
    xsdInclude.setResolvedSchema(this);
    getReferencingDirectives().add(xsdInclude);
    if (getTargetNamespace() == null || getTargetNamespace().equals(includingSchema.getTargetNamespace()))
    {
      if (includingSchema.getTargetNamespace() != null && getTargetNamespace() == null)
      {
        for (XSDSchema xsdSchema : getIncorporatedVersions())
        {
          XSDSchemaImpl incorporatedVersion = (XSDSchemaImpl)xsdSchema;
          if (includingSchema.getTargetNamespace().equals(incorporatedVersion.getTargetNamespace()))
          {
            if (incorporatedVersion.getReferencingDirectives().isEmpty())
            {
              incorporatedVersion.incorporate(xsdInclude);
              return incorporatedVersion;
            }
            for (XSDSchemaDirective xsdSchemaDirective : incorporatedVersion.getReferencingDirectives())
            {
              if (xsdSchemaDirective instanceof XSDInclude)
              {
                incorporatedVersion.incorporate(xsdInclude);
                return incorporatedVersion;
              }
            }
          }
        }
        XSDSchemaImpl includedSchema = (XSDSchemaImpl)cloneConcreteComponent(true, true);
        includedSchema.patch();
        includedSchema.setTargetNamespace(includingSchema.getTargetNamespace());
        includedSchema.patch();
        getIncorporatedVersions().add(includedSchema);
        includedSchema.incorporate(xsdInclude);
        return includedSchema;
      }
      else
      {
        incorporate(xsdInclude);
      }
    }
    return this;
  }

  protected void incorporate(XSDSchemaCompositor xsdSchemaCompositor)
  {
    xsdSchemaCompositor.setIncorporatedSchema(this);
    XSDSchema redefiningSchema = xsdSchemaCompositor.getSchema();
    getReferencingDirectives().add(xsdSchemaCompositor);

    if (getTargetNamespace() == null && redefiningSchema.getTargetNamespace() != null)
    {
      setTargetNamespace(redefiningSchema.getTargetNamespace());
    }

    if (getPendingSchemaLocation() != null)
    {
      for (Object component : getContents())
      {
        if (component instanceof XSDSchemaDirective)
        {
          ((XSDConcreteComponentImpl)component).patch();
        }
      }
    }

    if (xsdSchemaCompositor instanceof XSDRedefine)
    {
      XSDSwitch<Object> xsdSwitch =
        new XSDSwitch<Object>()
        {
          @Override
          public Object caseXSDAttributeGroupDefinition(XSDAttributeGroupDefinition xsdAttributeGroupDefinition)
          {
            XSDAttributeGroupDefinition redefinedAttributeGroupDefinition = 
              resolveAttributeGroupDefinition(xsdAttributeGroupDefinition.getName());
            for (XSDSchemaImpl schemaToRedefine : getSchemasToRedefine())
            {
              int index = schemaToRedefine.getAttributeGroupDefinitions().indexOf(redefinedAttributeGroupDefinition);
              if (index != -1)
              {
                schemaToRedefine.getAttributeGroupDefinitions().set(index, xsdAttributeGroupDefinition);
                schemaToRedefine.redefinitionMap.put(xsdAttributeGroupDefinition, redefinedAttributeGroupDefinition);
              }
            }
            return this;
          }
          @Override
          public Object caseXSDSimpleTypeDefinition(XSDSimpleTypeDefinition xsdSimpleTypeDefinition)
          {
            XSDSimpleTypeDefinition redefinedSimpleTypeDefinition = 
              resolveSimpleTypeDefinition(xsdSimpleTypeDefinition.getName());
            for (XSDSchemaImpl schemaToRedefine : getSchemasToRedefine())
            {
              int index = schemaToRedefine.getTypeDefinitions().indexOf(redefinedSimpleTypeDefinition);
              if (index != -1)
              {
                schemaToRedefine.getTypeDefinitions().set(index, xsdSimpleTypeDefinition);
                schemaToRedefine.redefinitionMap.put(xsdSimpleTypeDefinition, redefinedSimpleTypeDefinition);
              }
            }
            return this;
          }
          @Override
          public Object caseXSDComplexTypeDefinition(XSDComplexTypeDefinition xsdComplexTypeDefinition)
          {
            XSDComplexTypeDefinition redefinedComplexTypeDefinition = 
              resolveComplexTypeDefinition(xsdComplexTypeDefinition.getName());
            if (xsdComplexTypeDefinition != redefinedComplexTypeDefinition)
            {
              for (XSDSchemaImpl schemaToRedefine : getSchemasToRedefine())
              {
                int index = schemaToRedefine.getTypeDefinitions().indexOf(redefinedComplexTypeDefinition);
                if (index != -1)
                {
                  schemaToRedefine.getTypeDefinitions().set(index, xsdComplexTypeDefinition);
                  schemaToRedefine.redefinitionMap.put(xsdComplexTypeDefinition, redefinedComplexTypeDefinition);
                }
              }
            }
            return this;
          }
          @Override
          public Object caseXSDModelGroupDefinition(XSDModelGroupDefinition xsdModelGroupDefinition)
          {
            XSDModelGroupDefinition redefinedModelGroupDefinition = 
              resolveModelGroupDefinition(xsdModelGroupDefinition.getName());
            for (XSDSchemaImpl schemaToRedefine : getSchemasToRedefine())
            {
              int index = schemaToRedefine.getModelGroupDefinitions().indexOf(redefinedModelGroupDefinition);
              if (index != -1)
              {
                schemaToRedefine.getModelGroupDefinitions().set(index, xsdModelGroupDefinition);
                schemaToRedefine.redefinitionMap.put(xsdModelGroupDefinition, redefinedModelGroupDefinition);
              }
            }
            return this;
          }
        };

      for (XSDRedefineContent xsdRedefineContent : ((XSDRedefine)xsdSchemaCompositor).getContents())
      {
        xsdSwitch.doSwitch(xsdRedefineContent);
      }
    }

    if (((XSDSchemaImpl)redefiningSchema).getPendingSchemaLocation() != null)
    {
      ((XSDSchemaImpl)redefiningSchema).getSchemasToRedefine().addAll(getSchemasToRedefine());
    }

    propogateComponents(redefiningSchema);

    if (getPendingSchemaLocation() == null)
    {
      patch();
    }

    ((XSDSchemaImpl)redefiningSchema).getRedefinitionMap().putAll(getRedefinitionMap());
  }

  @Override
  public XSDConcreteComponent cloneConcreteComponent(boolean deep, boolean shareDOM)
  {
    XSDSchemaImpl clonedSchema = (XSDSchemaImpl)getXSDFactory().createXSDSchema();
    clonedSchema.isReconciling = true;

    clonedSchema.setTargetNamespace(getTargetNamespace());

    if (isSetAttributeFormDefault())
    {
      clonedSchema.setAttributeFormDefault(getAttributeFormDefault());
    }
    if (isSetElementFormDefault())
    {
      clonedSchema.setElementFormDefault(getElementFormDefault());
    }
    if (isSetFinalDefault())
    {
      if (!getFinalDefault().isEmpty())
      {
        clonedSchema.getFinalDefault().addAll(getFinalDefault());
      }
      else
      {
        clonedSchema.getFinalDefault().clear();
      }
    }
    if (isSetBlockDefault())
    {
      if (!getBlockDefault().isEmpty())
      {
        clonedSchema.getBlockDefault().addAll(getBlockDefault());
      }
      else
      {
        clonedSchema.getBlockDefault().clear();
      }
    }

    // clonedSchema.setSchemaLocation(getSchemaLocation());

    clonedSchema.setSchemaForSchemaQNamePrefix(getSchemaForSchemaQNamePrefix());
    clonedSchema.getQNamePrefixToNamespaceMap().putAll(getQNamePrefixToNamespaceMap());

    if (deep)
    {
      if (!getContents().isEmpty())
      {
        clonedSchema.getContents().addAll(cloneConcreteComponents(getContents(), true, shareDOM));
      }
    }

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

    clonedSchema.isReconciling = shareDOM;
    return clonedSchema;
  }
}
