/**
 * Copyright (c) 2005-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.ecore;


import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xml.namespace.XMLNamespacePackage;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDAttributeUseCategory;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDComponent;
import org.eclipse.xsd.XSDCompositor;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDConstraint;
import org.eclipse.xsd.XSDDerivationMethod;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDEnumerationFacet;
import org.eclipse.xsd.XSDFacet;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDFeature;
import org.eclipse.xsd.XSDForm;
import org.eclipse.xsd.XSDFractionDigitsFacet;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDLengthFacet;
import org.eclipse.xsd.XSDMaxExclusiveFacet;
import org.eclipse.xsd.XSDMaxInclusiveFacet;
import org.eclipse.xsd.XSDMaxLengthFacet;
import org.eclipse.xsd.XSDMinExclusiveFacet;
import org.eclipse.xsd.XSDMinInclusiveFacet;
import org.eclipse.xsd.XSDMinLengthFacet;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDPatternFacet;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTotalDigitsFacet;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.XSDWhiteSpace;
import org.eclipse.xsd.XSDWhiteSpaceFacet;
import org.eclipse.xsd.XSDWildcard;
import org.eclipse.xsd.util.XSDConstants;
import org.eclipse.xsd.util.XSDParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
 * This class produces an XSDSchema given an Ecore EPackage.
 */
public class EcoreSchemaBuilder extends MapBuilder
{
  /**
   * The schema for schema namespace version to be used for new schemas.
   */
  protected String defaultXMLSchemaNamespace = XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001;

  /**
   * The prefix to be used for the schema for schema namespace version in new schemas.
   */
  protected String defaultXMLSchemaNamespacePrefix = "xsd";

  /**
   * The extended meta data used to determine the schema structure.
   */
  protected ExtendedMetaData extendedMetaData;

  /**
   * Store the reverse map too.
   */
  protected Map<EModelElement, XSDComponent> eModelElementToXSDComponentMap = new HashMap<EModelElement, XSDComponent>();

  public EcoreSchemaBuilder(ExtendedMetaData extendedMetaData)
  {
    this.extendedMetaData = extendedMetaData;
  }

  @Override
  protected void map(XSDComponent xsdComponent, EModelElement eModelElement)
  {
    super.map(xsdComponent, eModelElement);

    // Store the reverse map as well.
    //
    eModelElementToXSDComponentMap.put(eModelElement, xsdComponent);
  }

  /*
  public Collection generate(EPackage ePackage)
  {
    XSDSchema xsdSchema = getSchema(ePackage);

    Collection result = new ArrayList();
    result.add(xsdSchema);
    if (mapper != null)
    {
      result.add(mapper.getRoot());
    }

    return result;
  }
  */

  public XSDSchema getSchema(EPackage ePackage)
  {
    XSDSchema xsdSchema = (XSDSchema)eModelElementToXSDComponentMap.get(ePackage);
    if (xsdSchema == null)
    {
      xsdSchema = buildSchema(ePackage);
    }
    return xsdSchema;
  }

  protected String getQualifiedPackageName(EPackage ePackage)
  {
    return ePackage.getName();
  }

  protected XSDSchema buildSchema(EPackage ePackage)
  {
    XSDSchema xsdSchema = XSDFactory.eINSTANCE.createXSDSchema();

    addInput(ePackage);
    addOutput(xsdSchema);
    map(xsdSchema, ePackage);

    // Set the namespace.
    //
    String targetNamespace = extendedMetaData.getNamespace(ePackage);
    xsdSchema.setTargetNamespace(targetNamespace);

    // Choose the schema for schema namespace and prefix.
    //
    Map<String, String> namespaces = xsdSchema.getQNamePrefixToNamespaceMap();
    xsdSchema.setSchemaForSchemaQNamePrefix(defaultXMLSchemaNamespacePrefix);
    namespaces.put(defaultXMLSchemaNamespacePrefix, defaultXMLSchemaNamespace);

    // Ensure that a prefix is assigned for the target namespace.
    //
    handlePrefix(namespaces, ePackage.getNsPrefix(), targetNamespace);

    // Create the node so that annotations can be added to the DOM.
    //
    xsdSchema.updateElement();

    buildAnnotations(xsdSchema, ePackage);

    // Remember the package name and prefix.
    //
    createEcoreAnnotation(xsdSchema, "package", getQualifiedPackageName(ePackage));
    createEcoreAnnotation(xsdSchema, "nsPrefix", ePackage.getNsPrefix());

    // Generate the global elements and attributes.
    //
    EClass documentRootEClass = extendedMetaData.getDocumentRoot(ePackage);
    if (documentRootEClass == null)
    {
      for (EClassifier eClassifier : ePackage.getEClassifiers())
      {
        if (eClassifier instanceof EClass)
        {
          EClass eClass = (EClass)eClassifier;
          if (extendedMetaData.getContentKind(eClass) == ExtendedMetaData.UNSPECIFIED_CONTENT)
          {
            buildGlobalElement(xsdSchema, eClass);
          }
        }
      }
    }
    else
    {
      if (!"DocumentRoot".equals(documentRootEClass.getName()))
      {
        createEcoreAnnotation(xsdSchema, "documentRoot", documentRootEClass.getName());
      }

      for (int i = 0, size = documentRootEClass.getFeatureCount(); i < size; ++i)
      {
        EStructuralFeature eStructuralFeature = documentRootEClass.getEStructuralFeature(i);
        if (extendedMetaData.getName(eStructuralFeature).indexOf(':') == -1)
        {
          buildGlobalFeature(xsdSchema, eStructuralFeature);
        }
      }
    }

    // Generate the type definitions.
    //
    for (EClassifier eClassifier : ePackage.getEClassifiers())
    {
      if (eClassifier != documentRootEClass)
      {
        buildTypeDefinition(xsdSchema, eClassifier);
      }
    }

    return xsdSchema;
  }

  protected XSDElementDeclaration buildGlobalElement(XSDSchema xsdSchema, EClass eClass)
  {
    XSDElementDeclaration xsdElementDeclaration = XSDFactory.eINSTANCE.createXSDElementDeclaration();
    xsdElementDeclaration.setName(extendedMetaData.getName(eClass));

    XSDTypeDefinition xsdTypeDefinition = xsdSchema.resolveTypeDefinitionURI(getURI(eClass));
    handleImport(xsdSchema, xsdTypeDefinition);
    xsdElementDeclaration.setTypeDefinition(xsdTypeDefinition);

    xsdSchema.getContents().add(xsdElementDeclaration);
    map(xsdElementDeclaration, eClass);

    createEcoreAnnotation(xsdElementDeclaration, "ignore", "true");

    return xsdElementDeclaration;
  }

  protected XSDFeature buildGlobalFeature(XSDSchema xsdSchema, EStructuralFeature eStructuralFeature)
  {
    switch (extendedMetaData.getFeatureKind(eStructuralFeature))
    {
      case ExtendedMetaData.ELEMENT_FEATURE:
      {
        XSDElementDeclaration xsdElementDeclaration = buildGlobalElement(xsdSchema, eStructuralFeature);
        return xsdElementDeclaration;
      }
      case ExtendedMetaData.ATTRIBUTE_FEATURE:
      {
        XSDAttributeDeclaration xsdAttributeDeclaration = buildGlobalAttribute(xsdSchema, eStructuralFeature);
        return xsdAttributeDeclaration;
      }
      case ExtendedMetaData.ELEMENT_WILDCARD_FEATURE:
      case ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE:
      case ExtendedMetaData.SIMPLE_FEATURE:
      case ExtendedMetaData.GROUP_FEATURE:
      default:
      {
        return null;
      }
    }
  }

  /**
   * Handle difference lexical representations for default values,
   * in particular, positive and negative infinity for float and double.
   * @since 2.8
   */
  protected String transformDefaultValue(XSDSimpleTypeDefinition xsdSimpleTypeDefinition, String defaultValue)
  {
    XSDSimpleTypeDefinition primitiveTypeDefinition = xsdSimpleTypeDefinition.getPrimitiveTypeDefinition();
    if (primitiveTypeDefinition != null && 
          (primitiveTypeDefinition.hasNameAndTargetNamespace("float", defaultXMLSchemaNamespace) ||
             primitiveTypeDefinition.hasNameAndTargetNamespace("double", defaultXMLSchemaNamespace)))
    {
      if ("Infinity".equals(defaultValue))
      {
        return "INF";
      }
      else if ("-Infinity".equals(defaultValue))
      {
        return "-INF";
      }
    }
    return defaultValue;
  }

  protected XSDElementDeclaration buildGlobalElement(XSDSchema xsdSchema, EStructuralFeature eStructuralFeature)
  {
    XSDElementDeclaration xsdElementDeclaration = XSDFactory.eINSTANCE.createXSDElementDeclaration();
    xsdElementDeclaration.setName(extendedMetaData.getName(eStructuralFeature));

    if (!eStructuralFeature.isChangeable())
    {
      xsdElementDeclaration.setAbstract(true);
    }

    EStructuralFeature affiliation = extendedMetaData.getAffiliation(eStructuralFeature);
    if (affiliation != null)
    {
      XSDElementDeclaration xsdAffiliation = xsdSchema.resolveElementDeclarationURI(getURI(affiliation));
      handleImport(xsdSchema, xsdAffiliation);
      xsdElementDeclaration.setSubstitutionGroupAffiliation(xsdAffiliation);
    }

    EClassifier eType = eStructuralFeature.getEType();
    XSDTypeDefinition xsdTypeDefinition = xsdSchema.resolveTypeDefinitionURI(getURI(eType));
    handleImport(xsdSchema, xsdTypeDefinition);
    xsdElementDeclaration.setTypeDefinition(xsdTypeDefinition);

    if (isWrapperType(eType))
    {
      xsdElementDeclaration.setNillable(true);
    }

    String defaultValue = eStructuralFeature.getDefaultValueLiteral();
    if (defaultValue != null)
    {
      xsdElementDeclaration.setConstraint(XSDConstraint.DEFAULT_LITERAL);
      xsdElementDeclaration.setLexicalValue(transformDefaultValue((XSDSimpleTypeDefinition)xsdElementDeclaration.getTypeDefinition(), defaultValue));
    }

    xsdSchema.getContents().add(xsdElementDeclaration);
    map(xsdElementDeclaration, eStructuralFeature);

    if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE))
    {
      createEcoreAnnotation(xsdElementDeclaration, "type", getGenericType(xsdSchema, eStructuralFeature.getEGenericType()));
    }

    buildAnnotations(xsdElementDeclaration, eStructuralFeature);

    return xsdElementDeclaration;
  }

  protected XSDAttributeDeclaration buildGlobalAttribute(XSDSchema xsdSchema, EStructuralFeature eStructuralFeature)
  {
    XSDAttributeDeclaration xsdAttributeDeclaration = XSDFactory.eINSTANCE.createXSDAttributeDeclaration();
    xsdAttributeDeclaration.setName(extendedMetaData.getName(eStructuralFeature));

    XSDSimpleTypeDefinition xsdSimpleTypeDefinition = xsdSchema.resolveSimpleTypeDefinitionURI(getURI(eStructuralFeature.getEType()));
    handleImport(xsdSchema, xsdSimpleTypeDefinition);
    xsdAttributeDeclaration.setTypeDefinition(xsdSimpleTypeDefinition);

    String defaultValue = eStructuralFeature.getDefaultValueLiteral();
    if (defaultValue != null)
    {
      xsdAttributeDeclaration.setConstraint(XSDConstraint.DEFAULT_LITERAL);
      xsdAttributeDeclaration.setLexicalValue(transformDefaultValue(xsdAttributeDeclaration.getTypeDefinition(), defaultValue));
    }

    xsdSchema.getContents().add(xsdAttributeDeclaration);
    map(xsdAttributeDeclaration, eStructuralFeature);

    if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE))
    {
      createEcoreAnnotation(xsdAttributeDeclaration, "type", getGenericType(xsdSchema, eStructuralFeature.getEGenericType()));
    }

    buildAnnotations(xsdAttributeDeclaration, eStructuralFeature);

    return xsdAttributeDeclaration;
  }

  protected XSDTypeDefinition buildTypeDefinition(XSDSchema xsdSchema, EClassifier eClassifier)
  {
    if (eClassifier instanceof EClass)
    {
      return buildComplexTypeDefinition(xsdSchema, (EClass)eClassifier);
    }
    else
    {
      return buildSimpleTypeDefinition(xsdSchema, (EDataType)eClassifier);
    }
  }

  protected XSDSimpleTypeDefinition buildSimpleTypeDefinition(XSDSchema xsdSchema, EDataType eDataType)
  {
    String name = extendedMetaData.getName(eDataType);
    boolean isAnonymousWrapperType =  name.endsWith(":Object");
    if (isAnonymousWrapperType && EcorePackage.eNS_URI.equals(xsdSchema.getTargetNamespace()))
    {
      name = eDataType.getName();
      isAnonymousWrapperType = false;
    }
    if (!isAnonymousWrapperType)
    {
      XSDSimpleTypeDefinition xsdSimpleTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition();

      xsdSimpleTypeDefinition.setName(name);

      String instanceClass = null;
      EDataType baseType = extendedMetaData.getBaseType(eDataType);
      if (baseType != null)
      {
        XSDSimpleTypeDefinition baseTypeDefinition =  xsdSchema.resolveSimpleTypeDefinitionURI(getURI(baseType));
        handleImport(xsdSchema, baseTypeDefinition);
        xsdSimpleTypeDefinition.setBaseTypeDefinition(baseTypeDefinition);

        // Produce an instance class declaration if the type is different from that of the base.
        //
        instanceClass = eDataType.getInstanceTypeName();
        if (instanceClass != null && instanceClass.equals(baseType.getInstanceTypeName()))
        {
          instanceClass = null;
        }
      }
      else
      {
        EDataType itemType = extendedMetaData.getItemType(eDataType);
        if (itemType != null)
        {
          XSDSimpleTypeDefinition itemTypeDefinition =  xsdSchema.resolveSimpleTypeDefinitionURI(getURI(itemType));
          handleImport(xsdSchema, itemTypeDefinition);
          xsdSimpleTypeDefinition.setItemTypeDefinition(itemTypeDefinition);
        }
        else
        {
          List<EDataType> memberTypes = extendedMetaData.getMemberTypes(eDataType);
          if (!memberTypes.isEmpty())
          {
            for (EDataType memberType : memberTypes)
            {
              XSDSimpleTypeDefinition memberTypeDefinition =  xsdSchema.resolveSimpleTypeDefinitionURI(getURI(memberType));
              handleImport(xsdSchema, memberTypeDefinition);
              xsdSimpleTypeDefinition.getMemberTypeDefinitions().add(memberTypeDefinition);
            }
          }
          else
          {
            xsdSimpleTypeDefinition.setBaseTypeDefinition(xsdSchema.getSchemaForSchema().resolveSimpleTypeDefinition("string"));
            if (!(eDataType instanceof EEnum))
            {
              instanceClass = eDataType.getInstanceTypeName();
            }
          }
        }
      }

      xsdSchema.getContents().add(xsdSimpleTypeDefinition);
      map(xsdSimpleTypeDefinition, eDataType);

      buildTypeParameters(xsdSimpleTypeDefinition, eDataType.getETypeParameters());

      if (instanceClass != null)
      {
        createEcoreAnnotation(xsdSimpleTypeDefinition, "instanceClass", instanceClass.replace('<', '{').replace('>', '}'));
      }

      String minInclusive = extendedMetaData.getMinInclusiveFacet(eDataType);
      if (minInclusive != null)
      {
        XSDMinInclusiveFacet xsdMinInclusiveFacet = XSDFactory.eINSTANCE.createXSDMinInclusiveFacet();
        xsdMinInclusiveFacet.setLexicalValue(minInclusive);
        xsdSimpleTypeDefinition.getFacetContents().add(xsdMinInclusiveFacet);
      }

      String maxInclusive = extendedMetaData.getMaxInclusiveFacet(eDataType);
      if (maxInclusive != null)
      {
        XSDMaxInclusiveFacet xsdMaxInclusiveFacet = XSDFactory.eINSTANCE.createXSDMaxInclusiveFacet();
        xsdMaxInclusiveFacet.setLexicalValue(maxInclusive);
        xsdSimpleTypeDefinition.getFacetContents().add(xsdMaxInclusiveFacet);
      }

      String minExclusive = extendedMetaData.getMinExclusiveFacet(eDataType);
      if (minExclusive != null)
      {
        XSDMinExclusiveFacet xsdMinExclusiveFacet = XSDFactory.eINSTANCE.createXSDMinExclusiveFacet();
        xsdMinExclusiveFacet.setLexicalValue(minExclusive);
        xsdSimpleTypeDefinition.getFacetContents().add(xsdMinExclusiveFacet);
      }

      String maxExclusive = extendedMetaData.getMaxExclusiveFacet(eDataType);
      if (maxExclusive != null)
      {
        XSDMaxExclusiveFacet xsdMaxExclusiveFacet = XSDFactory.eINSTANCE.createXSDMaxExclusiveFacet();
        xsdMaxExclusiveFacet.setLexicalValue(maxExclusive);
        xsdSimpleTypeDefinition.getFacetContents().add(xsdMaxExclusiveFacet);
      }

      int length = extendedMetaData.getLengthFacet(eDataType);
      if (length != -1)
      {
        XSDLengthFacet xsdLengthFacet = XSDFactory.eINSTANCE.createXSDLengthFacet();
        xsdLengthFacet.setLexicalValue(Integer.toString(length));
        xsdSimpleTypeDefinition.getFacetContents().add(xsdLengthFacet);
      }

      int maxLength = extendedMetaData.getMaxLengthFacet(eDataType);
      if (maxLength != -1)
      {
        XSDMaxLengthFacet xsdMaxLengthFacet = XSDFactory.eINSTANCE.createXSDMaxLengthFacet();
        xsdMaxLengthFacet.setLexicalValue(Integer.toString(maxLength));
        xsdSimpleTypeDefinition.getFacetContents().add(xsdMaxLengthFacet);
      }

      int minLength = extendedMetaData.getMinLengthFacet(eDataType);
      if (minLength != -1)
      {
        XSDMinLengthFacet xsdMinLengthFacet = XSDFactory.eINSTANCE.createXSDMinLengthFacet();
        xsdMinLengthFacet.setLexicalValue(Integer.toString(minLength));
        xsdSimpleTypeDefinition.getFacetContents().add(xsdMinLengthFacet);
      }

      int totalDigits = extendedMetaData.getTotalDigitsFacet(eDataType);
      if (totalDigits != -1)
      {
        XSDTotalDigitsFacet xsdTotalDigitsFacet = XSDFactory.eINSTANCE.createXSDTotalDigitsFacet();
        xsdTotalDigitsFacet.setLexicalValue(Integer.toString(totalDigits));
        xsdSimpleTypeDefinition.getFacetContents().add(xsdTotalDigitsFacet);
      }

      int fractionDigits = extendedMetaData.getFractionDigitsFacet(eDataType);
      if (fractionDigits != -1)
      {
        XSDFractionDigitsFacet xsdFractionDigitsFacet = XSDFactory.eINSTANCE.createXSDFractionDigitsFacet();
        xsdFractionDigitsFacet.setLexicalValue(Integer.toString(fractionDigits));
        xsdSimpleTypeDefinition.getFacetContents().add(xsdFractionDigitsFacet);
      }

      int whiteSpace = extendedMetaData.getWhiteSpaceFacet(eDataType);
      if (whiteSpace != ExtendedMetaData.UNSPECIFIED_WHITE_SPACE)
      {
        XSDWhiteSpaceFacet xsdWhiteSpaceFacet = XSDFactory.eINSTANCE.createXSDWhiteSpaceFacet();
        xsdWhiteSpaceFacet.setLexicalValue(XSDWhiteSpace.get(whiteSpace - 1).toString());
        xsdSimpleTypeDefinition.getFacetContents().add(xsdWhiteSpaceFacet);
      }

      for (String pattern : extendedMetaData.getPatternFacet(eDataType))
      {
        XSDPatternFacet xsdPatternFacet = XSDFactory.eINSTANCE.createXSDPatternFacet();
        xsdPatternFacet.setLexicalValue(pattern);
        xsdSimpleTypeDefinition.getFacetContents().add(xsdPatternFacet);
      }

      for (String enumeration : extendedMetaData.getEnumerationFacet(eDataType))
      {
        XSDEnumerationFacet xsdEnumerationFacet = XSDFactory.eINSTANCE.createXSDEnumerationFacet();
        xsdEnumerationFacet.setLexicalValue(enumeration);
        xsdSimpleTypeDefinition.getFacetContents().add(xsdEnumerationFacet);
      }

      String ecoreName = eDataType.getName();
      if (!name.equals(ecoreName) || Character.isLowerCase(ecoreName.charAt(0)) || ecoreName.indexOf('_') != -1)
      {
        createEcoreAnnotation(xsdSimpleTypeDefinition, "name", ecoreName);
      }

      String constraints = EcoreUtil.getAnnotation(eDataType, EcorePackage.eNS_URI, "constraints");
      if (constraints != null)
      {
        createEcoreAnnotation(xsdSimpleTypeDefinition, "constraints", constraints);
      }

      if (!eDataType.isSerializable())
      {
        createEcoreAnnotation(xsdSimpleTypeDefinition, "serializable", "false");
      }

      if (eDataType instanceof EEnum)
      {
        EEnum eEnum = (EEnum)eDataType;

        for (ListIterator<EEnumLiteral> literals = eEnum.getELiterals().listIterator(); literals.hasNext();)
        {
          EEnumLiteral literal = literals.next();
          XSDEnumerationFacet facet = XSDFactory.eINSTANCE.createXSDEnumerationFacet();
          facet.setLexicalValue(literal.getLiteral());
          xsdSimpleTypeDefinition.getFacetContents().add(facet);
          map(facet, literal);

          if (!literal.getLiteral().equals(literal.getName()))
          {
            createEcoreAnnotation(facet, "name", literal.getName());
          }

          if (literal.getValue() != literals.previousIndex())
          {
            createEcoreAnnotation(facet, "value", Integer.toString(literal.getValue()));
          }

          buildAnnotations(facet, literal);
        }
      }

      buildAnnotations(xsdSimpleTypeDefinition, eDataType);

      return xsdSimpleTypeDefinition;
    }
    else
    {
      return null;
    }
  }

  protected XSDComplexTypeDefinition buildComplexTypeDefinition(XSDSchema xsdSchema, EClass eClass)
  {
    XSDComplexTypeDefinition xsdComplexTypeDefinition = XSDFactory.eINSTANCE.createXSDComplexTypeDefinition();

    String name = extendedMetaData.getName(eClass);
    xsdComplexTypeDefinition.setName(name);

    if (eClass.isAbstract())
    {
      xsdComplexTypeDefinition.setAbstract(true);
    }

    List<EGenericType> genericTypeTypes = eClass.getEGenericSuperTypes();
    if (!genericTypeTypes.isEmpty())
    {
      Iterator<EGenericType> i = genericTypeTypes.iterator();
      EGenericType genericSuperType = i.next();
      XSDTypeDefinition baseType = xsdSchema.resolveTypeDefinitionURI(getURI(genericSuperType.getERawType()));
      if (!XSDConstants.isURType(baseType))
      {
        handleImport(xsdSchema, baseType);
        xsdComplexTypeDefinition.setDerivationMethod(XSDDerivationMethod.EXTENSION_LITERAL);
        xsdComplexTypeDefinition.setBaseTypeDefinition(baseType);
      }
  
      xsdSchema.getContents().add(xsdComplexTypeDefinition);
  
      if (!genericSuperType.getETypeArguments().isEmpty())
      {
        createEcoreAnnotation(xsdComplexTypeDefinition, "extends", getGenericType(xsdSchema, genericSuperType));
      }

      if (i.hasNext())
      {
        StringBuilder additionalSuperTypes = new StringBuilder();
        do
        {
          additionalSuperTypes.append(getGenericType(xsdSchema, i.next()));
          additionalSuperTypes.append(' ');
        }
        while (i.hasNext());
        createEcoreAnnotation(xsdComplexTypeDefinition, "implements", additionalSuperTypes.toString().trim());
      }
    }
    else
    {
      xsdSchema.getContents().add(xsdComplexTypeDefinition);
    }

    buildTypeParameters(xsdComplexTypeDefinition, eClass.getETypeParameters());

    map(xsdComplexTypeDefinition, eClass);

    String instanceClass =  eClass.getInstanceTypeName();
    if (instanceClass != null)
    {
      createEcoreAnnotation(xsdComplexTypeDefinition, "instanceClass", instanceClass.replace('<', '{').replace('>', '}'));
    }

    String ecoreName = eClass.getName();
    if (!name.equals(ecoreName) || Character.isLowerCase(ecoreName.charAt(0)) || ecoreName.indexOf('_') != -1)
    {
      createEcoreAnnotation(xsdComplexTypeDefinition, "name", ecoreName);
    }

    if (eClass.isInterface())
    {
      createEcoreAnnotation(xsdComplexTypeDefinition, "interface", "true");
    }

    String constraints = EcoreUtil.getAnnotation(eClass, EcorePackage.eNS_URI, "constraints");
    if (constraints != null)
    {
      createEcoreAnnotation(xsdComplexTypeDefinition, "constraints", constraints);
    }

    for (Iterator<EStructuralFeature> i = eClass.getEStructuralFeatures().iterator(); i.hasNext(); )
    {
      EStructuralFeature eStructuralFeature = i.next();
      buildContentFeature(xsdComplexTypeDefinition, eStructuralFeature);
    }

    List<EOperation> eOperations = eClass.getEOperations();
    if (!eOperations.isEmpty())
    {
      XSDAnnotation xsdAnnotation = xsdComplexTypeDefinition.getAnnotation();
      if (xsdAnnotation == null)
      {
        xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation();
        xsdComplexTypeDefinition.setAnnotation(xsdAnnotation);
      }
      Element applicationInformation = xsdAnnotation.createApplicationInformation(EcorePackage.eNS_URI);
      xsdAnnotation.getElement().appendChild(applicationInformation);
      createEcoreAnnotation(xsdSchema.getQNamePrefixToNamespaceMap(), applicationInformation, "key", "operations");
      Document document = xsdSchema.getDocument();
      for (EOperation eOperation : eOperations)
      {
        Element operation = document.createElementNS(null, "operation");
        operation.setAttributeNS(null, "name", eOperation.getName());
        applicationInformation.appendChild(operation);
        buildAnnotation(eOperation, operation);
        buildTypeParameters(xsdAnnotation, eOperation.getETypeParameters());
        EGenericType returnEGenericType = eOperation.getEGenericType();
        if (returnEGenericType != null)
        {
          operation.setAttributeNS(null, "type", getGenericType(xsdSchema, returnEGenericType));
        }
        List<EClassifier> exceptions = eOperation.getEExceptions();
        if (!exceptions.isEmpty())
        {
          StringBuilder stringBuilder = new StringBuilder();
          for (EGenericType eGenericType : eOperation.getEGenericExceptions())
          {
            stringBuilder.append(getGenericType(xsdSchema, eGenericType));
            stringBuilder.append(' ');
          }

          operation.setAttributeNS(null, "exceptions", stringBuilder.substring(0, stringBuilder.length() - 1));
        }

        for (EParameter eParameter : eOperation.getEParameters())
        {
          Element parameter = document.createElementNS(null, "parameter");
          parameter.setAttributeNS(null, "name", eParameter.getName());
          operation.appendChild(parameter);
          buildAnnotation(eParameter, parameter);
          parameter.setAttributeNS(null, "type", getGenericType(xsdSchema, eParameter.getEGenericType()));

          if (eParameter.getLowerBound() != 0)
          {
            parameter.setAttributeNS(null, "lowerBound", Integer.toString(eParameter.getLowerBound()));
          }
          if (eParameter.getUpperBound() != 1)
          {
            parameter.setAttributeNS(null, "upperBound", Integer.toString(eParameter.getUpperBound()));
          }
          if (!eParameter.isOrdered())
          {
            parameter.setAttributeNS(null, "ordered", "false");
          }
          if (!eParameter.isUnique())
          {
            parameter.setAttributeNS(null, "unique", "false");
          }
        }

        if (eOperation.getLowerBound() != 0)
        {
          operation.setAttributeNS(null, "lowerBound", Integer.toString(eOperation.getLowerBound()));
        }
        if (eOperation.getUpperBound() != 1)
        {
          operation.setAttributeNS(null, "upperBound", Integer.toString(eOperation.getUpperBound()));
        }
        if (!eOperation.isOrdered())
        {
          operation.setAttributeNS(null, "ordered", "false");
        }
        if (!eOperation.isUnique())
        {
          operation.setAttributeNS(null, "unique", "false");
        }

        String body = EcoreUtil.getAnnotation(eOperation, GEN_MODEL_PACKAGE_NS_URI, "body");
        if (body != null)
        {
          Element bodyElement = document.createElementNS(null, "body");
          bodyElement.appendChild(document.createTextNode(body));
          operation.appendChild(bodyElement);
        }
      }
    }

    buildAnnotations(xsdComplexTypeDefinition, eClass);

    return xsdComplexTypeDefinition;
  }

  protected void buildTypeParameters(XSDComponent xsdComponent, List<ETypeParameter> eTypeParameters)
  {
    if (!eTypeParameters.isEmpty())
    {
      XSDSchema xsdSchema = xsdComponent.getSchema();
      XSDAnnotation xsdAnnotation;
      Element applicationInformation;
      if (xsdComponent instanceof XSDTypeDefinition)
      {
        xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation();
        ((XSDTypeDefinition)xsdComponent).setAnnotation(xsdAnnotation);
        applicationInformation = xsdAnnotation.createApplicationInformation(EcorePackage.eNS_URI);
        xsdAnnotation.getElement().appendChild(applicationInformation);
        createEcoreAnnotation(xsdSchema.getQNamePrefixToNamespaceMap(), applicationInformation, "key", "typeParameters");
      }
      else
      {
        xsdAnnotation = (XSDAnnotation)xsdComponent;
        applicationInformation = (Element)xsdAnnotation.getApplicationInformation().get(xsdAnnotation.getApplicationInformation().size() - 1).getLastChild();
      }
      Document document = xsdSchema.getDocument();
      for (ETypeParameter eTypeParameter : eTypeParameters)
      {
        Element typeParameter = document.createElementNS(null, "typeParameter");
        typeParameter.setAttributeNS(null, "name", eTypeParameter.getName());
        applicationInformation.appendChild(typeParameter);
        buildAnnotation(eTypeParameter, typeParameter);
        List<EGenericType> eBounds = eTypeParameter.getEBounds();
        if (!eBounds.isEmpty())
        {
          StringBuilder stringBuilder = new StringBuilder();
          for (Iterator<EGenericType> i = eBounds.iterator(); i.hasNext(); )
          {
            String bound = getGenericType(xsdSchema, i.next());
            stringBuilder.append(bound);
            if (i.hasNext())
            {
              stringBuilder.append(' ');
            }
          }

          typeParameter.setAttributeNS(null, "bounds", stringBuilder.toString());
        }
      }
    }
  }

  protected XSDComponent buildContentFeature(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature)
  {
    switch (extendedMetaData.getFeatureKind(eStructuralFeature))
    {
      case ExtendedMetaData.ELEMENT_FEATURE:
      {
        XSDParticle xsdParticle = buildElementParticle(xsdComplexTypeDefinition, eStructuralFeature);
        return xsdParticle;
      }
      case ExtendedMetaData.ATTRIBUTE_FEATURE:
      {
        XSDAttributeUse xsdAttributeUse = buildAttributeUse(xsdComplexTypeDefinition, eStructuralFeature);
        return xsdAttributeUse;
      }
      case ExtendedMetaData.GROUP_FEATURE:
      {
        XSDParticle xsdParticle = buildModelGroupParticle(xsdComplexTypeDefinition, eStructuralFeature);
        return xsdParticle;
      }
      case ExtendedMetaData.ELEMENT_WILDCARD_FEATURE:
      {
        XSDWildcard xsdWildcard = buildElementWildcard(xsdComplexTypeDefinition, eStructuralFeature);
        return xsdWildcard;
      }
      case ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE:
      {
        XSDWildcard xsdWildcard = buildAttributeWildcard(xsdComplexTypeDefinition, eStructuralFeature);
        return xsdWildcard;
      }
      case ExtendedMetaData.SIMPLE_FEATURE:
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition = buildSimpleContent(xsdComplexTypeDefinition, eStructuralFeature);
        return xsdSimpleTypeDefinition;
      }
      default:
      {
        if (eStructuralFeature instanceof EAttribute)
        {
          EAttribute eAttribute = (EAttribute)eStructuralFeature;
          if (eAttribute.isMany())
          {
            return buildElementParticle(xsdComplexTypeDefinition, eAttribute);
          }
          else
          {
            return buildAttributeUse(xsdComplexTypeDefinition, eAttribute);
          }
        }
        else
        {
          EReference eReference = (EReference)eStructuralFeature;
          if (eReference.isContainment())
          {
            return buildElementParticle(xsdComplexTypeDefinition, eReference);
          }
          else if (eReference.isContainer() && eReference.isTransient())
          {
            return null;
          }
          else
          {
            return buildAttributeUse(xsdComplexTypeDefinition, eReference);
          }
        }
      }
    }
  }

  protected XSDParticle buildModelGroupParticle(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature)
  {
    XSDModelGroup xsdModelGroup = findOrCreateModelGroup(xsdComplexTypeDefinition);

    XSDModelGroup modelGroup = XSDFactory.eINSTANCE.createXSDModelGroup();
    modelGroup.setCompositor(XSDCompositor.CHOICE_LITERAL);
    XSDParticle xsdParticle = XSDFactory.eINSTANCE.createXSDParticle();
    xsdParticle.setContent(modelGroup);

    if (eStructuralFeature.getUpperBound() != 1)
    {
      xsdParticle.setMaxOccurs(eStructuralFeature.getUpperBound());
    }

    xsdModelGroup.getContents().add(xsdParticle);
    map(xsdParticle, eStructuralFeature);

    createEcoreAnnotation(xsdParticle, "featureMap", eStructuralFeature.getName());

    buildAnnotations(xsdModelGroup, eStructuralFeature);

    return xsdParticle;
  }

  protected XSDWildcard buildElementWildcard(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature)
  {
    String name = extendedMetaData.getName(eStructuralFeature);
    if (":mixed".equals(name))
    {
      xsdComplexTypeDefinition.setMixed(true);
      return null;
    }
    else
    {
      XSDWildcard xsdWildcard = XSDFactory.eINSTANCE.createXSDWildcard();
      xsdWildcard.setStringLexicalNamespaceConstraint
        (BasicExtendedMetaData.getEncodedWildcards
           (extendedMetaData.getNamespace(eStructuralFeature.getEContainingClass()),
            extendedMetaData.getWildcards(eStructuralFeature)));
      XSDModelGroup xsdModelGroup = findOrCreateModelGroup(xsdComplexTypeDefinition);
      XSDParticle xsdParticle = XSDFactory.eINSTANCE.createXSDParticle();
      xsdParticle.setContent(xsdWildcard);
      xsdModelGroup.getContents().add(xsdParticle);
      map(xsdParticle, eStructuralFeature);

      if (eStructuralFeature.getLowerBound() != 1)
      {
        xsdParticle.setMinOccurs(eStructuralFeature.getLowerBound());
      }

      if (eStructuralFeature.getUpperBound() != 1)
      {
        xsdParticle.setMaxOccurs(eStructuralFeature.getUpperBound());
      }
      createEcoreAnnotation(xsdWildcard, "name", eStructuralFeature.getName());

      buildAnnotations(xsdWildcard, eStructuralFeature);

      return xsdWildcard;
    }
  }

  protected XSDWildcard buildAttributeWildcard(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature)
  {
    XSDWildcard xsdWildcard = XSDFactory.eINSTANCE.createXSDWildcard();
    xsdWildcard.setStringLexicalNamespaceConstraint
      (BasicExtendedMetaData.getEncodedWildcards
         (extendedMetaData.getNamespace(eStructuralFeature.getEContainingClass()),
          extendedMetaData.getWildcards(eStructuralFeature)));
    xsdComplexTypeDefinition.setAttributeWildcardContent(xsdWildcard);

    map(xsdWildcard, eStructuralFeature);

    createEcoreAnnotation(xsdWildcard, "name", eStructuralFeature.getName());

    buildAnnotations(xsdWildcard, eStructuralFeature);

    return xsdWildcard;
  }

  protected XSDSimpleTypeDefinition buildSimpleContent(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature)
  {
    XSDSchema xsdSchema = xsdComplexTypeDefinition.getSchema();
    XSDSimpleTypeDefinition xsdSimpleTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition();
    EClassifier eType = eStructuralFeature.getEType();
    EClassifier referenceType = null;
    XSDSimpleTypeDefinition baseType;
    if (eStructuralFeature instanceof EReference)
    {
      referenceType = eType;
      baseType =
        xsdSchema.getSchemaForSchema().resolveSimpleTypeDefinition
          (((EReference)eStructuralFeature).isResolveProxies() ?  "anyURI" : "IDREF");
      handleMultiplicity(xsdSchema, eStructuralFeature, xsdSimpleTypeDefinition, baseType);
    }
    else
    {
      baseType = xsdComplexTypeDefinition.resolveSimpleTypeDefinitionURI(getURI(eType));
      handleImport(xsdSchema, baseType);
      handleMultiplicity(xsdSchema, eStructuralFeature, xsdSimpleTypeDefinition, baseType);
    }
    xsdComplexTypeDefinition.setBaseTypeDefinition(xsdSimpleTypeDefinition.getBaseType());
    xsdComplexTypeDefinition.setDerivationMethod(xsdSimpleTypeDefinition.getContents().isEmpty() ? XSDDerivationMethod.EXTENSION_LITERAL : XSDDerivationMethod.RESTRICTION_LITERAL);
    xsdComplexTypeDefinition.setContent(xsdSimpleTypeDefinition);

    map(xsdSimpleTypeDefinition, eStructuralFeature);

    buildAttributeInformation(xsdComplexTypeDefinition, "value", false, referenceType, xsdSimpleTypeDefinition, eStructuralFeature);

    if (eStructuralFeature instanceof EAttribute && 
          ((EAttribute)eStructuralFeature).isID() && 
          !XSDConstants.isOrIsDerivedFromID(xsdSimpleTypeDefinition))
    {
      createEcoreAnnotation(xsdSimpleTypeDefinition, "id", "true");
    }

    if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE))
    {
      createEcoreAnnotation(xsdSimpleTypeDefinition, referenceType == null ? "type" : "reference", getGenericType(xsdSchema, eStructuralFeature.getEGenericType()));
    }

    return xsdSimpleTypeDefinition;
  }

  protected XSDAttributeUse buildAttributeUse(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature)
  {
    XSDSchema xsdSchema = xsdComplexTypeDefinition.getSchema();
    String namespace = extendedMetaData.getNamespace(eStructuralFeature);
    String name = extendedMetaData.getName(eStructuralFeature);

    // It must be a ref if it refers to another namespace.
    // If it refers to this namespace,
    // it's treated as a ref,
    // if this feature has the same type as the feature for matching global attribute.
    //
    String typeNamespace = extendedMetaData.getNamespace(eStructuralFeature.getEContainingClass());
    boolean isRef = namespace != null && !namespace.equals(typeNamespace);
    if (namespace == null ? typeNamespace == null : namespace.equals(typeNamespace))
    {
      EStructuralFeature globalFeature = extendedMetaData.getAttribute(namespace, name);
      isRef = globalFeature != null && EcoreUtil.equals(globalFeature.getEGenericType(), eStructuralFeature.getEGenericType());
    }

    XSDAttributeUse xsdAttributeUse = XSDFactory.eINSTANCE.createXSDAttributeUse();
    XSDAttributeDeclaration xsdAttributeDeclaration = XSDFactory.eINSTANCE.createXSDAttributeDeclaration();

    EClassifier referenceType = null;
    if (isRef)
    {
      XSDAttributeDeclaration referencedXSDAttributeDeclaration =  xsdComplexTypeDefinition.resolveAttributeDeclaration(namespace, name);
      handleImport(xsdSchema, referencedXSDAttributeDeclaration);
      xsdAttributeDeclaration.setResolvedAttributeDeclaration(referencedXSDAttributeDeclaration);
    }
    else
    {
      xsdAttributeDeclaration.setName(name);

      if (namespace != null)
      {
        xsdAttributeDeclaration.setForm(XSDForm.QUALIFIED_LITERAL);
      }

      EClassifier eType = eStructuralFeature.getEType();
      if (eStructuralFeature instanceof EReference)
      {
        referenceType = eType;
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition =
            xsdSchema.getSchemaForSchema().resolveSimpleTypeDefinition
              (((EReference)eStructuralFeature).isResolveProxies() ?  "anyURI" : "IDREF");
        handleMultiplicity(xsdSchema, eStructuralFeature, xsdAttributeDeclaration, xsdSimpleTypeDefinition);
      }
      else
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition =  xsdComplexTypeDefinition.resolveSimpleTypeDefinitionURI(getURI(eType));
        handleImport(xsdSchema, xsdSimpleTypeDefinition);
        handleMultiplicity(xsdSchema, eStructuralFeature, xsdAttributeDeclaration, xsdSimpleTypeDefinition);
      }
    }

    xsdAttributeUse.setContent(xsdAttributeDeclaration);
    xsdComplexTypeDefinition.getAttributeContents().add(xsdAttributeUse);
    map(xsdAttributeUse, eStructuralFeature);

    buildAttributeInformation(xsdComplexTypeDefinition, name, isRef, referenceType, xsdAttributeUse, eStructuralFeature);

    if (eStructuralFeature instanceof EAttribute && 
          ((EAttribute)eStructuralFeature).isID() && 
          !XSDConstants.isOrIsDerivedFromID(xsdAttributeDeclaration.getTypeDefinition()))
    {
      createEcoreAnnotation(xsdAttributeUse, "id", "true");
    }

    if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE))
    {
      createEcoreAnnotation(xsdAttributeUse, referenceType == null ? "type" : "reference", getGenericType(xsdSchema, eStructuralFeature.getEGenericType()));
    }

    return xsdAttributeUse;
  }

  protected void buildAttributeInformation
    (XSDComplexTypeDefinition xsdComplexTypeDefinition,
     String name,
     boolean isRef,
     EClassifier referenceType,
     XSDComponent xsdComponent,
     EStructuralFeature eStructuralFeature)
  {
    List<EAttribute> eKeys = null;
    
    if (referenceType == null && eStructuralFeature.isMany())
    {
      createEcoreAnnotation(xsdComponent, "many", "true");
    }

    if (eStructuralFeature instanceof EReference)
    {
      EReference eReference = (EReference)eStructuralFeature;
      EReference eOpposite = eReference.getEOpposite();
      if (eOpposite != null)
      {
        createEcoreAnnotation(xsdComponent, "opposite", eOpposite.getName());
      }
      eKeys = eReference.getEKeys();
    }
    
    if (eKeys != null && !eKeys.isEmpty())
    {
      StringBuilder keys = new StringBuilder();
      for (EAttribute eKey : eKeys)
      {
        keys.append(eKey.getName());
        keys.append(' ');
      }
      createEcoreAnnotation(xsdComponent, "keys", keys.toString().trim());
    }

    XSDAttributeUse xsdAttriuteUse = xsdComponent instanceof XSDAttributeUse ? (XSDAttributeUse)xsdComponent : null;

    boolean canHaveDefault = xsdAttriuteUse != null;
    if (eStructuralFeature.isRequired())
    {
      if (eStructuralFeature.isTransient() || xsdAttriuteUse == null)
      {
        createEcoreAnnotation(xsdComponent, "lowerBound", Integer.toString(eStructuralFeature.getLowerBound()));
      }
      else
      {
        xsdAttriuteUse.setUse(XSDAttributeUseCategory.REQUIRED_LITERAL);
        canHaveDefault = false;
      }
    }

    String defaultValue = eStructuralFeature.getDefaultValueLiteral();
    if (defaultValue != null)
    {
      if (canHaveDefault && xsdAttriuteUse != null)
      {
        if (isRef)
        {
          xsdAttriuteUse.setConstraint(XSDConstraint.DEFAULT_LITERAL);
          xsdAttriuteUse.setLexicalValue(transformDefaultValue(xsdAttriuteUse.getAttributeDeclaration().getTypeDefinition(), defaultValue));
        }
        else
        {
          XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttriuteUse.getAttributeDeclaration();
          xsdAttributeDeclaration.setConstraint(XSDConstraint.DEFAULT_LITERAL);
          xsdAttributeDeclaration.setLexicalValue(transformDefaultValue(xsdAttributeDeclaration.getTypeDefinition(), defaultValue));
        }
      }
      else
      {
        createEcoreAnnotation(xsdComponent, "default", defaultValue);
      }
    }

    if (eStructuralFeature.isMany())
    {
      if (eStructuralFeature.isUnsettable())
      {
        createEcoreAnnotation(xsdComponent, "unsettable", "true");
      }
    }
    else if ((eStructuralFeature.getEType().getDefaultValue() != null || eStructuralFeature.getDefaultValueLiteral() != null) !=
                eStructuralFeature.isUnsettable())
    {
      createEcoreAnnotation(xsdComponent, "unsettable", Boolean.toString(eStructuralFeature.isUnsettable()));
    }

    String ecoreName = eStructuralFeature.getName();
    if (!name.equals(ecoreName) || Character.isUpperCase(ecoreName.charAt(0)) || ecoreName.indexOf('_') != -1)
    {
      createEcoreAnnotation(xsdComponent, "name", ecoreName);
    }

    if (eStructuralFeature.isMany() && !eStructuralFeature.isOrdered())
    {
      createEcoreAnnotation(xsdComponent, "ordered", "false");
    }

    if (eStructuralFeature.isMany() && eStructuralFeature.isUnique() && eStructuralFeature instanceof EAttribute)
    {
      createEcoreAnnotation(xsdComponent, "unique", "true");
    }

    if (!eStructuralFeature.isChangeable())
    {
      createEcoreAnnotation(xsdComponent, "changeable", "false");
    }

    if (extendedMetaData.getGroup(eStructuralFeature) == null)
    {
      if (eStructuralFeature.isDerived())
      {
        createEcoreAnnotation(xsdComponent, "derived", "true");
      }

      if (eStructuralFeature.isTransient())
      {
        createEcoreAnnotation(xsdComponent, "transient", "true");
      }

      if (eStructuralFeature.isVolatile())
      {
        createEcoreAnnotation(xsdComponent, "volatile", "true");
      }
    }

    if (referenceType != null)
    {
      XSDTypeDefinition xsdTypeDefinition = xsdComplexTypeDefinition.resolveTypeDefinitionURI(getURI(referenceType));
      handleImport(xsdComplexTypeDefinition.getSchema(), xsdTypeDefinition);
      String prefix =
        handlePrefix
          (xsdComplexTypeDefinition.getSchema().getQNamePrefixToNamespaceMap(),
            referenceType.getEPackage().getNsPrefix(),
            xsdTypeDefinition.getTargetNamespace());
      createEcoreAnnotation(xsdComponent, "reference", prefix + ":" + xsdTypeDefinition.getName());
    }

    if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.GET))
    {
      createEcoreAnnotation(xsdComponent, "suppressedGetVisibility", "true");
    }
    if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.SET))
    {
      createEcoreAnnotation(xsdComponent, "suppressedSetVisibility", "true");
    }
    if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.IS_SET))
    {
      createEcoreAnnotation(xsdComponent, "suppressedIsSetVisibility", "true");
    }
    if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET))
    {
      createEcoreAnnotation(xsdComponent, "suppressedUnsetVisibility", "true");
    }

    buildAnnotations(xsdComponent, eStructuralFeature);
  }

  protected void handleMultiplicity
    (XSDSchema xsdSchema,
     EStructuralFeature eStructuralFeature,
     XSDAttributeDeclaration xsdAttributeDeclaration,
     XSDSimpleTypeDefinition xsdSimpleTypeDefinition)
  {
    handleMultiplicity(xsdSchema, eStructuralFeature, (XSDComponent)xsdAttributeDeclaration, xsdSimpleTypeDefinition);
  }

  protected void handleMultiplicity
    (XSDSchema xsdSchema,
     EStructuralFeature eStructuralFeature,
     XSDComponent xsdComponent,
     XSDSimpleTypeDefinition xsdSimpleTypeDefinition)
  {
    if (eStructuralFeature.isMany())
    {
      XSDSimpleTypeDefinition xsdListTypeDefinition;
      if (xsdSimpleTypeDefinition.hasNameAndTargetNamespace("IDREF", defaultXMLSchemaNamespace))
      {
        xsdListTypeDefinition = xsdSchema.getSchemaForSchema().resolveSimpleTypeDefinition("IDREFS");
      }
      else
      {
        xsdListTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition();
        xsdListTypeDefinition.setItemTypeDefinition(xsdSimpleTypeDefinition);
      }
      if (eStructuralFeature.getLowerBound() > 1 || eStructuralFeature.getUpperBound() > 1)
      {
        XSDSimpleTypeDefinition xsdRestrictedTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition();
        if (xsdListTypeDefinition.getContainer() == null)
        {
          xsdRestrictedTypeDefinition.getContents().add(xsdListTypeDefinition);
        }
        else
        {
          xsdRestrictedTypeDefinition.setBaseTypeDefinition(xsdListTypeDefinition);
        }
        if (eStructuralFeature.getLowerBound() == eStructuralFeature.getUpperBound())
        {
          XSDLengthFacet xsdLengthFacet = XSDFactory.eINSTANCE.createXSDLengthFacet();
          xsdLengthFacet.setLexicalValue(Integer.toString(eStructuralFeature.getLowerBound()));
          xsdRestrictedTypeDefinition.getFacetContents().add(xsdLengthFacet);
        }
        else
        {
          if (eStructuralFeature.getLowerBound() > 1)
          {
            XSDMinLengthFacet xsdMinLengthFacet = XSDFactory.eINSTANCE.createXSDMinLengthFacet();
            xsdMinLengthFacet.setLexicalValue(Integer.toString(eStructuralFeature.getLowerBound()));
            xsdRestrictedTypeDefinition.getFacetContents().add(xsdMinLengthFacet);
          }
          if (eStructuralFeature.getUpperBound() > 1)
          {
            XSDMaxLengthFacet xsdMaxLengthFacet = XSDFactory.eINSTANCE.createXSDMaxLengthFacet();
            xsdMaxLengthFacet.setLexicalValue(Integer.toString(eStructuralFeature.getUpperBound()));
            xsdRestrictedTypeDefinition.getFacetContents().add(xsdMaxLengthFacet);
          }
        }
        if (xsdComponent instanceof XSDAttributeDeclaration)
        {
          ((XSDAttributeDeclaration)xsdComponent).setAnonymousTypeDefinition(xsdRestrictedTypeDefinition);
        }
        else
        {
          ((XSDSimpleTypeDefinition)xsdComponent).getContents().add(xsdRestrictedTypeDefinition);
        }
      }
      else
      {
        if (xsdListTypeDefinition.getContainer() == null)
        {
          if (xsdComponent instanceof XSDAttributeDeclaration)
          {
            ((XSDAttributeDeclaration)xsdComponent).setAnonymousTypeDefinition(xsdListTypeDefinition);
          }
          else
          {
            ((XSDSimpleTypeDefinition)xsdComponent).getContents().add(xsdListTypeDefinition);
          }
        }
        else
        {
          if (xsdComponent instanceof XSDAttributeDeclaration)
          {
            ((XSDAttributeDeclaration)xsdComponent).setTypeDefinition(xsdListTypeDefinition);
          }
          else
          {
            ((XSDSimpleTypeDefinition)xsdComponent).setBaseTypeDefinition(xsdListTypeDefinition);
          }
        }
      }
    }
    else
    {
      if (xsdComponent instanceof XSDAttributeDeclaration)
      {
        ((XSDAttributeDeclaration)xsdComponent).setTypeDefinition(xsdSimpleTypeDefinition);
      }
      else
      {
        ((XSDSimpleTypeDefinition)xsdComponent).setBaseTypeDefinition(xsdSimpleTypeDefinition);
      }
    }
  }

  protected XSDParticle buildElementParticle(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature)
  {
    String namespace = extendedMetaData.getNamespace(eStructuralFeature);
    String name = extendedMetaData.getName(eStructuralFeature);

    // It must be a ref if it refers to another namespace.
    // If it refers to this namespace,
    // it's treated as a ref,
    // if this feature has the same type as the feature for matching global element.
    //
    String typeNamespace = extendedMetaData.getNamespace(eStructuralFeature.getEContainingClass());
    boolean isRef = namespace != null && !namespace.equals(typeNamespace);
    if (namespace == null ? typeNamespace == null : namespace.equals(typeNamespace))
    {
      EStructuralFeature globalFeature = extendedMetaData.getElement(namespace, name);
      isRef = globalFeature != null && EcoreUtil.equals(globalFeature.getEGenericType(), eStructuralFeature.getEGenericType());
    }

    XSDModelGroup xsdModelGroup = findOrCreateModelGroup(xsdComplexTypeDefinition);

    EStructuralFeature group = extendedMetaData.getGroup(eStructuralFeature);
    if (group != null)
    {
      XSDParticle xsdParticle = (XSDParticle)eModelElementToXSDComponentMap.get(group);
      if (xsdParticle != null)
      {
        xsdModelGroup = (XSDModelGroup)xsdParticle.getContent();
      }
    }

    XSDElementDeclaration xsdElementDeclaration = XSDFactory.eINSTANCE.createXSDElementDeclaration();

    EClassifier referenceType = null;
    EReference eOpposite = null;
    List<EAttribute> eKeys = null;
    EClassifier eType = eStructuralFeature.getEType();
    if (isRef)
    {
      XSDElementDeclaration referencedXSDElementDeclaration = xsdComplexTypeDefinition.resolveElementDeclaration(namespace, name);
      handleImport(xsdComplexTypeDefinition.getSchema(), referencedXSDElementDeclaration);
      xsdElementDeclaration.setResolvedElementDeclaration(referencedXSDElementDeclaration);

      if (eStructuralFeature instanceof EReference)
      {
        EReference eReference = (EReference)eStructuralFeature;
        eOpposite = eReference.getEOpposite();
        eKeys = eReference.getEKeys();
      }
    }
    else
    {
      xsdElementDeclaration.setName(name);
      if (namespace != null)
      {
        xsdElementDeclaration.setForm(XSDForm.QUALIFIED_LITERAL);
      }

      XSDTypeDefinition xsdTypeDefinition =
        xsdComplexTypeDefinition.resolveTypeDefinitionURI(getURI(eType));

      String defaultValue = eStructuralFeature.getDefaultValueLiteral();
      if (defaultValue != null)
      {
        xsdElementDeclaration.setConstraint(XSDConstraint.DEFAULT_LITERAL);
        xsdElementDeclaration.setLexicalValue(transformDefaultValue((XSDSimpleTypeDefinition)xsdTypeDefinition, defaultValue));
      }

      if (eStructuralFeature instanceof EReference)
      {
        EReference eReference = (EReference)eStructuralFeature;
        eOpposite = eReference.getEOpposite();
        eKeys = eReference.getEKeys();
        if (!eReference.isContainment() && !eReference.isContainer())
        {
          referenceType = eType;
          xsdTypeDefinition =
            xsdComplexTypeDefinition.getSchema().getSchemaForSchema().resolveTypeDefinition
            (eReference.isResolveProxies() ? "anyURI" : "IDREF");
        }
      }

      handleImport(xsdComplexTypeDefinition.getSchema(), xsdTypeDefinition);
      xsdElementDeclaration.setTypeDefinition(xsdTypeDefinition);

      // If the attribute can have a null value (primitives and enums can't), and
      // if the attribute can hold many nulls or
      // it can hold only a single value that is allowed to be null
      // and it can be considered set when it has the null value...
      //
      if (isWrapperType(eType) ||
            (eStructuralFeature instanceof EAttribute &&
             eType.getDefaultValue() == null &&
             (eStructuralFeature.isMany() ||
                (!eStructuralFeature.isRequired() &&
                   (eStructuralFeature.getDefaultValueLiteral() != null || eStructuralFeature.isUnsettable())))))
      {
        xsdElementDeclaration.setNillable(true);
      }
    }

    XSDParticle xsdParticle = XSDFactory.eINSTANCE.createXSDParticle();
    xsdParticle.setContent(xsdElementDeclaration);

    xsdModelGroup.getContents().add(xsdParticle);
    map(xsdParticle, eStructuralFeature);

    if (eStructuralFeature.isMany())
    {
      if (eStructuralFeature.isUnsettable())
      {
        createEcoreAnnotation(xsdParticle, "unsettable", "true");
      }
    }
    else if (xsdElementDeclaration.isNillable() ?
               !eStructuralFeature.isUnsettable() :
               (eType.getDefaultValue() != null || eStructuralFeature.getDefaultValueLiteral() != null) !=
                  eStructuralFeature.isUnsettable())
    {
      createEcoreAnnotation(xsdParticle, "unsettable", Boolean.toString(eStructuralFeature.isUnsettable()));
    }

    if (eOpposite != null)
    {
      createEcoreAnnotation(xsdParticle, "opposite", eOpposite.getName());
    }

    if (eKeys != null && !eKeys.isEmpty())
    {
      StringBuilder keys = new StringBuilder();
      for (EAttribute eKey : eKeys)
      {
        keys.append(eKey.getName());
        keys.append(' ');
      }
      createEcoreAnnotation(xsdParticle, "keys", keys.toString().trim());
    }

    if (group == null)
    {
      if (eStructuralFeature.isTransient() && !xsdComplexTypeDefinition.isMixed())
      {
        xsdParticle.setMinOccurs(0);
        if (eStructuralFeature.getLowerBound() != 0)
        {
          createEcoreAnnotation(xsdParticle, "lowerBound", Integer.toString(eStructuralFeature.getLowerBound()));
        }
      }
      else if (eStructuralFeature.getLowerBound() != 1)
      {
        xsdParticle.setMinOccurs(eStructuralFeature.getLowerBound());
      }

      if (eStructuralFeature.getUpperBound() != 1)
      {
        xsdParticle.setMaxOccurs(eStructuralFeature.getUpperBound());
      }
    }
    else
    {
      if (eStructuralFeature.isTransient() && !xsdComplexTypeDefinition.isMixed())
      {
        xsdParticle.setMinOccurs(0);
        if (eStructuralFeature.getLowerBound() != 0)
        {
          createEcoreAnnotation(xsdParticle, "lowerBound", Integer.toString(eStructuralFeature.getLowerBound()));
        }
      }
      else if (eStructuralFeature.getLowerBound() != 1)
      {
        createEcoreAnnotation(xsdParticle, "lowerBound", Integer.toString(eStructuralFeature.getLowerBound()));
      }

      if (eStructuralFeature.getUpperBound() != 1)
      {
        createEcoreAnnotation(xsdParticle, "upperBound", Integer.toString(eStructuralFeature.getUpperBound()));
      }
    }

    String ecoreName = eStructuralFeature.getName();
    if (!name.equals(ecoreName) || Character.isUpperCase(ecoreName.charAt(0)) || ecoreName.indexOf('_') != -1)
    {
      createEcoreAnnotation(xsdParticle, "name", ecoreName);
    }

    if (eStructuralFeature.isMany() && !eStructuralFeature.isOrdered())
    {
      createEcoreAnnotation(xsdParticle, "ordered", "false");
    }

    if (eStructuralFeature.isMany() && eStructuralFeature.isUnique() && eStructuralFeature instanceof EAttribute)
    {
      createEcoreAnnotation(xsdParticle, "unique", "true");
    }

    if (!eStructuralFeature.isChangeable())
    {
      createEcoreAnnotation(xsdParticle, "changeable", "false");
    }

    if (extendedMetaData.getContentKind(eStructuralFeature.getEContainingClass()) != ExtendedMetaData.MIXED_CONTENT &&
          extendedMetaData.getGroup(eStructuralFeature) == null)
    {
      if (eStructuralFeature.isDerived())
      {
        createEcoreAnnotation(xsdParticle, "derived", "true");
      }

      if (eStructuralFeature.isTransient())
      {
        createEcoreAnnotation(xsdParticle, "transient", "true");
      }

      if (eStructuralFeature.isVolatile())
      {
        createEcoreAnnotation(xsdParticle, "volatile", "true");
      }
    }

    if (eStructuralFeature instanceof EReference &&
          ((EReference)eStructuralFeature).isResolveProxies() &&
          ((EReference)eStructuralFeature).isContainment())
    {
      createEcoreAnnotation(xsdParticle, "resolveProxies", "true");
    }

    if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE))
    {
      createEcoreAnnotation(xsdParticle, referenceType == null ? "type" : "reference", getGenericType(xsdComplexTypeDefinition.getSchema(), eStructuralFeature.getEGenericType()));
    }
    else if (referenceType != null)
    {
      XSDTypeDefinition xsdTypeDefinition = xsdComplexTypeDefinition.resolveTypeDefinitionURI(getURI(referenceType));
      handleImport(xsdComplexTypeDefinition.getSchema(), xsdTypeDefinition);
      String prefix =
        handlePrefix
          (xsdComplexTypeDefinition.getSchema().getQNamePrefixToNamespaceMap(),
            referenceType.getEPackage().getNsPrefix(),
            xsdTypeDefinition.getTargetNamespace());
      createEcoreAnnotation(xsdElementDeclaration, "reference", prefix + ":" + xsdTypeDefinition.getName());
    }

    if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.GET))
    {
      createEcoreAnnotation(xsdElementDeclaration, "suppressedGetVisibility", "true");
    }
    if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.SET))
    {
      createEcoreAnnotation(xsdElementDeclaration, "suppressedSetVisibility", "true");
    }
    if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.IS_SET))
    {
      createEcoreAnnotation(xsdElementDeclaration, "suppressedIsSetVisibility", "true");
    }
    if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET))
    {
      createEcoreAnnotation(xsdElementDeclaration, "suppressedUnsetVisibility", "true");
    }

    if (eStructuralFeature instanceof EAttribute && 
          ((EAttribute)eStructuralFeature).isID() && 
          xsdElementDeclaration.getTypeDefinition() instanceof XSDSimpleTypeDefinition &&
          !XSDConstants.isOrIsDerivedFromID((XSDSimpleTypeDefinition)xsdElementDeclaration.getTypeDefinition()))
    {
      createEcoreAnnotation(xsdParticle, "id", "true");
    }

    buildAnnotations(xsdParticle, eStructuralFeature);

    return xsdParticle;
  }

  protected XSDModelGroup findOrCreateModelGroup(XSDComplexTypeDefinition xsdComplexTypeDefinition)
  {
    if (xsdComplexTypeDefinition.getContent() == null)
    {
      return buildModelGroup(xsdComplexTypeDefinition);
    }
    else
    {
      XSDParticle xsdParticle = (XSDParticle)xsdComplexTypeDefinition.getContent();
      return (XSDModelGroup)xsdParticle.getContent();
    }
  }

  protected XSDModelGroup buildModelGroup(XSDComplexTypeDefinition xsdComplexTypeDefinition)
  {
    XSDModelGroup xsdModelGroup = XSDFactory.eINSTANCE.createXSDModelGroup();
    xsdModelGroup.setCompositor(XSDCompositor.SEQUENCE_LITERAL);
    XSDParticle xsdParticle = XSDFactory.eINSTANCE.createXSDParticle();
    xsdParticle.setContent(xsdModelGroup);
    xsdComplexTypeDefinition.setContent(xsdParticle);
    return xsdModelGroup;
  }

  protected boolean isWrapperType(EClassifier eClassifier)
  {
    String name = extendedMetaData.getName(eClassifier);
    return name.endsWith(":Object") && !EcorePackage.eNS_URI.equals(extendedMetaData.getNamespace(eClassifier));
  }

  protected String getURI(EClassifier eClassifier)
  {
    String namespace = extendedMetaData.getNamespace(eClassifier);
    String name = extendedMetaData.getName(eClassifier);
    if (XMLTypePackage.eNS_URI.equals(namespace))
    {
      namespace = defaultXMLSchemaNamespace;
      if (name.endsWith(":Object"))
      {
        name = name.substring(0, name.length() - 7);
      }
    }
    else if (EcorePackage.eNS_URI.equals(namespace))
    {
      if ("EObject".equals(name))
      {
        namespace = defaultXMLSchemaNamespace;
        name = "anyType";
      }
      else if (name.endsWith(":Object"))
      {
        name = eClassifier.getName();
      }
    }
    else if (name.endsWith(":Object"))
    {
      name = name.substring(0, name.length() - 7);
    }
    String result =
      namespace == null ?
        name :
        namespace + "#" + name;
    return result;
  }

  protected String getURI(EStructuralFeature eStructuralFeature)
  {
    String namespace = extendedMetaData.getNamespace(eStructuralFeature);
    String name = extendedMetaData.getName(eStructuralFeature);
    if (XMLTypePackage.eNS_URI.equals(namespace))
    {
      namespace = defaultXMLSchemaNamespace;
    }
    String result =
      namespace == null ?
        name :
        namespace + "#" + name;
    return result;
  }

  protected String getGenericType(XSDSchema xsdSchema, EGenericType eGenericType)
  {
    Map<String, String> qNamePrefixToNamespaceMap = xsdSchema.getQNamePrefixToNamespaceMap();
    StringBuilder result = new StringBuilder();
    EClassifier eClassifier = eGenericType.getEClassifier();
    if (eClassifier != null)
    {
       XSDTypeDefinition type = xsdSchema.resolveTypeDefinitionURI(getURI(eClassifier));
       handleImport(xsdSchema, type);
       String prefix =
         handlePrefix
           (qNamePrefixToNamespaceMap,
             eClassifier.getEPackage().getNsPrefix(),
             type.getTargetNamespace());
       result.append(prefix);
       result.append(':');
       result.append(type.getName());
       List<EGenericType> eTypeArguments = eGenericType.getETypeArguments();
       if (!eTypeArguments.isEmpty())
       {
         result.append('{');
         for (Iterator<EGenericType> i = eTypeArguments.iterator(); i.hasNext(); )
         {
           result.append(getGenericType(xsdSchema, i.next()));
           if (i.hasNext())
           {
             result.append(", ");
           }
         }
         result.append('}');
       }
    }
    else
    {
      ETypeParameter eTypeParameter = eGenericType.getETypeParameter();
      if (eTypeParameter != null)
      {
        result.append(eTypeParameter.getName());
      }
      else
      {
        result.append('?');
        EGenericType eUpperBound = eGenericType.getEUpperBound();
        if (eUpperBound != null)
        {
          result.append(" extends ");
          result.append(getGenericType(xsdSchema, eUpperBound));
        }
        else
        {
          EGenericType eLowerBound = eGenericType.getELowerBound();
          if (eLowerBound != null)
          {
            result.append(" super ");
            result.append(getGenericType(xsdSchema, eLowerBound));
          }
        }
      }
    }
    return result.toString();
  }

  protected void createEcoreAnnotation(XSDComponent xsdComponent, String key, String value)
  {
    Element element = xsdComponent.getElement();
    if (element != null)
    {
      createEcoreAnnotation(xsdComponent.getSchema().getQNamePrefixToNamespaceMap(), element, key, value);
    }
  }

  protected void createEcoreAnnotation(Map<String, String> qNamePrefixToNamespaceMap, Element element, String key, String value)
  {
    String ecorePrefix = handlePrefix(qNamePrefixToNamespaceMap, "ecore", EcorePackage.eNS_URI);
    element.setAttributeNS(EcorePackage.eNS_URI, ecorePrefix + ':' + key, value);
  }

  protected void createAnnotation(XSDComponent xsdComponent, String namespace, String key, String value)
  {
    Element element = xsdComponent.getElement();
    if (element != null)
    {
      createAnnotation(xsdComponent.getSchema().getQNamePrefixToNamespaceMap(), element, namespace, key, value);
    }
  }

  protected void createAnnotation(Map<String, String> qNamePrefixToNamespaceMap, Element element, String namespace, String key, String value)
  {
    String prefix = handlePrefix(qNamePrefixToNamespaceMap, qualifiedPackageName(namespace), namespace);
    element.setAttributeNS(namespace, prefix + ':' + key, value);
  }

  protected void handleImport(XSDSchema xsdSchema, XSDNamedComponent xsdNamedComponent)
  {
    String namespace = xsdNamedComponent.getTargetNamespace();

    if (!defaultXMLSchemaNamespace.equals(namespace) &&
         (namespace == null ? xsdSchema.getTargetNamespace() != null : !namespace.equals(xsdSchema.getTargetNamespace())))
    {
      for (Object content : xsdSchema.getContents())
      {
        if (content instanceof XSDImport)
        {
          XSDImport xsdImport = (XSDImport)content;
          if (namespace == null ? xsdImport.getNamespace() == null : namespace.equals(xsdImport.getNamespace()))
          {
            return;
          }
        }
        else if (!(content instanceof XSDAnnotation))
        {
          break;
        }
      }

      XSDImport xsdImport = XSDFactory.eINSTANCE.createXSDImport();
      xsdImport.setNamespace(namespace);

      EPackage ePackage = extendedMetaData.getPackage(namespace);
      if (ePackage != null)
      {
        handlePrefix(xsdSchema.getQNamePrefixToNamespaceMap(), ePackage.getNsPrefix(), namespace);
        //xsdImport.setSchemaLocation(ePackage.eResource().getURI().trimFileExtension().appendFileExtension("xsd").toString());
        xsdImport.setSchemaLocation(ePackage.getNsURI());
      }

      xsdSchema.getContents().add(0, xsdImport);
    }
  }

  protected String handlePrefix(Map<String, String> namespaces, String preferredPrefix, String namespace)
  {
    if (XMLNamespacePackage.eNS_URI.equals(namespace))
    {
      return "xml";
    }

    String value = namespaces.get(preferredPrefix);
    if (namespace == null ? value == null : namespace.equals(value))
    {
      return preferredPrefix;
    }

    // If there is a non-null value, i.e., if the prefix is in use, see if there is already a prefix chosen.
    //
    if (value != null || defaultXMLSchemaNamespace.equals(namespace))
    {
      for (Map.Entry<String, String> entry : namespaces.entrySet())
      {
        if (namespace == null ? entry.getValue() == null : namespace.equals(entry.getValue()))
        {
          // Return the previously assigned prefix; it may not match the preferred one.
          //
          return entry.getKey();
        }
      }
    }

    String uniquePrefix = preferredPrefix;
    for (int i = 0; namespaces.containsKey(uniquePrefix); ++i)
    {
      uniquePrefix = preferredPrefix + "_" + i;
    }
    namespaces.put("".equals(uniquePrefix) ? null : uniquePrefix, namespace);
    return uniquePrefix;
  }

  protected static final String GEN_MODEL_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/GenModel";

  protected boolean isIgnoredAnnotationSource(String sourceURI)
  {
    return
      EcorePackage.eNS_URI.equals(sourceURI) ||
        ExtendedMetaData.ANNOTATION_URI.equals(sourceURI) ||
        GEN_MODEL_PACKAGE_NS_URI.equals(sourceURI);
  }

  protected void buildAnnotations(XSDComponent xsdComponent, EModelElement eModelElement)
  {
    for (EAnnotation eAnnotation : eModelElement.getEAnnotations())
    {
      String source = eAnnotation.getSource();
      if (!isIgnoredAnnotationSource(source))
      {
        XSDAnnotation xsdAnnotation = null;
        for (Map.Entry<String, String> entry : eAnnotation.getDetails().entrySet())
        {
          String key = entry.getKey();
          String value = entry.getValue();
          if (key != null && value.indexOf('\n') == -1 && value.indexOf('\r') == -1)
          {
            createAnnotation(xsdComponent, source, key, value);
          }
          else
          {
            if (xsdAnnotation == null)
            {
              xsdAnnotation = buildAnnotation(xsdComponent, eModelElement);
            }
            if (xsdAnnotation != null)
            {
              Element applicationInformation = xsdAnnotation.createApplicationInformation(source);
              if (key != null)
              {
                createEcoreAnnotation(xsdComponent.getSchema().getQNamePrefixToNamespaceMap(), applicationInformation, "key", key);
              }
              if (value != null)
              {
                applicationInformation.appendChild(xsdAnnotation.getSchema().getDocument().createTextNode(value));
              }
              xsdAnnotation.getElement().appendChild(applicationInformation);
            }
          }
        }
      }
    }

    String documentation = EcoreUtil.getDocumentation(eModelElement);
    if (documentation != null)
    {
      XSDAnnotation xsdAnnotation = buildAnnotation(xsdComponent, eModelElement);
      if (xsdAnnotation != null)
      {
        createUserInfo(xsdAnnotation, documentation);
      }
    }
  }

  protected XSDAnnotation buildAnnotation(XSDConcreteComponent xsdComponent, EModelElement eModelElement)
  {
    XSDAnnotation xsdAnnotation = null;
    if (xsdComponent instanceof XSDAttributeUse)
    {
      xsdComponent = ((XSDAttributeUse)xsdComponent).getContent();
    }
    else if (xsdComponent instanceof XSDParticle)
    {
      xsdComponent = ((XSDParticle)xsdComponent).getContent();
    }

    if (xsdComponent instanceof XSDSchema)
    {
      ((XSDSchema)xsdComponent).getContents().add(0, xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation());
    }
    else if (xsdComponent instanceof XSDTypeDefinition)
    {
      XSDTypeDefinition xsdTypeDefinition = ((XSDTypeDefinition)xsdComponent);
      if ((xsdAnnotation = xsdTypeDefinition.getAnnotation()) == null)
      {
        xsdTypeDefinition.setAnnotation(xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation());
      }
    }
    else if (xsdComponent instanceof XSDFacet)
    {
      XSDFacet xsdFacet = ((XSDFacet)xsdComponent);
      if ((xsdAnnotation = xsdFacet.getAnnotation()) == null)
      {
        xsdFacet.setAnnotation(xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation());
      }
    }
    else if (xsdComponent instanceof XSDElementDeclaration)
    {
      XSDElementDeclaration xsdElementDeclaration = ((XSDElementDeclaration)xsdComponent);
      if ((xsdAnnotation = xsdElementDeclaration.getAnnotation()) == null)
      {
        xsdElementDeclaration.setAnnotation(xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation());
      }
    }
    else if (xsdComponent instanceof XSDAttributeDeclaration)
    {
      XSDAttributeDeclaration xsdAttributeDeclaration = ((XSDAttributeDeclaration)xsdComponent);
      if ((xsdAnnotation = xsdAttributeDeclaration.getAnnotation()) == null)
      {
        xsdAttributeDeclaration.setAnnotation(xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation());
      }
    }

    return xsdAnnotation;
  }

  protected void createUserInfo(XSDAnnotation xsdAnnotation, String documentation)
  {
    Element userInformation = xsdAnnotation.createUserInformation(null);

    // Try to parse the documentation and use the parsed version if it's successful.
    //
    XSDParser xsdParser = new XSDParser(null);
    xsdParser.parseString("<documentation>" + documentation + "</documentation>");
    Document document = xsdParser.getDocument();
    if (xsdParser.getDiagnostics().isEmpty() && document.getDocumentElement().getFirstChild() != null)
    {
      Document xsdDocument = xsdAnnotation.getSchema().getDocument();
      for (Node node = document.getDocumentElement().getFirstChild(); node != null; node = node.getNextSibling())
      {
        userInformation.appendChild(xsdDocument.importNode(node, true));
      }
    }
    else
    {
      userInformation.appendChild(xsdAnnotation.getSchema().getDocument().createTextNode(documentation));
    }

    xsdAnnotation.getElement().appendChild(userInformation);
  }

  protected void buildAnnotation(EModelElement eModelElement, Element parent)
  {
    Document document = parent.getOwnerDocument();
    for (EAnnotation eAnnotation : eModelElement.getEAnnotations())
    {
      String source = eAnnotation.getSource();
      if (!isIgnoredAnnotationSource(source))
      {
        Element annotation = document.createElementNS(null, "annotation");
        if (source != null)
        {
          annotation.setAttributeNS(null, "source", source);
        }
        for (Map.Entry<String, String> entry : eAnnotation.getDetails())
        {
          String key = entry.getKey();
          String value = entry.getValue();
          Element detail = document.createElementNS(null, "detail");
          if (key != null)
          {
            detail.setAttributeNS(null, "key", key);
          }
          if (value != null)
          {
            detail.appendChild(document.createTextNode(value));
          }
          annotation.appendChild(detail);
        }
        parent.appendChild(annotation);
      }
      else if (GEN_MODEL_PACKAGE_NS_URI.equals(source) && eAnnotation.getDetails().containsKey("documentation"))
      {
        String documentation = EcoreUtil.getDocumentation(eModelElement);
        if (documentation != null)
        {
          Element annotation = document.createElementNS(null, "annotation");
          annotation.setAttributeNS(null, "source", GEN_MODEL_PACKAGE_NS_URI);
          Element detail = document.createElementNS(null, "detail");
          detail.setAttributeNS(null, "key", "documentation");
          detail.appendChild(document.createTextNode(documentation));
          annotation.appendChild(detail);
          parent.appendChild(annotation);
        }
      }
    }
  }
}
