/**
 * Copyright (c) 2011-2012 Eclipse contributors and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipse.emf.ecore.xcore.util;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.emf.codegen.ecore.genmodel.GenBase;
import org.eclipse.emf.codegen.ecore.genmodel.GenClassifier;
import org.eclipse.emf.codegen.ecore.genmodel.GenFeature;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.codegen.ecore.genmodel.GenTypeParameter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
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.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.EClassifierImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.EcoreValidator;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xcore.XAnnotation;
import org.eclipse.emf.ecore.xcore.XAnnotationDirective;
import org.eclipse.emf.ecore.xcore.XAttribute;
import org.eclipse.emf.ecore.xcore.XClass;
import org.eclipse.emf.ecore.xcore.XClassifier;
import org.eclipse.emf.ecore.xcore.XDataType;
import org.eclipse.emf.ecore.xcore.XEnum;
import org.eclipse.emf.ecore.xcore.XEnumLiteral;
import org.eclipse.emf.ecore.xcore.XGenericType;
import org.eclipse.emf.ecore.xcore.XMember;
import org.eclipse.emf.ecore.xcore.XModelElement;
import org.eclipse.emf.ecore.xcore.XOperation;
import org.eclipse.emf.ecore.xcore.XPackage;
import org.eclipse.emf.ecore.xcore.XParameter;
import org.eclipse.emf.ecore.xcore.XReference;
import org.eclipse.emf.ecore.xcore.XStructuralFeature;
import org.eclipse.emf.ecore.xcore.XTypeParameter;
import org.eclipse.emf.ecore.xcore.XTypedElement;
import org.eclipse.emf.ecore.xcore.XcorePackage;
import org.eclipse.emf.ecore.xcore.XcorePlugin;
import org.eclipse.emf.ecore.xcore.interpreter.IClassLoaderProvider;
import org.eclipse.emf.ecore.xcore.interpreter.XcoreConversionDelegate;
import org.eclipse.emf.ecore.xcore.interpreter.XcoreInterpreter;
import org.eclipse.emf.ecore.xcore.interpreter.XcoreInvocationDelegate;
import org.eclipse.emf.ecore.xcore.interpreter.XcoreSettingDelegate;
import org.eclipse.emf.ecore.xcore.mappings.XcoreMapper;
import org.eclipse.emf.ecore.xcore.services.XcoreGrammarAccess;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.xbase.XBlockExpression;

import com.google.inject.Inject;
import com.google.inject.Provider;


public class XcoreEcoreBuilder
{
  private static final Pattern COMMENT_LINE_BREAK_PATTERN = Pattern.compile("([ \t]*(\\r?\\n)(\\s*\\*\\s?)?)|\\s*$", Pattern.MULTILINE);

  @Inject
  private XcoreMapper mapper;

  @Inject
  private Provider<XcoreInvocationDelegate> operationDelegateProvider;

  @Inject
  private Provider<XcoreSettingDelegate> settingDelegateProvider;

  @Inject
  private Provider<XcoreConversionDelegate> conversionDelegateProvider;

  @Inject
  private Provider<XcoreInterpreter> interpreterProvider;

  @Inject
  private IClassLoaderProvider classLoaderProvider;

  @Inject
  private XcoreGrammarAccess xcoreGrammarAccess;

  protected List<Runnable> runnables = new ArrayList<Runnable>();

  protected List<Runnable> instanceTypeRunnables = new ArrayList<Runnable>();

  protected XcoreInterpreter interpreter;

  protected ClassLoader classLoader;

  public void link()
  {
    // Hook up local references.
    //
    List<Runnable> currentRunnables = new ArrayList<Runnable>(runnables);
    runnables.clear();
    for (Runnable runnable : currentRunnables)
    {
      try
      {
        runnable.run();
      }
      catch (Throwable throwable)
      {
        XcorePlugin.INSTANCE.log(throwable);
      }
    }
    for (Runnable runnable : runnables)
    {
      try
      {
        runnable.run();
      }
      catch (Throwable throwable)
      {
        XcorePlugin.INSTANCE.log(throwable);
      }
    }
  }

  public void linkInstanceTypes()
  {
    // Hook up instance types.
    //
    for (Runnable runnable : instanceTypeRunnables)
    {
      try
      {
        runnable.run();
      }
      catch (Throwable throwable)
      {
        XcorePlugin.INSTANCE.log(throwable);
      }
    }
  }

  public static void setQualifiedPackageName(EPackage ePackage, String name)
  {
    String basePackage = null;
    if (name != null)
    {
      int index = name.lastIndexOf(".");
      if (index == -1)
      {
        ePackage.setName(name);
      }
      else
      {
        basePackage = name.substring(0, index);
        ePackage.setName(name.substring(index + 1));
      }
    }
    else
    {
      ePackage.setName("_");
    }
    EcoreUtil.setAnnotation(ePackage, GenModelPackage.eNS_URI, "basePackage", basePackage);
  }

  protected String nonNullName(String name)
  {
    return name == null ? "_" : name;
  }

  public EPackage getEPackage(XPackage xPackage)
  {
    interpreter = interpreterProvider.get();
    classLoader = classLoaderProvider.getClassLoader(xPackage.eResource().getResourceSet());
    if (classLoader != null)
    {
      interpreter.setClassLoader(classLoader);
    }
    EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
    mapper.getMapping(xPackage).setEPackage(ePackage);
    mapper.getToXcoreMapping(ePackage).setXcoreElement(xPackage);
    handleAnnotations(xPackage, ePackage);
    String name = xPackage.getName();
    setQualifiedPackageName(ePackage, name);
    if (name != null)
    {
      // The pre linking phase model won't process the annotations and won't pick up the nsURI in the annotation.
      // That's particularly problematic because the nsURI is something indexed from this prelinked model.
      // At least to this for Ecore to avoid inducing a model with circular inheritance.
      // TODO
      //
      if (ePackage.getNsURI() == null)
      {
        ePackage.setNsURI("org.eclipse.emf.ecore".equals(name) ? EcorePackage.eNS_URI : name);
      }
      if (ePackage.getNsPrefix() == null)
      {
        ePackage.setNsPrefix(ePackage.getName());
      }
    }

    EList<EClassifier> eClassifiers = ePackage.getEClassifiers();
    for (XClassifier xClassifier : xPackage.getClassifiers())
    {
      EClassifier eClassifier = getEClassifier(xClassifier);
      eClassifiers.add(eClassifier);
    }

    for (XAnnotationDirective xAnnotationDirective : xPackage.getAnnotationDirectives())
    {
      EcoreUtil.setAnnotation(ePackage, XcorePackage.eNS_URI, xAnnotationDirective.getName(), xAnnotationDirective.getSourceURI());
    }

    return ePackage;
  }

  protected void handleAnnotations(final XModelElement xModelElement, final EModelElement eModelElement)
  {
    ICompositeNode node = NodeModelUtils.getNode(xModelElement);
    if (node != null)
    {
      for (ILeafNode child : node.getLeafNodes())
      {
        if (child.isHidden())
        {
          if (child.getGrammarElement() == xcoreGrammarAccess.getML_COMMENTRule())
          {
            String text = child.getText();
            int length = text.length();
            if (length > 4)
            {
              String[] lines = COMMENT_LINE_BREAK_PATTERN.split(text.subSequence(2, length - 2), 0);
              StringBuilder comment = null;
              for (String line : lines)
              {
                if (line.length() != 0)
                {
                  if (comment == null)
                  {
                    comment = new StringBuilder();
                    comment.append(line);
                  }
                  else
                  {
                    comment.append('\n');
                    comment.append(line);
                  }
                }
                else if (comment != null)
                {
                  comment.append('\n');
                  comment.append(line);
                }
              }
              if (comment != null)
              {
                EcoreUtil.setDocumentation(eModelElement, comment.toString());
              }
            }
            break;
          }
        }
        else
        {
          break;
        }
      }
    }
    handleAnnotations(xModelElement, eModelElement, true);
    runnables.add
      (new Runnable()
       {
         public void run()
         {
           handleAnnotations(xModelElement, eModelElement, false);
         }
       });
  }

  protected void handleAnnotations(final XModelElement xModelElement, final EModelElement eModelElement, boolean preIndexing)
  {
    EList<EAnnotation> eAnnotations = eModelElement.getEAnnotations();
    for (XAnnotation xAnnotation : xModelElement.getAnnotations())
    {
      //      map(eAnnotation, xAnnotation);
      String sourceURI = null;

      if (preIndexing)
      {
        List<INode> nodes = NodeModelUtils.findNodesForFeature(xAnnotation, XcorePackage.Literals.XANNOTATION__SOURCE);
        StringBuilder annotationLiteral = new StringBuilder();
        for (INode node : nodes)
        {
          annotationLiteral.append(NodeModelUtils.getTokenText(node));
        }
        int index = annotationLiteral.lastIndexOf(" ");
        if (index != -1)
        {
          annotationLiteral.delete(0, index + 1);
        }
        index = annotationLiteral.lastIndexOf(".");
        if (index != -1)
        {
          annotationLiteral.delete(0, index + 1);
        }
        String simpleAnnotationName = annotationLiteral.toString();
        if ("GenModel".equals(simpleAnnotationName))
        {
          sourceURI = GenModelPackage.eNS_URI;
        }
        else if ("Ecore".equals(simpleAnnotationName))
        {
          sourceURI = EcorePackage.eNS_URI;
        }
        else if ("ExtendedMetaData".equals(simpleAnnotationName))
        {
          sourceURI = ExtendedMetaData.ANNOTATION_URI;
        }
      }
      else
      {
        XAnnotationDirective source = xAnnotation.getSource();
        if (source != null)
        {
          sourceURI = source.getSourceURI();
        }
      }

      if (sourceURI != null)
      {
        EClass eClass = EcorePackage.eNS_URI.equals(sourceURI) ? eModelElement.eClass() : null;
   
        EMap<String, String> details = xAnnotation.getDetails();
        if (details.isEmpty())
        {
          EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
          eAnnotation.setSource(sourceURI);
          eAnnotations.add(eAnnotation);
        }
        else
        {
          for (Map.Entry<String, String> detail : details)
          {
            String key = detail.getKey();
            String value = detail.getValue();
            if (eClass != null)
            {
              EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(key);
              if (eStructuralFeature instanceof EAttribute)
              {
                // Be more careful about exceptions.
                // TODO
                //
                EDataType eDataType = (EDataType)eStructuralFeature.getEType();
                eModelElement.eSet(eStructuralFeature, EcoreUtil.createFromString(eDataType, value));
                continue;
              }
            }
            if (EcoreUtil.getAnnotation(eModelElement, sourceURI, key) == null)
            {
              EcoreUtil.setAnnotation(eModelElement, sourceURI, key, value);
            }
          }
        }
      }
    }
  }

  protected EClassifier getEClassifier(final XClassifier xClassifier)
  {
    final EClassifier eClassifier = xClassifier instanceof XClass ? getEClass((XClass)xClassifier) : xClassifier instanceof XEnum
      ? getEEnum((XEnum)xClassifier) : getEDataType((XDataType)xClassifier);
    handleAnnotations(xClassifier, eClassifier);
    eClassifier.setName(nonNullName(xClassifier.getName()));

    // Test if there is an instance type name but avoid resolving proxies.
    //
    if (xClassifier.eIsSet(XcorePackage.Literals.XCLASSIFIER__INSTANCE_TYPE))
    {
      if (eClassifier instanceof EClass)
      {
        // For classes that wrap interfaces, it's important the instance type name isn't null when the XcoreJvmInferrer infers whether to generate an interface,
        // so set a dummy result earlier and allow it to be updated later.
        //
        eClassifier.setInstanceTypeName("java.lang.Cloneable");
      }

      // Populate the instance type early because GenOperation IDs depend on the data type's unqualified instance type and it might not be set so early.
      List<INode> nodes = NodeModelUtils.findNodesForFeature(xClassifier, XcorePackage.Literals.XCLASSIFIER__INSTANCE_TYPE);
      if (!nodes.isEmpty())
      {
        StringBuilder instanceTypeLiteral = new StringBuilder();
        for (INode node : nodes)
        {
          instanceTypeLiteral.append(NodeModelUtils.getTokenText(node));
        }
        eClassifier.setInstanceTypeName(instanceTypeLiteral.toString());
      }

      instanceTypeRunnables.add
        (new Runnable()
         {
           public void run()
           {
             JvmTypeReference instanceType = xClassifier.getInstanceType();
             if (instanceType != null)
             {
               String instanceTypeName = instanceType.getIdentifier();
               String normalizedInstanceTypeName = EcoreUtil.toJavaInstanceTypeName((EGenericType)EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(instanceTypeName).getData().get(0));
               eClassifier.setInstanceTypeName(normalizedInstanceTypeName);
               if (classLoader != null && eClassifier instanceof EClassifierImpl)
               {
                 try
                 {
                   Class<?> instanceClass = classLoader.loadClass(eClassifier.getInstanceClassName());
                   ((EClassifierImpl)eClassifier).setInstanceClassGen(instanceClass);
                 }
                 catch (Throwable throwable)
                 {
                   // Ignore.
                 }
               }
             }
           }
         });
    }
    return eClassifier;
  }

  protected EClass getEClass(final XClass xClass)
  {
    final EClass eClass = EcoreFactory.eINSTANCE.createEClass();
    mapper.getMapping(xClass).setEClass(eClass);
    mapper.getToXcoreMapping(eClass).setXcoreElement(xClass);
    if (xClass.isInterface())
    {
      eClass.setInterface(true);
      eClass.setAbstract(true);
    }
    else if (xClass.isAbstract())
    {
      eClass.setAbstract(true);
    }
    EList<EGenericType> eGenericSuperTypes = eClass.getEGenericSuperTypes();
    for (XGenericType superType : xClass.getSuperTypes())
    {
      eGenericSuperTypes.add(getEGenericType(superType));
    }
    EList<ETypeParameter> eTypeParameters = eClass.getETypeParameters();
    for (XTypeParameter xTypeParameter : xClass.getTypeParameters())
    {
      ETypeParameter eTypeParameter = getETypeParameter(xTypeParameter);
      eTypeParameters.add(eTypeParameter);
    }
    EList<EOperation> eOperations = eClass.getEOperations();
    EList<EStructuralFeature> eStructuralFeatures = eClass.getEStructuralFeatures();
    for (XMember xMember : xClass.getMembers())
    {
      if (xMember instanceof XOperation)
      {
        EOperation eOperation = getEOperation((XOperation)xMember);
        eOperations.add(eOperation);
      }
      else if (xMember instanceof XReference)
      {
        EReference eReference = getEReference((XReference)xMember);
        eStructuralFeatures.add(eReference);
      }
      else
      {
        EAttribute eAttribute = getEAttribute((XAttribute)xMember);
        eStructuralFeatures.add(eAttribute);
      }
    }
    return eClass;
  }

  protected EOperation getEOperation(XOperation xOperation)
  {
    EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation();
    mapper.getMapping(xOperation).setEOperation(eOperation);
    mapper.getToXcoreMapping(eOperation).setXcoreElement(xOperation);
    eOperation.setUnique(false);
    handleETypedElement(eOperation, xOperation);
    EList<ETypeParameter> eTypeParameters = eOperation.getETypeParameters();
    for (XTypeParameter xTypeParameter : xOperation.getTypeParameters())
    {
      ETypeParameter eTypeParameter = getETypeParameter(xTypeParameter);
      eTypeParameters.add(eTypeParameter);
    }
    EList<EParameter> eParameters = eOperation.getEParameters();
    for (XParameter xParameter : xOperation.getParameters())
    {
      EParameter eParameter = getEParameter(xParameter);
      eParameters.add(eParameter);
    }
    for (XGenericType exception : xOperation.getExceptions())
    {
      EGenericType eException = getEGenericType(exception);
      eOperation.getEGenericExceptions().add(eException);
    }
    XBlockExpression body = xOperation.getBody();
    if (body != null)
    {
      final XcoreInvocationDelegate invocationDelegate = operationDelegateProvider.get();
      invocationDelegate.initialize(body, eOperation, interpreter);
      ((EOperation.Internal)eOperation).setInvocationDelegate(invocationDelegate);

      // Set a body annotation so that GenOperation.hasBody will return true.
      //
      EcoreUtil.setAnnotation(eOperation, GenModelPackage.eNS_URI, "body", "");
    }
    return eOperation;
  }

  protected EParameter getEParameter(XParameter xParameter)
  {
    EParameter eParameter = EcoreFactory.eINSTANCE.createEParameter();
    mapper.getMapping(xParameter).setEParameter(eParameter);
    mapper.getToXcoreMapping(eParameter).setXcoreElement(xParameter);
    eParameter.setUnique(false);
    handleETypedElement(eParameter, xParameter);
    return eParameter;
  }

  protected ETypeParameter getETypeParameter(XTypeParameter xTypeParameter)
  {
    ETypeParameter eTypeParameter = EcoreFactory.eINSTANCE.createETypeParameter();
    mapper.getMapping(xTypeParameter).setETypeParameter(eTypeParameter);
    mapper.getToXcoreMapping(eTypeParameter).setXcoreElement(xTypeParameter);
    handleAnnotations(xTypeParameter, eTypeParameter);
    eTypeParameter.setName(nonNullName(xTypeParameter.getName()));
    EList<EGenericType> eBounds = eTypeParameter.getEBounds();
    for (XGenericType xGenericType : xTypeParameter.getBounds())
    {
      eBounds.add(getEGenericType(xGenericType));
    }
    return eTypeParameter;
  }

  protected void handleETypedElement(ETypedElement eTypedElement, XTypedElement xTypedElement)
  {
    eTypedElement.setName(nonNullName(xTypedElement.getName()));
    handleAnnotations(xTypedElement, eTypedElement);
    eTypedElement.setEGenericType(getEGenericType(xTypedElement.getType()));
    if (xTypedElement.isUnordered())
    {
      eTypedElement.setOrdered(false);
    }
    if (xTypedElement.isUnique())
    {
      eTypedElement.setUnique(true);
    }
    int[] multiplicity = xTypedElement.getMultiplicity();
    if (multiplicity == null)
    {
      // optional is the default
      //
    }
    else if (multiplicity.length == 0)
    {
      // []
      //
      eTypedElement.setUpperBound(EStructuralFeature.UNBOUNDED_MULTIPLICITY);
    }
    else if (multiplicity.length == 1)
    {
      if (multiplicity[0] == -3)
      {
        // [?]
        //
      }
      else if (multiplicity[0] == -2)
      {
        // [+]
        //
        eTypedElement.setLowerBound(1);
        eTypedElement.setUpperBound(EStructuralFeature.UNBOUNDED_MULTIPLICITY);
      }
      else if (multiplicity[0] == -1)
      {
        // [*]
        //
        eTypedElement.setUpperBound(EStructuralFeature.UNBOUNDED_MULTIPLICITY);
      }
      else
      {
        // [n]
        //
        eTypedElement.setLowerBound(multiplicity[0]);
        eTypedElement.setUpperBound(multiplicity[0]);
      }
    }
    else
    {
      eTypedElement.setLowerBound(multiplicity[0]);
      eTypedElement.setUpperBound(multiplicity[1]);
    }
  }

  protected EGenericType getEGenericType(final XGenericType xGenericType)
  {
    if (xGenericType == null)
    {
      return null;
    }
    else
    {
      final EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
      //      map(eGenericType, xGenericType);
      XGenericType lowerBound = xGenericType.getLowerBound();
      if (lowerBound != null)
      {
        eGenericType.setELowerBound(getEGenericType(lowerBound));
      }
      XGenericType upperBound = xGenericType.getUpperBound();
      if (upperBound != null)
      {
        eGenericType.setEUpperBound(getEGenericType(upperBound));
      }
      EList<EGenericType> eTypeArguments = eGenericType.getETypeArguments();
      for (XGenericType typeArgument : xGenericType.getTypeArguments())
      {
        eTypeArguments.add(getEGenericType(typeArgument));
      }

      runnables.add(new Runnable()
        {
          public void run()
          {
            GenBase type = xGenericType.getType();
            if (type instanceof GenTypeParameter)
            {
              eGenericType.setETypeParameter(((GenTypeParameter)type).getEcoreTypeParameter());
            }
            else if (type instanceof GenClassifier)
            {
              eGenericType.setEClassifier(((GenClassifier)type).getEcoreClassifier());
            }
          }
        });
      return eGenericType;
    }
  }

  protected EReference getEReference(final XReference xReference)
  {
    final EReference eReference = EcoreFactory.eINSTANCE.createEReference();
    mapper.getMapping(xReference).setEStructuralFeature(eReference);
    mapper.getToXcoreMapping(eReference).setXcoreElement(xReference);
    if (xReference.isContainment())
    {
      eReference.setContainment(true);
      if (!xReference.isResolveProxies())
      {
        eReference.setResolveProxies(false);
      }
    }
    if (xReference.isLocal())
    {
      eReference.setResolveProxies(false);
    }

    handleEStructuralFeature(eReference, xReference);

    runnables.add(new Runnable()
      {
        public void run()
        {
          GenFeature opposite = xReference.getOpposite();
          if (opposite != null)
          {
            eReference.setEOpposite((EReference)opposite.getEcoreFeature());
          }
          runnables.add(new Runnable()
            {
              public void run()
              {
                for (GenFeature key : xReference.getKeys())
                {
                  EStructuralFeature eAttribute = key.getEcoreFeature();
                  if (eAttribute instanceof EAttribute)
                  {
                    eReference.getEKeys().add((EAttribute)eAttribute);
                  }
                }
              }});
        }
      });

    return eReference;
  }

  protected EAttribute getEAttribute(final XAttribute xAttribute)
  {
    final EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
    mapper.getMapping(xAttribute).setEStructuralFeature(eAttribute);
    mapper.getToXcoreMapping(eAttribute).setXcoreElement(xAttribute);
    eAttribute.setUnique(false);
    if (xAttribute.isID())
    {
      eAttribute.setID(true);
    }
    eAttribute.setDefaultValueLiteral(xAttribute.getDefaultValueLiteral());
    handleEStructuralFeature(eAttribute, xAttribute);
    return eAttribute;
  }

  protected void handleEStructuralFeature(EStructuralFeature eStructuralFeature, XStructuralFeature xStructuralFeature)
  {
    eStructuralFeature.setName(nonNullName(xStructuralFeature.getName()));
    handleETypedElement(eStructuralFeature, xStructuralFeature);
    if (xStructuralFeature.isReadonly())
    {
      eStructuralFeature.setChangeable(false);
    }
    if (xStructuralFeature.isTransient())
    {
      eStructuralFeature.setTransient(true);
    }
    if (xStructuralFeature.isVolatile())
    {
      eStructuralFeature.setVolatile(true);
    }
    if (xStructuralFeature.isUnsettable())
    {
      eStructuralFeature.setUnsettable(true);
    }
    if (xStructuralFeature.isDerived())
    {
      eStructuralFeature.setDerived(true);
    }

    XBlockExpression getBody = xStructuralFeature.getGetBody();
    XBlockExpression setBody = xStructuralFeature.getSetBody();
    XBlockExpression isSetBody = xStructuralFeature.getIsSetBody();
    XBlockExpression unsetBody = xStructuralFeature.getUnsetBody();
    if (getBody != null || setBody != null || isSetBody != null || unsetBody != null)
    {
      XcoreSettingDelegate settingDelegate = settingDelegateProvider.get();
      settingDelegate.initialize(getBody, setBody, isSetBody, unsetBody, eStructuralFeature, interpreter);
      ((EStructuralFeature.Internal)eStructuralFeature).setSettingDelegate(settingDelegate);
    }

    if (getBody != null)
    {
      eStructuralFeature.setTransient(true);
      eStructuralFeature.setVolatile(true);
      eStructuralFeature.setDerived(true);
      if (setBody == null)
      {
        eStructuralFeature.setChangeable(false);
      }
    }
  }

  protected EDataType getEDataType(XDataType xDataType)
  {
    EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
    mapper.getMapping(xDataType).setEDataType(eDataType);
    mapper.getToXcoreMapping(eDataType).setXcoreElement(xDataType);
    EList<ETypeParameter> eTypeParameters = eDataType.getETypeParameters();
    for (XTypeParameter xTypeParameter : xDataType.getTypeParameters())
    {
      ETypeParameter eTypeParameter = getETypeParameter(xTypeParameter);
      eTypeParameters.add(eTypeParameter);
    }
    XBlockExpression createBody = xDataType.getCreateBody();
    if (createBody != null)
    {
      XcoreConversionDelegate conversionDelegate = conversionDelegateProvider.get();
      conversionDelegate.initialize(createBody, xDataType.getConvertBody(), eDataType, interpreter);
      ((EDataType.Internal)eDataType).setConversionDelegate(conversionDelegate);
    }
    return eDataType;
  }

  protected EEnum getEEnum(XEnum xEnum)
  {
    EEnum eEnum = EcoreFactory.eINSTANCE.createEEnum();
    mapper.getMapping(xEnum).setEDataType(eEnum);
    mapper.getToXcoreMapping(eEnum).setXcoreElement(xEnum);
    EList<EEnumLiteral> eLiterals = eEnum.getELiterals();
    for (XEnumLiteral xEnumLiteral : xEnum.getLiterals())
    {
      eLiterals.add(getEEnumLiteral(xEnumLiteral));
    }
    return eEnum;
  }

  protected EEnumLiteral getEEnumLiteral(XEnumLiteral xEnumLiteral)
  {
    EEnumLiteral eEnumLiteral = EcoreFactory.eINSTANCE.createEEnumLiteral();
    mapper.getToXcoreMapping(eEnumLiteral).setXcoreElement(xEnumLiteral);
    mapper.getMapping(xEnumLiteral).setEEnumLiteral(eEnumLiteral);
    handleAnnotations(xEnumLiteral, eEnumLiteral);
    eEnumLiteral.setName(nonNullName(xEnumLiteral.getName()));
    eEnumLiteral.setLiteral(xEnumLiteral.getLiteral());
    eEnumLiteral.setValue(xEnumLiteral.getValue());
    return eEnumLiteral;
  }
}
