[536550] Improve code generation performance
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/Generator.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/Generator.java
index 779a088..8327667 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/Generator.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/Generator.java
@@ -831,8 +831,18 @@
             System.arraycopy(oldBuilders, 0, builders, 0, enhancerBuilderIndex);
             System.arraycopy(oldBuilders, enhancerBuilderIndex + 1, builders, enhancerBuilderIndex, oldBuilders.length - enhancerBuilderIndex - 1);
           }
+
           projectDescription.setBuildSpec(builders);
-          project.setDescription(projectDescription, BasicMonitor.subProgress(progressMonitor, 1));
+
+          // Avoid updating if there are no changes.
+          //
+          IProjectDescription originalDescription = project.getDescription();
+          if (!Arrays.equals(originalDescription.getBuildSpec(), projectDescription.getBuildSpec()) ||
+                !Arrays.equals(originalDescription.getNatureIds(), projectDescription.getNatureIds()) ||
+                !Arrays.equals(originalDescription.getReferencedProjects(), projectDescription.getReferencedProjects()))
+          {
+            project.setDescription(projectDescription, BasicMonitor.subProgress(progressMonitor, 1));
+          }
 
           IContainer sourceContainer = project;
           if (javaSource.segmentCount() > 1)
@@ -1000,9 +1010,14 @@
             }
           }
 
-          javaProject.setRawClasspath
-            (classpathEntries.toArray(new IClasspathEntry[classpathEntries.size()]),
-             BasicMonitor.subProgress(progressMonitor, 1));
+          // Avoid setting the classpath if it hasn't changed.
+          //
+          IClasspathEntry[] oldRawClasspath = javaProject.getRawClasspath();
+          IClasspathEntry[] newRawClasspath = classpathEntries.toArray(new IClasspathEntry[classpathEntries.size()]);
+          if (!Arrays.equals(oldRawClasspath, newRawClasspath))
+          {
+            javaProject.setRawClasspath(newRawClasspath, BasicMonitor.subProgress(progressMonitor, 1));
+          }
         }
 
         if (isInitiallyEmpty)
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/generator/AbstractGeneratorAdapter.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/generator/AbstractGeneratorAdapter.java
index 8f9c10f..bb20839 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/generator/AbstractGeneratorAdapter.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/generator/AbstractGeneratorAdapter.java
@@ -1895,17 +1895,65 @@
         arguments = new Object[] { generatingObject };
       }
 
-      JControlModel jControlModel = getGenerator().getJControlModel();      
+      final JControlModel jControlModel = getGenerator().getJControlModel();
       JMerger jMerger = null;
+      final boolean shouldMerge = shouldMerge(targetFile);
       if (jControlModel.canMerge())
       {
-        jMerger = new JMerger(jControlModel);
+        // Specialize the merger so that in the case that merging isn't needed, it by-passes all the expensive things like creating a compilation unit and the dictionaries.
+        //
+        jMerger =
+          new JMerger(jControlModel)
+          { 
+            private String compilationUnitContents;
+
+            @Override
+            public void setSourceCompilationUnit(String sourceCompilationUnitContents)
+            {
+              if (shouldMerge)
+              {
+                super.setSourceCompilationUnit(sourceCompilationUnitContents);
+              }
+              else
+              {
+                // Simply record the source.
+                //
+                compilationUnitContents = sourceCompilationUnitContents;
+              }
+            }
+
+            @Override
+            public void merge()
+            {
+              // Do nothing if we're not really merging.
+              //
+              if (shouldMerge)
+              {
+                super.merge();
+              }
+            }
+
+            @Override
+            public String getTargetCompilationUnitContents()
+            {
+              if (shouldMerge)
+              {
+                return super.getTargetCompilationUnitContents();
+              }
+              else
+              {
+                // Ensure that at least the tab conversion and brace style preference are applied to the original emmitter's result.
+                // 
+                return CodeGenUtil.convertFormat(jControlModel.getLeadingTabReplacement(), jControlModel.convertToStandardBraceStyle(), compilationUnitContents);
+              }
+            }
+          };
       }
 
       createImportManager(packageName, className);
       String targetFileContents = null;
       String targetFileEncoding = getEncoding(targetFile);
-      if (shouldMerge(targetFile) && exists(targetFile) && jMerger != null)
+      if (shouldMerge && exists(targetFile) && jMerger != null)
       {
         // Prime the import manager with the existing imports of the target.
         //
@@ -1940,7 +1988,7 @@
         
         try
         {
-          jMerger.setSourceCompilationUnit(jMerger.createCompilationUnitForContents(emitterResult));
+          jMerger.setSourceCompilationUnit(emitterResult);
         }
         catch (RuntimeException runtimeException)
         {
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/GenBase.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/GenBase.java
index 54b3c7f..44a8e0a 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/GenBase.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/GenBase.java
@@ -249,4 +249,9 @@
    * @since 2.3
    */
   String getCopyright(String indentation);
+
+  /**
+   * @since 2.15
+   */
+  void clearCache();
 }
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/generator/GenPackageGeneratorAdapter.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/generator/GenPackageGeneratorAdapter.java
index bc21b67..24d9928 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/generator/GenPackageGeneratorAdapter.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/generator/GenPackageGeneratorAdapter.java
@@ -186,11 +186,6 @@
   @Override
   protected Diagnostic doPostGenerate(Object object, Object projectType)
   {
-    if (MODEL_PROJECT_TYPE.equals(projectType))
-    {
-      ((GenPackage)object).clearCache();
-      return Diagnostic.OK_INSTANCE;
-    }
     return super.doPostGenerate(object, projectType);
   }
 
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenBaseImpl.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenBaseImpl.java
index 21851bf..688a778 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenBaseImpl.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenBaseImpl.java
@@ -77,7 +77,6 @@
 import org.eclipse.emf.common.EMFPlugin;
 import org.eclipse.emf.common.notify.NotificationChain;
 import org.eclipse.emf.common.util.BasicMonitor;
-import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.common.util.Monitor;
 import org.eclipse.emf.common.util.URI;
@@ -100,6 +99,7 @@
 import org.eclipse.emf.ecore.EcorePackage;
 import org.eclipse.emf.ecore.InternalEObject;
 import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.resource.ResourceSet;
 import org.eclipse.emf.ecore.resource.URIConverter;
 import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
@@ -126,7 +126,9 @@
 public abstract class GenBaseImpl extends EObjectImpl implements GenBase
 {
   private static final Pattern SUBSTITUTION_PATTERN = Pattern.compile("\\{\\d+\\}");
-  
+
+  private static final Pattern TAG_PATTERN = Pattern.compile("^[ \\t]*@(\\S+)", Pattern.MULTILINE);
+
   /**
    * The cached value of the '{@link #getGenAnnotations() <em>Gen Annotations</em>}' containment reference list.
    * <!-- begin-user-doc -->
@@ -1339,8 +1341,7 @@
     }
     else
     {
-      Diagnostic diagnostic = EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(instanceTypeName);
-      EGenericType eGenericType = (EGenericType)diagnostic.getData().get(0);
+      EGenericType eGenericType = EcoreValidator.EGenericTypeBuilder.INSTANCE.buildEGenericType(instanceTypeName);
       return getTypeArgument(context, eGenericType, false, erased);
     }
   }
@@ -1720,7 +1721,26 @@
 
     public boolean accept(EModelElement eModelElement, String source, String key, String value)
     {
-      return !(GenModelPackage.eNS_URI.equals(source) && ("documentation".equals(key) || "copyright".equals(key)));
+      if (!(GenModelPackage.eNS_URI.equals(source)))
+      {
+        return true;
+      }
+      else if ("documentation".equals(key) || "copyright".equals(key)) 
+      {
+        return false;
+      }
+      else if ("body".equals(key) || "get".equals(key))
+      {
+        // Generate the annotation information only if the model element comes from an "ecore" resource.
+        // E.g., do not produce this information if the model comes from an "xcore" resource.
+        //
+        Resource eResource = eModelElement.eResource();
+        return eResource == null || "ecore".equals(eResource.getURI().fileExtension());
+      }
+      else
+      {
+        return true;
+      }
     }
   }
 
@@ -1739,31 +1759,31 @@
       String source = eAnnotation.getSource();
       if (source != null)
       {
-        StringBuffer stringBuffer = null;
+        StringBuilder stringBuilder = null;
         for (Map.Entry<String, String> entry : eAnnotation.getDetails())
         {
           String key = entry.getKey();
           String value = entry.getValue();
           if (annotationFilter.accept(eModelElement, source, key, value))
           {
-            if (stringBuffer == null)
+            if (stringBuilder == null)
             {
-              stringBuffer = new StringBuffer(escapeString(source, " ="));
+              stringBuilder = new StringBuilder(escapeString(source, " ="));
             }
-            stringBuffer.append(' ');
-            stringBuffer.append(escapeString(key, " ="));
-            stringBuffer.append("=\'");
-            stringBuffer.append(escapeString(value, ""));
-            stringBuffer.append('\'');
+            stringBuilder.append(' ');
+            stringBuilder.append(escapeString(key, " ="));
+            stringBuilder.append("=\'");
+            stringBuilder.append(escapeString(value, ""));
+            stringBuilder.append('\'');
           }
         }
-        if (stringBuffer != null)
+        if (stringBuilder != null)
         {
           if (result.size() == 0)
           {
             result = new ArrayList<String>();
           }
-          result.add(stringBuffer.toString());
+          result.add(stringBuilder.toString());
         }
       }
     }
@@ -2726,31 +2746,36 @@
     return indent(getImpliciAPITags(excludeOwnDocumentation), indentation);
   }
 
+  private Map<String, String> documentationTags;
+
   /**
    * @since-2.14
    */
   protected Map<String, String> getDocumentationTags()
   {
-    String documentation = getDocumentation();
-    if (documentation != null)
+    if (documentationTags == null)
     {
-      Map<String, String> result = new HashMap<String, String>();
-      int index = 0;
-      String tag = "";
-      Pattern tagPattern = Pattern.compile("^[ \\t]*@(\\S+)", Pattern.MULTILINE);
-      for (Matcher matcher = tagPattern.matcher(documentation); matcher.find();)
+      String documentation = getDocumentation();
+      if (documentation != null)
       {
-        result.put(tag, documentation.substring(index, matcher.start()));
-        index = matcher.end();
-        tag = matcher.group(1);
+        Map<String, String> result = new HashMap<String, String>();
+        int index = 0;
+        String tag = "";
+        for (Matcher matcher = TAG_PATTERN.matcher(documentation); matcher.find();)
+        {
+          result.put(tag, documentation.substring(index, matcher.start()));
+          index = matcher.end();
+          tag = matcher.group(1);
+        }
+        result.put(tag, documentation.substring(index));
+        documentationTags = result;
       }
-      result.put(tag, documentation.substring(index));
-      return result;
+      else
+      {
+        documentationTags = Collections.emptyMap();
+      }
     }
-    else
-    {
-      return Collections.emptyMap();
-    }
+    return documentationTags;
   }
 
   protected String getCopyright(boolean includeGenModelCopyrightTextAsDefault)
@@ -3907,4 +3932,15 @@
     return result;
   }
 
+  public void clearCache()
+  {
+    documentationTags = null;
+    for (EObject eObject : eContents())
+    {
+      if (eObject instanceof GenBase)
+      {
+        ((GenBase)eObject).clearCache();
+      }
+    }
+  }
 }
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenClassImpl.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenClassImpl.java
index 8b42247..207fbe8 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenClassImpl.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenClassImpl.java
@@ -445,14 +445,26 @@
     return getGenModel().getImportedName(getQualifiedClassName());
   }
 
+  private List<GenClass> baseGenClasses;
+
   public List<GenClass> getBaseGenClasses()
   {
-    return collectGenClasses(getEcoreClass().getESuperTypes(), null);
+    if (baseGenClasses == null)
+    {
+      baseGenClasses = collectGenClasses(getEcoreClass().getESuperTypes(), null);
+    }
+    return baseGenClasses;
   }
 
+  private List<GenClass> allBaseGenClasses;
+
   public List<GenClass> getAllBaseGenClasses()
   {
-    return collectGenClasses(getEcoreClass().getEAllSuperTypes(), null);
+    if (allBaseGenClasses == null)
+    {
+      allBaseGenClasses = collectGenClasses(getEcoreClass().getEAllSuperTypes(), null);
+    }
+    return allBaseGenClasses;
   }
 
   public boolean isRawBaseClass(GenClass baseClass)
@@ -1066,30 +1078,41 @@
     }
   }
 
-  private OperationHelper operationHelper = new OperationHelper();
-  
+  private OperationHelper operationHelper;
+
+  @Override
   public void clearCache()
   {
+    super.clearCache();
+
     getAccessorOperations = null;
     setAccessorOperations = null;
     isSetAccessorOperations = null;
     unsetAccessorOperations = null;
 
-    operationHelper = new OperationHelper();
-    
-    // Need to ensure that the cached names are computed in the same order and manner as they are in the generated package interface.
-    //
-    for (GenOperation genOperation : getAllGenOperations(false))
-    {
-      if (getOverrideGenOperation(genOperation) == null)
-      {
-        operationHelper.getUniqueName(genOperation);
-      }
-    }
+    operationHelper = null;
+    genClassConstraints = null;
+    baseGenClasses = null;
+    allBaseGenClasses = null;
+    implementedGenOperations = null;
   }
 
   public String getUniqueName(GenOperation genOperation)
   {
+    if (operationHelper == null)
+    {
+      operationHelper = new OperationHelper();
+      
+      // Need to ensure that the cached names are computed in the same order and manner as they are in the generated package interface.
+      //
+      for (GenOperation otherGenOperation : getAllGenOperations(false))
+      {
+        if (getOverrideGenOperation(otherGenOperation) == null)
+        {
+          operationHelper.getUniqueName(otherGenOperation);
+        }
+      }
+    }
     return operationHelper.getUniqueName(genOperation);
   }
 
@@ -1502,34 +1525,40 @@
     }
   }
 
+  private List<GenOperation> implementedGenOperations;
+
   public List<GenOperation> getImplementedGenOperations()
   {
-    EList<GenClass> implementedGenClasses = new UniqueEList<GenClass>(getImplementedGenClasses());
-    ECollections.reverse(implementedGenClasses);
-    if (needsRootImplementsInterfaceOperations())
+    if (implementedGenOperations == null)
     {
-      GenClass rootImplementsInterface = getGenModel().getRootImplementsInterfaceGenClass();
-      if (rootImplementsInterface != null)
+      EList<GenClass> implementedGenClasses = new UniqueEList<GenClass>(getImplementedGenClasses());
+      ECollections.reverse(implementedGenClasses);
+      if (needsRootImplementsInterfaceOperations())
       {
-        List<GenClass> allBaseClasses = new UniqueEList<GenClass>(rootImplementsInterface.getAllBaseGenClasses());
-        for (Iterator<GenClass> i = allBaseClasses.iterator(); i.hasNext(); )
+        GenClass rootImplementsInterface = getGenModel().getRootImplementsInterfaceGenClass();
+        if (rootImplementsInterface != null)
         {
-          GenClass genClass = i.next();
-          if (genClass.isEObject())
+          List<GenClass> allBaseClasses = new UniqueEList<GenClass>(rootImplementsInterface.getAllBaseGenClasses());
+          for (Iterator<GenClass> i = allBaseClasses.iterator(); i.hasNext(); )
           {
-            i.remove();
+            GenClass genClass = i.next();
+            if (genClass.isEObject())
+            {
+              i.remove();
+            }
           }
+          allBaseClasses.add(rootImplementsInterface);
+          implementedGenClasses.addAll(allBaseClasses);
         }
-        allBaseClasses.add(rootImplementsInterface);
-        implementedGenClasses.addAll(allBaseClasses);
       }
+      implementedGenOperations =
+        collectGenOperations
+          (this,
+           implementedGenClasses,
+           null, 
+           new CollidingGenOperationFilter());
     }
-    return
-      collectGenOperations
-        (this,
-         implementedGenClasses,
-         null, 
-         new CollidingGenOperationFilter());
+    return implementedGenOperations;
   }
 
   public boolean hasImplementedToStringGenOperation()
@@ -3061,15 +3090,21 @@
     }
   }
 
+  private List<String> genClassConstraints;
+
   @Override
   public List<String> getGenConstraints()
   {
-    List<String> result = new UniqueEList<String>(super.getGenConstraints());
-    for (GenOperation genOperation : getInvariantOperations())
+    if (genClassConstraints == null)
     {
-      result.add(genOperation.getName());
+      List<String> result = new UniqueEList<String>(super.getGenConstraints());
+      for (GenOperation genOperation : getInvariantOperations())
+      {
+        result.add(genOperation.getName());
+      }
+      genClassConstraints = result;
     }
-    return result;
+    return genClassConstraints;
   }
 
   /**
@@ -3513,13 +3548,14 @@
     {
       boolean hasBody = genOperation.hasBody() || genOperation.hasInvocationDelegate();
 
-      if (genOperation.getName().startsWith("isSet") && genOperation.getGenParameters().isEmpty())
+      String name = genOperation.getName();
+      if (name.startsWith("isSet") && genOperation.getGenParameters().isEmpty())
       {
         for (GenFeature genFeature : allGenFeatures)
         {
           if (genFeature.isChangeable() &&
                 genFeature.isUnsettable() &&
-                genOperation.getName().equals("isSet" + genFeature.getAccessorName()) &&
+                name.equals("isSet" + genFeature.getAccessorName()) &&
                 (!hasBody ||
                   !extendsGenClassFeatures.contains(genFeature) &&
                     (genFeature.isVolatile() && !genFeature.hasDelegateFeature() ||
@@ -3529,13 +3565,12 @@
           }
         }
       }
-      else if ((genOperation.getName().startsWith("get") || genOperation.getName().startsWith("is")) &&
-                 genOperation.getGenParameters().isEmpty())
+      else if ((name.startsWith("get") || name.startsWith("is")) && genOperation.getGenParameters().isEmpty())
       {
         String operationType = genOperation.getType(GenClassImpl.this);
         for (GenFeature genFeature : allGenFeatures)
         {
-          if (genFeature.getGetAccessor().equals(genOperation.getName()) &&
+          if (genFeature.getGetAccessor().equals(name) &&
                 (genFeature.getType(GenClassImpl.this).equals(operationType) || !extendsGenClassFeatures.contains(genFeature)) &&
                 (!hasBody ||
                     !extendsGenClassFeatures.contains(genFeature) &&
@@ -3546,14 +3581,14 @@
           }
         }
       }
-      else if (genOperation.getName().startsWith("set") && genOperation.getGenParameters().size() == 1)
+      else if (name.startsWith("set") && genOperation.getGenParameters().size() == 1)
       {
         GenParameter genParameter = genOperation.getGenParameters().get(0);
         for (GenFeature genFeature : allGenFeatures)
         {
           if (genFeature.isChangeable() &&
                 !genFeature.isListType() &&
-                genOperation.getName().equals("set" + genFeature.getAccessorName()) &&
+                name.equals("set" + genFeature.getAccessorName()) &&
                 genParameter.getType(GenClassImpl.this).equals(genFeature.getType(GenClassImpl.this)) &&
                 (!hasBody ||
                   !extendsGenClassFeatures.contains(genFeature) &&
@@ -3564,13 +3599,13 @@
           }
         }
       }
-      else if (genOperation.getName().startsWith("unset") && genOperation.getGenParameters().isEmpty())
+      else if (name.startsWith("unset") && genOperation.getGenParameters().isEmpty())
       {
         for (GenFeature genFeature : allGenFeatures)
         {
           if (genFeature.isChangeable() &&
                 genFeature.isUnsettable() &&
-                genOperation.getName().equals("unset" + genFeature.getAccessorName()) &&
+                name.equals("unset" + genFeature.getAccessorName()) &&
                 (!hasBody ||
                   !extendsGenClassFeatures.contains(genFeature) &&
                     (genFeature.isVolatile() && !genFeature.hasDelegateFeature() ||
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenClassifierImpl.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenClassifierImpl.java
index 23dbe22..8a7fcde 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenClassifierImpl.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenClassifierImpl.java
@@ -371,16 +371,28 @@
     return uncapPrefixedName(getName()) + getMetaType();
   }
 
+  private String classifierID;
+
   public String getClassifierID()
   {
-    String name = getName();
-    String prefix = getGenPackage().getPrefix();
-    return format(name, '_', prefix, true, true).toUpperCase(getGenModel().getLocale());
+    if (classifierID == null)
+    {
+      String name = getName();
+      String prefix = getGenPackage().getPrefix();
+      classifierID = format(name, '_', prefix, true, true).toUpperCase(getGenModel().getLocale());
+    }
+    return classifierID;
   }
 
+  private List<String> genConstraints;
+
   public List<String> getGenConstraints()
   {
-    return EcoreUtil.getConstraints(getEcoreClassifier());
+    if (genConstraints == null)
+    {
+      genConstraints = EcoreUtil.getConstraints(getEcoreClassifier());
+    }
+    return genConstraints;
   }
 
   public List<String> getAllGenConstraints()
@@ -456,4 +468,12 @@
     }
     return null;
   }
+
+  @Override
+  public void clearCache()
+  {
+    super.clearCache();
+    classifierID = null;
+    genConstraints = null;
+  }
 }
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenFeatureImpl.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenFeatureImpl.java
index b1f1e50..068703a 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenFeatureImpl.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenFeatureImpl.java
@@ -1190,34 +1190,45 @@
     return result;
   }
 
+  private String getAccessor;
+
   public String getGetAccessor()
   {
-    String capName = getCapName();
-    if (isMapEntryFeature()) return "getTyped" + capName;
-    String result = isBooleanType() ? "is" + capName : "get" + ("Class".equals(capName) ? "Class_" : capName);
-    
-    if (isListType() && !isFeatureMapType() && !isMapType() && getGenModel().isArrayAccessors())
+    if (getAccessor == null)
     {
-      result += "List";
-    }
-
-    GenClass rootImplementsInterface = getGenModel().getRootImplementsInterfaceGenClass();
-    GenClass context = getContext();
-    if (rootImplementsInterface != null && !rootImplementsInterface.isEObject())
-    {
-      for (GenOperation genOperation : rootImplementsInterface.getAllGenOperations())
+      String capName = getCapName();
+      if (isMapEntryFeature())
       {
-        if (genOperation.getName().equals(result) && 
-              genOperation.getGenParameters().isEmpty() && 
-              !genOperation.getType(context).equals(getType(context)))
+        getAccessor = "getTyped" + capName;
+      }
+      else
+      {
+        String result = isBooleanType() ? "is" + capName : "get" + ("Class".equals(capName) ? "Class_" : capName);
+        if (isListType() && !isFeatureMapType() && !isMapType() && getGenModel().isArrayAccessors())
         {
-          result = result + "_";
-          break;
+          result += "List";
         }
+
+        GenClass rootImplementsInterface = getGenModel().getRootImplementsInterfaceGenClass();
+        GenClass context = getContext();
+        if (rootImplementsInterface != null && !rootImplementsInterface.isEObject())
+        {
+          for (GenOperation genOperation : rootImplementsInterface.getAllGenOperations())
+          {
+            if (genOperation.getGenParameters().isEmpty() &&
+                  genOperation.getName().equals(result) &&
+                  !genOperation.getType(context).equals(getType(context)))
+            {
+              result = result + "_";
+              break;
+            }
+          }
+        }
+
+        getAccessor = result;
       }
     }
-
-    return result;
+    return getAccessor;
   }
 
   public String getSafeName()
@@ -2615,4 +2626,11 @@
     GenClass genClass = getGenClass();
     return genClass.getRawQualifiedInterfaceName() + (!genClass.isMapEntry() && !isSuppressedGetVisibility() ? "#" + getGetAccessor() + "()" : "");
   }
+
+  @Override
+  public void clearCache()
+  {
+    super.clearCache();
+    getAccessor = null;
+  }
 } //GenFeatureImpl
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenModelImpl.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenModelImpl.java
index aa3fc0b..5efc881 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenModelImpl.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenModelImpl.java
@@ -38,12 +38,6 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.preferences.IScopeContext;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.ToolFactory;
-import org.eclipse.jdt.core.formatter.CodeFormatter;
-
 import org.eclipse.emf.codegen.ecore.CodeGenEcorePlugin;
 import org.eclipse.emf.codegen.ecore.Generator;
 import org.eclipse.emf.codegen.ecore.generator.AbstractGeneratorAdapter;
@@ -55,19 +49,19 @@
 import org.eclipse.emf.codegen.ecore.genmodel.GenDecoration;
 import org.eclipse.emf.codegen.ecore.genmodel.GenDelegationKind;
 import org.eclipse.emf.codegen.ecore.genmodel.GenEclipsePlatformVersion;
-import org.eclipse.emf.codegen.ecore.genmodel.GenJDKLevel;
 import org.eclipse.emf.codegen.ecore.genmodel.GenEnum;
 import org.eclipse.emf.codegen.ecore.genmodel.GenEnumLiteral;
 import org.eclipse.emf.codegen.ecore.genmodel.GenFeature;
+import org.eclipse.emf.codegen.ecore.genmodel.GenJDKLevel;
 import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
 import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory;
 import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
 import org.eclipse.emf.codegen.ecore.genmodel.GenOperation;
 import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
-import org.eclipse.emf.codegen.ecore.genmodel.GenRuntimePlatform;
-import org.eclipse.emf.codegen.ecore.genmodel.GenRuntimeVersion;
 import org.eclipse.emf.codegen.ecore.genmodel.GenParameter;
 import org.eclipse.emf.codegen.ecore.genmodel.GenResourceKind;
+import org.eclipse.emf.codegen.ecore.genmodel.GenRuntimePlatform;
+import org.eclipse.emf.codegen.ecore.genmodel.GenRuntimeVersion;
 import org.eclipse.emf.codegen.ecore.genmodel.GenTypeParameter;
 import org.eclipse.emf.codegen.ecore.genmodel.util.GenModelUtil;
 import org.eclipse.emf.codegen.jet.JETCompiler;
@@ -121,6 +115,11 @@
 import org.eclipse.emf.ecore.xml.namespace.XMLNamespacePackage;
 import org.eclipse.emf.ecore.xml.type.XMLTypeFactory;
 import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.formatter.CodeFormatter;
 
 
 /**
@@ -3268,7 +3267,6 @@
   @Override
   public boolean canGenerate()
   {
-    clearCache();
     return canGenerate && hasModelSupport();
   }
 
@@ -3596,7 +3594,6 @@
   @Override
   public boolean canGenerateEdit()
   {
-    clearCache();
     return canGenerate && hasEditSupport();
   }
 
@@ -3707,7 +3704,6 @@
   @Override
   public boolean canGenerateEditor()
   {
-    clearCache();
     return canGenerate && hasEditorSupport();
   }
 
@@ -3851,7 +3847,6 @@
   @Override
   public boolean canGenerateTests()
   {
-    clearCache();
     return canGenerate && hasTestSupport();
   }
 
@@ -5211,16 +5206,22 @@
     return genPackage != null ? genPackage.getQualifiedPackageName() : getModelDirectory();
   }
 
+  private GenPackage mainGenPackage;
+
   protected GenPackage getMainGenPackage()
   {
     if (!getGenPackages().isEmpty())
     {
-      GenPackage genPackage = getGenPackages().get(0);
-      while (genPackage.getGenClassifiers().isEmpty() && !genPackage.getNestedGenPackages().isEmpty())
+      if (mainGenPackage == null)
       {
-        genPackage = genPackage.getNestedGenPackages().get(0);
+        GenPackage genPackage = getGenPackages().get(0);
+        while (genPackage.getGenClassifiers().isEmpty() && !genPackage.getNestedGenPackages().isEmpty())
+        {
+          genPackage = genPackage.getNestedGenPackages().get(0);
+        }
+        mainGenPackage = genPackage;
       }
-      return genPackage;
+      return mainGenPackage;
     }
     return null;
   }
@@ -9759,8 +9760,10 @@
     }
   }
 
-  private void clearCache()
+  @Override
+  public void clearCache()
   {
+    super.clearCache();
     if (eClassifierToGenClassifierMap != null)
     {
       eClassifierToGenClassifierMap.clear();
@@ -9770,6 +9773,7 @@
       ePackageToGenPackageMap.clear();
     }
     bundleHelper.flush();
+    mainGenPackage = null;
   }
 
   public List<GenPackage> computeMissingUsedGenPackages()
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenOperationImpl.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenOperationImpl.java
index a083db8..1a84022 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenOperationImpl.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenOperationImpl.java
@@ -1248,7 +1248,6 @@
     else
     {
       return
-        getReturnType() != null && 
           "boolean".equals(getReturnType()) &&
           getGenParameters().size() == 2 &&
           "org.eclipse.emf.common.util.DiagnosticChain".equals
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenPackageImpl.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenPackageImpl.java
index c756119..12defda 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenPackageImpl.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenPackageImpl.java
@@ -2406,25 +2406,30 @@
     return result;
   }
 
+  private List<GenClass> orderedGenClasses;
+
   public List<GenClass> getOrderedGenClasses()
   {
-    List<GenClass> result = new ArrayList<GenClass>();
-    Set<GenClass> resultSet = new HashSet<GenClass>();
-
-    for (Iterator<GenClass> iter = getGenClasses().iterator(); iter.hasNext(); )
+    if (orderedGenClasses == null)
     {
-      List<GenClass> extendChain = new LinkedList<GenClass>();
-      Set<GenClass> visited = new HashSet<GenClass>();
-      for (GenClass genClass = iter.next(); genClass != null && visited.add(genClass); genClass = genClass.getBaseGenClass())
+      orderedGenClasses = new ArrayList<GenClass>();
+      Set<GenClass> resultSet = new HashSet<GenClass>();
+
+      for (Iterator<GenClass> iter = getGenClasses().iterator(); iter.hasNext(); )
       {
-        if (this == genClass.getGenPackage() && resultSet.add(genClass))
+        List<GenClass> extendChain = new LinkedList<GenClass>();
+        Set<GenClass> visited = new HashSet<GenClass>();
+        for (GenClass genClass = iter.next(); genClass != null && visited.add(genClass); genClass = genClass.getBaseGenClass())
         {
-          extendChain.add(0, genClass);
+          if (this == genClass.getGenPackage() && resultSet.add(genClass))
+          {
+            extendChain.add(0, genClass);
+          }
         }
+        orderedGenClasses.addAll(extendChain);
       }
-      result.addAll(extendChain);
     }
-    return result;
+    return orderedGenClasses;
   }
 
   public List<GenClassifier> getOrderedGenClassifiers()
@@ -2458,22 +2463,38 @@
     }
     else
     {
+      if (dependencyHelper == null)
+      {
+        dependencyHelper = new DependencyHelper();
+      }
       return dependencyHelper.getSimpleDependencies();
     }
   }
 
   public List<GenPackage> getPackageInterDependencies()
   {
+    if (dependencyHelper == null)
+    {
+      dependencyHelper = new DependencyHelper();
+    }
     return dependencyHelper.getInterDependencies();
   }
 
   public List<GenPackage> getPackageLoadInterDependencies()
   {
+    if (dependencyHelper == null)
+    {
+      dependencyHelper = new DependencyHelper();
+    }
     return dependencyHelper.getLoadInterDependencies();
   }
 
   public List<GenPackage> getPackageBuildInterDependencies()
   {
+    if (dependencyHelper == null)
+    {
+      dependencyHelper = new DependencyHelper();
+    }
     return dependencyHelper.getBuildInterDependencies();
   }
 
@@ -2485,6 +2506,10 @@
     }
     else
     {
+      if (dependencyHelper == null)
+      {
+        dependencyHelper = new DependencyHelper();
+      }
       return dependencyHelper.getInitializationDependencies();
     }
   }
@@ -2494,10 +2519,14 @@
     if (genPackage == this) return "this";
     if (genPackage.getEcorePackage() == EcorePackage.eINSTANCE) return "ecorePackage";
 
+    if (dependencyHelper == null)
+    {
+      dependencyHelper = new DependencyHelper();
+    }
     return "the" + dependencyHelper.getUniqueName(genPackage);
   }
 
-  private DependencyHelper dependencyHelper = null;
+  private DependencyHelper dependencyHelper;
 
   private class DependencyHelper extends GenBaseImpl.UniqueNameHelper
   {
@@ -2790,26 +2819,32 @@
     return !getJavaLangConflicts().isEmpty();
   }
 
+  private List<String> javaLanguageConflicts;
+
   public List<String> getJavaLangConflicts()
   {
-    List<String> result = new ArrayList<String>();
-    for (GenClass genClass : getGenClasses())
+    if (javaLanguageConflicts == null)
     {
-      String name = genClass.getName();
-      if (CodeGenUtil.isJavaDefaultType(name))
+      List<String> result = new ArrayList<String>();
+      for (GenClass genClass : getGenClasses())
       {
-        result.add(name);
+        String name = genClass.getName();
+        if (CodeGenUtil.isJavaDefaultType(name))
+        {
+          result.add(name);
+        }
       }
-    }
-    for (GenEnum genEnum : getGenEnums())
-    {
-      String name = genEnum.getName();
-      if (CodeGenUtil.isJavaDefaultType(name))
+      for (GenEnum genEnum : getGenEnums())
       {
-        result.add(name);
+        String name = genEnum.getName();
+        if (CodeGenUtil.isJavaDefaultType(name))
+        {
+          result.add(name);
+        }
       }
+      javaLanguageConflicts = result;
     }
-    return result;
+    return javaLanguageConflicts;
   }
 
   public boolean hasInterfaceImplConflict()
@@ -2856,7 +2891,7 @@
     return switchHelper.getUniqueName(genClass);
   }
 
-  private SwitchHelper switchHelper = null;
+  private SwitchHelper switchHelper;
 
   private class SwitchHelper extends GenBaseImpl.UniqueNameHelper
   {
@@ -2943,7 +2978,7 @@
     return validatorHelper.getPackageUniqueSafeName(genPackage);
   }
 
-  private ValidatorHelper validatorHelper = null;
+  private ValidatorHelper validatorHelper;
 
   private class ValidatorHelper extends UniqueNameHelper
   {
@@ -3381,22 +3416,22 @@
    */
   public void prepareCache()
   {
-    // Create helpers to cache and supply information for unique naming
-    switchHelper = new SwitchHelper();
-    validatorHelper = new ValidatorHelper();
-    dependencyHelper = new DependencyHelper();
-    annotationSourceHelper = new AnnotationSourceHelper();
+    // All helpers are demand created now to avoid expensive overhead that might not be used.
   }
 
   /**
    * Clear the cache for unique naming information.
    */
+  @Override
   public void clearCache()
   {
+    super.clearCache();
     switchHelper = null;
     validatorHelper = null;
     dependencyHelper = null;
     annotationSourceHelper = null;
+    orderedGenClasses = null;
+    javaLanguageConflicts = null;
   }
 
   /**
@@ -3472,9 +3507,10 @@
           Object generator = theGeneratorClass.newInstance();
 
           // Set the mapper to build an XSD2EcoreMappingRoot, if available.
+          // As of EMF 2.15, I've disabled this.
           //
           Bundle xsd2ecorePlugin = Platform.getBundle("org.eclipse.emf.mapping.xsd2ecore");
-          if (xsd2ecorePlugin != null)
+          if (Boolean.FALSE && xsd2ecorePlugin != null)
           {
             try
             {
@@ -4381,7 +4417,7 @@
     return result;
   }
 
-  private AnnotationSourceHelper annotationSourceHelper = null;
+  private AnnotationSourceHelper annotationSourceHelper;
 
   private class AnnotationSourceHelper extends GenBaseImpl.UniqueNameHelper
   {
@@ -4426,6 +4462,10 @@
 
   public String getAnnotationSourceIdentifier(String annotationSource)
   {
+    if (annotationSourceHelper == null)
+    {
+      annotationSourceHelper = new AnnotationSourceHelper();
+    }
     return annotationSourceHelper.getUniqueName(annotationSource);
   }
 
diff --git a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenTypedElementImpl.java b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenTypedElementImpl.java
index f7aca47..1072cdc 100644
--- a/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenTypedElementImpl.java
+++ b/plugins/org.eclipse.emf.codegen.ecore/src/org/eclipse/emf/codegen/ecore/genmodel/impl/GenTypedElementImpl.java
@@ -21,7 +21,6 @@
 import org.eclipse.emf.codegen.ecore.genmodel.GenTypedElement;
 import org.eclipse.emf.codegen.util.CodeGenUtil;
 import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.common.util.EList;
 
 import org.eclipse.emf.ecore.EClass;
@@ -762,8 +761,7 @@
       return false;
     }
     String substitutedType = getTypeArgument(context, actualEGenericType, false, false);
-    Diagnostic diagnostic = EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(substitutedType);
-    EGenericType eGenericType = (EGenericType)diagnostic.getData().get(0);
+    EGenericType eGenericType = EcoreValidator.EGenericTypeBuilder.INSTANCE.buildEGenericType(substitutedType);
     if (eGenericType != null)
     {
       // Type parameter casts can't be checked.
diff --git a/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/merge/java/JMerger.java b/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/merge/java/JMerger.java
index 1dfe8f4..ec1984f 100644
--- a/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/merge/java/JMerger.java
+++ b/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/merge/java/JMerger.java
@@ -385,6 +385,14 @@
     return sourceCompilationUnit;
   }
 
+  /**
+   * @since 2.15
+   */
+  public void setSourceCompilationUnit(String sourceCompilationUnitContents)
+  {
+    setSourceCompilationUnit(createCompilationUnitForContents(sourceCompilationUnitContents));
+  }
+
   public void setSourceCompilationUnit(JCompilationUnit sourceCompilationUnit)
   {
     this.sourceCompilationUnit =  sourceCompilationUnit;
diff --git a/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/util/CodeGenUtil.java b/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/util/CodeGenUtil.java
index 23f611d..808c4cc 100644
--- a/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/util/CodeGenUtil.java
+++ b/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/util/CodeGenUtil.java
@@ -23,7 +23,6 @@
 import java.util.ListIterator;
 import java.util.Locale;
 import java.util.Set;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.osgi.framework.Bundle;
@@ -287,7 +286,7 @@
    */
   public static boolean isJavaLangType(String s)
   {
-    return getJavaDefaultTypes().contains(s) && Character.isUpperCase(s.charAt(0));
+    return getJavaDefaultTypes().contains(s) && isUpperCase(s.charAt(0));
   }
 
   /**
@@ -295,7 +294,7 @@
    */
   public static boolean isJavaPrimitiveType(String s)
   {
-    return getJavaDefaultTypes().contains(s) && Character.isLowerCase(s.charAt(0));
+    return getJavaDefaultTypes().contains(s) && isLowerCase(s.charAt(0));
   }
 
   // Interprets escaped characters within the string according to Java
@@ -468,7 +467,7 @@
           break;
         }
       }
-      if (i > 1 && i < name.length() && !Character.isDigit(name.charAt(i))) 
+      if (i > 1 && i < name.length() && !isDigit(name.charAt(i))) 
       {
         --i;
       }
@@ -536,7 +535,7 @@
     List<String> parsedName = new ArrayList<String>();
     if (prefix != null && 
           name.startsWith(prefix) && 
-          name.length() > prefix.length() && Character.isUpperCase(name.charAt(prefix.length())))
+          name.length() > prefix.length() && isUpperCase(name.charAt(prefix.length())))
     {
       name = name.substring(prefix.length());
       if (includePrefix)
@@ -590,7 +589,7 @@
       for (int index = 0, length = sourceName.length(); index < length; ++index)
       {
         char curChar = sourceName.charAt(index);
-        if (Character.isUpperCase(curChar) || (!lastIsLower && Character.isDigit(curChar)) || curChar == separator)
+        if (isUpperCase(curChar) || (!lastIsLower && isDigit(curChar)) || curChar == separator)
         {
           if (lastIsLower && currentWord.length() > 1 || curChar == separator && currentWord.length() > 0)
           {
@@ -643,7 +642,7 @@
       for (int index = 0, length = sourceName.length(); index < length; index = sourceName.offsetByCodePoints(index, 1))
       {
         int codePoint = sourceName.charAt(index);
-        if (Character.isUpperCase(codePoint) || (!lastIsLower && Character.isDigit(codePoint)) ||  Character.isJavaIdentifierPart(codePoint))
+        if (isUpperCase(codePoint) || (!lastIsLower && isDigit(codePoint)) ||  Character.isJavaIdentifierPart(codePoint))
         {
           if (lastIsLower && currentWord.length() > 1 || (codePoint == '$' || codePoint == '_') && currentWord.length() > 0)
           {
@@ -838,112 +837,155 @@
 
     if (convertToStandardBraceStyle)
     {
-      FindAndReplace findAndReplaceLineWithJustABrace = 
-        new FindAndReplace(BRACE_LINE_PATTERN)
-        {
-          @Override
-          public boolean handleMatch(int offset, Matcher matcher)
-          {
-            if (matcher.groupCount() >= 1)
-            {
-              int begin = offset + matcher.start(1);
-
-              // Don't do replacement if we just did one, or if previous line
-              // ended with a semicolon.
-              //
-              if (current != 0 && (begin <= current || string.charAt(begin - 1) == ';'))
-              {
-                return true;
-              }
-
-              // Don't do replacement if previous line ended with a comment.
-              //
-              for (int i = begin - 1; i >= current; --i)
-              {
-                char character = string.charAt(i);
-                if (character == '\n' || character == '\r' || i == current)
-                {
-                  boolean slash = false;
-                  while (++i < begin)
-                  {
-                    character = string.charAt(i);
-                    if (character == '/')
-                    {
-                      if (slash)
-                      {
-                        return true;
-                      }
-                      slash = true;
-                    }
-                    else
-                    {
-                      slash = false;
-                    }
-                  }
-
-                  break;
-                }
-              }
-
-              int end = offset + matcher.end(1);
-              replace(begin, end, " {"); // }
-            }
-            return true;
-          }
-        };
-      value = findAndReplaceLineWithJustABrace.apply(value);
+      value = new BraceFixer().apply(value);
     }
 
     return value;
   }
 
-  private static abstract class FindAndReplace
+  private static class BraceFixer
   {
-    protected Pattern pattern;
-    protected String string;
-    protected StringBuilder stringBuilder;
-    protected int current;
+    protected char[] string;
 
-    public FindAndReplace(Pattern pattern)
-    {
-      this.pattern = pattern;
-    }
+    protected StringBuilder stringBuilder;
+
+    protected int current;
 
     public String apply(String string)
     {
       current = 0;
-      this.string = string;
+      this.string = string.toCharArray();
       this.stringBuilder = new StringBuilder();
 
-      for (int start = 0, end = string.length(); start < end; )
+      for (int i = 0, length = this.string.length; i < length; ++i)
       {
-        Matcher matcher = pattern.matcher(string.subSequence(start, end));
-        if (matcher.find())
+        char character = this.string[i];
+        if (character == '{') // }
         {
-          if (!handleMatch(start, matcher))
+          int end = scanForLineEnd(i + 1);
+          if (end != -1)
+          {
+            int begin = scanForStart(i - 1);
+            if (begin != -1)
+            {
+              handleMatch(begin, end);
+              i = end;
+            }
+          }
+        }
+      }
+
+      stringBuilder.append(this.string, current, this.string.length - current);
+      return stringBuilder.toString();
+    }
+
+    private int scanForLineEnd(int index)
+    {
+      for (int i = index, length = string.length; i < length; ++i)
+      {
+        char character = string[i];
+        if (character == '\n')
+        {
+          return i;
+        }
+        else if (character == '\r')
+        {
+          ++i;
+          if (i < length && string[i] == '\n')
+          {
+            return i - 1;
+          }
+          else
           {
             break;
           }
-          start += matcher.end();
         }
-        else
+        else if (character != ' ' && character != '\t')
         {
           break;
         }
       }
+      return -1;
+    }
 
-      stringBuilder.append(string.substring(current));
-      return stringBuilder.toString();
+    private int scanForStart(int index)
+    {
+      boolean sawLineFeed = false;
+      for (int i = index; i >=0; --i)
+      {
+        char character = string[i];
+        if (character == '\n')
+        {
+          if (i > 0 && string[i - 1] == '\r')
+          {
+            --i;
+          }
+          sawLineFeed = true;
+        }
+        else if (character != ' ' && character != '\t')
+        {
+          if (sawLineFeed)
+          {
+            return i + 1;
+          }
+          else
+          {
+            return -1;
+          }
+        }
+      }
+      return -1;
     }
 
     public void replace(int begin, int end, String replacement)
     {
-      stringBuilder.append(string.substring(current, begin));
+      stringBuilder.append(string, current, begin - current);
       stringBuilder.append(replacement);
       current = end;
     }
 
-    public abstract boolean handleMatch(int offset, Matcher matcher);
+    public boolean handleMatch(int begin, int end)
+    {
+      // Don't do replacement if we just did one, or if previous line
+      // ended with a semicolon.
+      //
+      if (current != 0 && (begin <= current || string[begin - 1] == ';'))
+      {
+        return true;
+      }
+
+      // Don't do replacement if previous line ended with a comment.
+      //
+      for (int i = begin - 1; i >= current; --i)
+      {
+        char character = string[i];
+        if (character == '\n' || character == '\r' || i == current)
+        {
+          boolean slash = false;
+          while (++i < begin)
+          {
+            character = string[i];
+            if (character == '/')
+            {
+              if (slash)
+              {
+                return true;
+              }
+              slash = true;
+            }
+            else
+            {
+              slash = false;
+            }
+          }
+
+          break;
+        }
+      }
+
+      replace(begin, end, " {"); // }
+      return true;
+    }
   }
 
   /**
@@ -1104,6 +1146,42 @@
     return false;
   }
 
+  private static boolean isUpperCase(int codePoint)
+  {
+    if (codePoint < 128)
+    {
+      return codePoint >= 'A' && codePoint <= 'Z';
+    }
+    else
+    {
+      return Character.isUpperCase(codePoint);
+    }
+  }
+
+  private static boolean isLowerCase(int codePoint)
+  {
+    if (codePoint < 128)
+    {
+      return codePoint >= 'a' && codePoint <= 'z';
+    }
+    else
+    {
+      return Character.isLowerCase(codePoint);
+    }
+  }
+
+  private static boolean isDigit(int codePoint)
+  {
+    if (codePoint < 128)
+    {
+      return codePoint >= '0' && codePoint <= '9';
+    }
+    else
+    {
+      return Character.isDigit(codePoint);
+    }
+  }
+
   public static class EclipseUtil
   {
     /**
@@ -1144,6 +1222,15 @@
       {
         // Ignore the absence of the new version support in older runtimes.
       }
+      try
+      {
+        Field field = AST.class.getField("JLS10");
+        jls = (Integer)field.get(null);
+      }
+      catch (Throwable exception)
+      {
+        // Ignore the absence of the new version support in older runtimes.
+      }
       JLS = jls;
     }
 
@@ -1157,7 +1244,8 @@
     }
 
     /**
-     * Return an ASTParser that supports the latest language level in the version of the JDT in the installed runtime or JLS4 otherwise.
+     * Return an ASTParser that supports the latest language level in the version of the JDT in the installed runtime, if {@code latest} is {@code true},
+     * or at most JLS4 otherwise.
      * @since 2.14
      */
     public static ASTParser newASTParser(boolean latest)
diff --git a/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/util/ImportManager.java b/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/util/ImportManager.java
index a0e6e40..e6a95d4 100644
--- a/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/util/ImportManager.java
+++ b/plugins/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/util/ImportManager.java
@@ -18,6 +18,7 @@
 import java.util.List;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -209,7 +210,7 @@
 
     for (int i = 0; i < srcLength; i++)
     {
-      if (Character.isWhitespace(src[i]))
+      if (src[i] <= ' ')
       {
         if (result == null)
         {
@@ -685,10 +686,16 @@
    */
   private static class EclipseHelper
   {
+    private static final AtomicReference<ASTParser> cachedASTParser = new AtomicReference<ASTParser>(null);
+
     public static List<String> getCompilationUnitImports(String compilationUnitContents)
     {
       List<String> result = new ArrayList<String>();
-      ASTParser parser = CodeGenUtil.EclipseUtil.newASTParser();
+      ASTParser parser = cachedASTParser.getAndSet(null);
+      if (parser == null)
+      {
+        parser = CodeGenUtil.EclipseUtil.newASTParser(true);
+      }
       parser.setSource(compilationUnitContents.toCharArray());
       CompilationUnit compilationUnit = (CompilationUnit)parser.createAST(new NullProgressMonitor());
       for (Iterator<?> i = compilationUnit.imports().iterator(); i.hasNext();)
@@ -696,10 +703,12 @@
         ImportDeclaration importDeclaration = (ImportDeclaration)i.next();
         result.add(importDeclaration.getName().getFullyQualifiedName());
       }
+      cachedASTParser.set(parser);
       return result;
     }
   }
 
+
   /**
    * Records the given <code>StringBuilder</code> and its current length, so that computed imports can later be
    * {@link #emitSortedImports() emitted}, and {@link #addCompilationUnitImports(String) adds} any import declarations
diff --git a/plugins/org.eclipse.emf.ecore.xcore.ui/src/org/eclipse/emf/ecore/xcore/ui/builder/XcoreFileSystemAccess.java b/plugins/org.eclipse.emf.ecore.xcore.ui/src/org/eclipse/emf/ecore/xcore/ui/builder/XcoreFileSystemAccess.java
index 0caa867..30d542a 100644
--- a/plugins/org.eclipse.emf.ecore.xcore.ui/src/org/eclipse/emf/ecore/xcore/ui/builder/XcoreFileSystemAccess.java
+++ b/plugins/org.eclipse.emf.ecore.xcore.ui/src/org/eclipse/emf/ecore/xcore/ui/builder/XcoreFileSystemAccess.java
@@ -7,11 +7,16 @@
  */
 package org.eclipse.emf.ecore.xcore.ui.builder;
 
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Set;
 
+import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.emf.ecore.xcore.generator.XcoreGenModelGeneratorAdapterFactory;
 import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
@@ -33,4 +38,63 @@
   {
     getCallBack().afterFileUpdate(root.getFile(new Path(file)));
   }
+
+  @Override
+  protected boolean hasContentsChanged(IFile file, InputStream newContent)
+  {
+    BufferedInputStream oldContent = null;
+    try
+    {
+      oldContent = new BufferedInputStream(file.getContents());
+      byte[] newBytes = new byte[4048];
+      byte[] oldBytes = new byte[4048];
+      while (true)
+      {
+        int newBytesRead = newContent.read(newBytes);
+        int oldBytesRead = oldContent.read(oldBytes);
+        
+        if (newBytesRead != oldBytesRead)
+        {
+          return true;
+        }
+        else
+        {
+          for (int i = 0; i < newBytesRead; ++i)
+          {
+            if (newBytes[i] != oldBytes[i])
+            {
+              return true;
+            }
+          }
+
+          if (newBytesRead < 4048)
+          {
+            return false;
+          }
+        }
+      }
+    }
+    catch (CoreException e)
+    {
+      return true;
+    }
+    catch (IOException e)
+    {
+      return true;
+    }
+    finally
+    {
+      if (oldContent != null)
+      {
+        try
+        {
+          oldContent.close();
+        }
+        catch (IOException e)
+        {
+          // ignore
+        }
+      }
+    }
+  }
 }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAnnotation.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAnnotation.java
index b40804d..fa462da 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAnnotation.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAnnotation.java
@@ -18,12 +18,12 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XAnnotation#getSource <em>Source</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XAnnotation#getDetails <em>Details</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XAnnotation#getModelElement <em>Model Element</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXAnnotation()
  * @model
@@ -69,7 +69,7 @@
    * <!-- end-user-doc -->
    * @return the value of the '<em>Details</em>' map.
    * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXAnnotation_Details()
-   * @model mapType="org.eclipse.emf.ecore.xcore.XStringToStringMapEntry<org.eclipse.emf.ecore.EString, org.eclipse.emf.ecore.EString>"
+   * @model mapType="org.eclipse.emf.ecore.xcore.XStringToStringMapEntry&lt;org.eclipse.emf.ecore.EString, org.eclipse.emf.ecore.EString&gt;"
    * @generated
    */
   EMap<String, String> getDetails();
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAnnotationDirective.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAnnotationDirective.java
index 692ce47..f8f30aa 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAnnotationDirective.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAnnotationDirective.java
@@ -15,11 +15,11 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XAnnotationDirective#getSourceURI <em>Source URI</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XAnnotationDirective#getPackage <em>Package</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXAnnotationDirective()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAttribute.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAttribute.java
index 22d0839..0e33464 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAttribute.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XAttribute.java
@@ -15,11 +15,11 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XAttribute#getDefaultValueLiteral <em>Default Value Literal</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XAttribute#isID <em>ID</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXAttribute()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XClass.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XClass.java
index 5e61066..208ef56 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XClass.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XClass.java
@@ -18,13 +18,13 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XClass#isAbstract <em>Abstract</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XClass#isInterface <em>Interface</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XClass#getMembers <em>Members</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XClass#getSuperTypes <em>Super Types</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXClass()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XClassifier.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XClassifier.java
index 633e0f7..f9ee5da 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XClassifier.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XClassifier.java
@@ -19,12 +19,12 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XClassifier#getInstanceType <em>Instance Type</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XClassifier#getPackage <em>Package</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XClassifier#getTypeParameters <em>Type Parameters</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXClassifier()
  * @model abstract="true"
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XDataType.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XDataType.java
index 1d71b7c..fa620da 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XDataType.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XDataType.java
@@ -18,12 +18,12 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XDataType#isSerializable <em>Serializable</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XDataType#getCreateBody <em>Create Body</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XDataType#getConvertBody <em>Convert Body</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXDataType()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XEnum.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XEnum.java
index d53494d..8b2dd82 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XEnum.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XEnum.java
@@ -18,10 +18,10 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XEnum#getLiterals <em>Literals</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXEnum()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XEnumLiteral.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XEnumLiteral.java
index f2429df..dce74c4 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XEnumLiteral.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XEnumLiteral.java
@@ -15,12 +15,12 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XEnumLiteral#getValue <em>Value</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XEnumLiteral#getLiteral <em>Literal</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XEnumLiteral#getEnum <em>Enum</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXEnumLiteral()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XGenericType.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XGenericType.java
index 5e70a33..61117a5 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XGenericType.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XGenericType.java
@@ -22,13 +22,13 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XGenericType#getUpperBound <em>Upper Bound</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XGenericType#getTypeArguments <em>Type Arguments</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XGenericType#getLowerBound <em>Lower Bound</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XGenericType#getType <em>Type</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXGenericType()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XImportDirective.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XImportDirective.java
index d4fc655..1723614 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XImportDirective.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XImportDirective.java
@@ -18,12 +18,12 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XImportDirective#getImportedNamespace <em>Imported Namespace</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XImportDirective#getImportedObject <em>Imported Object</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XImportDirective#getPackage <em>Package</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXImportDirective()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XMember.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XMember.java
index 4a8b500..afbe1a4 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XMember.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XMember.java
@@ -15,10 +15,10 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XMember#getContainingClass <em>Containing Class</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXMember()
  * @model abstract="true"
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XModelElement.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XModelElement.java
index ef1b794..78b833d 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XModelElement.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XModelElement.java
@@ -20,10 +20,10 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XModelElement#getAnnotations <em>Annotations</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXModelElement()
  * @model abstract="true"
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XNamedElement.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XNamedElement.java
index 0778fca..fc2dc02 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XNamedElement.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XNamedElement.java
@@ -15,10 +15,10 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XNamedElement#getName <em>Name</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXNamedElement()
  * @model abstract="true"
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XOperation.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XOperation.java
index 8927ff5..9539fc7 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XOperation.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XOperation.java
@@ -19,13 +19,13 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XOperation#getTypeParameters <em>Type Parameters</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XOperation#getParameters <em>Parameters</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XOperation#getExceptions <em>Exceptions</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XOperation#getBody <em>Body</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXOperation()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XPackage.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XPackage.java
index 9c76bd6..dba7370 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XPackage.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XPackage.java
@@ -18,12 +18,12 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XPackage#getImportDirectives <em>Import Directives</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XPackage#getAnnotationDirectives <em>Annotation Directives</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XPackage#getClassifiers <em>Classifiers</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXPackage()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XParameter.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XParameter.java
index 24e46fa..1b248a1 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XParameter.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XParameter.java
@@ -15,10 +15,10 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XParameter#getOperation <em>Operation</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXParameter()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XReference.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XReference.java
index bc5cd1d..f383247 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XReference.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XReference.java
@@ -19,6 +19,7 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XReference#isContainer <em>Container</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XReference#isContainment <em>Containment</em>}</li>
@@ -27,7 +28,6 @@
  *   <li>{@link org.eclipse.emf.ecore.xcore.XReference#getOpposite <em>Opposite</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XReference#getKeys <em>Keys</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXReference()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XStructuralFeature.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XStructuralFeature.java
index a208cbe..6bac8d7 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XStructuralFeature.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XStructuralFeature.java
@@ -18,6 +18,7 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XStructuralFeature#isReadonly <em>Readonly</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XStructuralFeature#isVolatile <em>Volatile</em>}</li>
@@ -29,7 +30,6 @@
  *   <li>{@link org.eclipse.emf.ecore.xcore.XStructuralFeature#getIsSetBody <em>Is Set Body</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XStructuralFeature#getUnsetBody <em>Unset Body</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXStructuralFeature()
  * @model abstract="true"
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XTypeParameter.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XTypeParameter.java
index dc4e54d..bfc3bff 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XTypeParameter.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XTypeParameter.java
@@ -18,10 +18,10 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XTypeParameter#getBounds <em>Bounds</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXTypeParameter()
  * @model
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XTypedElement.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XTypedElement.java
index 9e0d6bc..c904b02 100755
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XTypedElement.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XTypedElement.java
@@ -15,13 +15,13 @@
  *
  * <p>
  * The following features are supported:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XTypedElement#isUnordered <em>Unordered</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XTypedElement#isUnique <em>Unique</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XTypedElement#getType <em>Type</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.XTypedElement#getMultiplicity <em>Multiplicity</em>}</li>
  * </ul>
- * </p>
  *
  * @see org.eclipse.emf.ecore.xcore.XcorePackage#getXTypedElement()
  * @model abstract="true"
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java
index 3287dc6..c4c0e64 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java
@@ -30,6 +30,7 @@
 import org.eclipse.emf.ecore.xcore.scoping.XcoreScopeProvider;
 import org.eclipse.emf.ecore.xcore.scoping.XcoreSerializerScopeProvider;
 import org.eclipse.emf.ecore.xcore.serializer.XcoreCrossReferenceSerializer;
+import org.eclipse.emf.ecore.xcore.util.XcoreFeatureCallAsTypeLiteralHelper;
 import org.eclipse.emf.ecore.xcore.validation.XcoreAwareMessageProvider;
 import org.eclipse.emf.ecore.xcore.validation.XcoreDiagnosticConverter;
 import org.eclipse.emf.ecore.xcore.validation.XcoreDiagnostician;
@@ -65,6 +66,7 @@
 import org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedFeatures;
 import org.eclipse.xtext.xbase.scoping.batch.XbaseBatchScopeProvider;
 import org.eclipse.xtext.xbase.typesystem.internal.DefaultReentrantTypeResolver;
+import org.eclipse.xtext.xbase.util.FeatureCallAsTypeLiteralHelper;
 import org.eclipse.xtext.xbase.validation.JvmTypeReferencesValidator;
 
 import com.google.inject.Binder;
@@ -240,4 +242,9 @@
   {
     return XcoreCrossReferenceSerializer.class;
   }
+
+  public Class<? extends FeatureCallAsTypeLiteralHelper> bindFeatureCallAsTypeLiteralHelper()
+  {
+    return XcoreFeatureCallAsTypeLiteralHelper.class;
+  }
 }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAnnotationDirectiveImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAnnotationDirectiveImpl.java
index 622a025..208ef24 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAnnotationDirectiveImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAnnotationDirectiveImpl.java
@@ -27,11 +27,11 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XAnnotationDirectiveImpl#getSourceURI <em>Source URI</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XAnnotationDirectiveImpl#getPackage <em>Package</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -109,7 +109,7 @@
   public XPackage getPackage()
   {
     if (eContainerFeatureID() != XcorePackage.XANNOTATION_DIRECTIVE__PACKAGE) return null;
-    return (XPackage)eContainer();
+    return (XPackage)eInternalContainer();
   }
 
   /**
@@ -242,7 +242,7 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (sourceURI: ");
     result.append(sourceURI);
     result.append(')');
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAnnotationImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAnnotationImpl.java
index 2cf9ed3..c708bb5 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAnnotationImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAnnotationImpl.java
@@ -35,12 +35,12 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XAnnotationImpl#getSource <em>Source</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XAnnotationImpl#getDetails <em>Details</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XAnnotationImpl#getModelElement <em>Model Element</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -152,7 +152,7 @@
   public XModelElement getModelElement()
   {
     if (eContainerFeatureID() != XcorePackage.XANNOTATION__MODEL_ELEMENT) return null;
-    return (XModelElement)eContainer();
+    return (XModelElement)eInternalContainer();
   }
 
   /**
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAttributeImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAttributeImpl.java
index f798885..c4da162 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAttributeImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XAttributeImpl.java
@@ -24,11 +24,11 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XAttributeImpl#getDefaultValueLiteral <em>Default Value Literal</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XAttributeImpl#isID <em>ID</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -65,14 +65,14 @@
   protected static final boolean ID_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isID() <em>ID</em>}' attribute.
+   * The flag representing the value of the '{@link #isID() <em>ID</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isID()
    * @generated
    * @ordered
    */
-  protected boolean iD = ID_EDEFAULT;
+  protected static final int ID_EFLAG = 1 << 8;
 
   /**
    * <!-- begin-user-doc -->
@@ -125,7 +125,7 @@
    */
   public boolean isID()
   {
-    return iD;
+    return (eFlags & ID_EFLAG) != 0;
   }
 
   /**
@@ -135,10 +135,10 @@
    */
   public void setID(boolean newID)
   {
-    boolean oldID = iD;
-    iD = newID;
+    boolean oldID = (eFlags & ID_EFLAG) != 0;
+    if (newID) eFlags |= ID_EFLAG; else eFlags &= ~ID_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XATTRIBUTE__ID, oldID, iD));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XATTRIBUTE__ID, oldID, newID));
   }
 
   /**
@@ -212,7 +212,7 @@
       case XcorePackage.XATTRIBUTE__DEFAULT_VALUE_LITERAL:
         return DEFAULT_VALUE_LITERAL_EDEFAULT == null ? defaultValueLiteral != null : !DEFAULT_VALUE_LITERAL_EDEFAULT.equals(defaultValueLiteral);
       case XcorePackage.XATTRIBUTE__ID:
-        return iD != ID_EDEFAULT;
+        return ((eFlags & ID_EFLAG) != 0) != ID_EDEFAULT;
     }
     return super.eIsSet(featureID);
   }
@@ -227,11 +227,11 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (defaultValueLiteral: ");
     result.append(defaultValueLiteral);
     result.append(", iD: ");
-    result.append(iD);
+    result.append((eFlags & ID_EFLAG) != 0);
     result.append(')');
     return result.toString();
   }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XClassImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XClassImpl.java
index 7d3f3fb..bb81d2f 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XClassImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XClassImpl.java
@@ -36,13 +36,13 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XClassImpl#isAbstract <em>Abstract</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XClassImpl#isInterface <em>Interface</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XClassImpl#getMembers <em>Members</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XClassImpl#getSuperTypes <em>Super Types</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -59,14 +59,14 @@
   protected static final boolean ABSTRACT_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isAbstract() <em>Abstract</em>}' attribute.
+   * The flag representing the value of the '{@link #isAbstract() <em>Abstract</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isAbstract()
    * @generated
    * @ordered
    */
-  protected boolean abstract_ = ABSTRACT_EDEFAULT;
+  protected static final int ABSTRACT_EFLAG = 1 << 0;
 
   /**
    * The default value of the '{@link #isInterface() <em>Interface</em>}' attribute.
@@ -79,14 +79,14 @@
   protected static final boolean INTERFACE_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isInterface() <em>Interface</em>}' attribute.
+   * The flag representing the value of the '{@link #isInterface() <em>Interface</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isInterface()
    * @generated
    * @ordered
    */
-  protected boolean interface_ = INTERFACE_EDEFAULT;
+  protected static final int INTERFACE_EFLAG = 1 << 1;
 
   /**
    * The cached value of the '{@link #getMembers() <em>Members</em>}' containment reference list.
@@ -136,7 +136,7 @@
    */
   public boolean isAbstract()
   {
-    return abstract_;
+    return (eFlags & ABSTRACT_EFLAG) != 0;
   }
 
   /**
@@ -146,10 +146,10 @@
    */
   public void setAbstract(boolean newAbstract)
   {
-    boolean oldAbstract = abstract_;
-    abstract_ = newAbstract;
+    boolean oldAbstract = (eFlags & ABSTRACT_EFLAG) != 0;
+    if (newAbstract) eFlags |= ABSTRACT_EFLAG; else eFlags &= ~ABSTRACT_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XCLASS__ABSTRACT, oldAbstract, abstract_));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XCLASS__ABSTRACT, oldAbstract, newAbstract));
   }
 
   /**
@@ -159,7 +159,7 @@
    */
   public boolean isInterface()
   {
-    return interface_;
+    return (eFlags & INTERFACE_EFLAG) != 0;
   }
 
   /**
@@ -169,10 +169,10 @@
    */
   public void setInterface(boolean newInterface)
   {
-    boolean oldInterface = interface_;
-    interface_ = newInterface;
+    boolean oldInterface = (eFlags & INTERFACE_EFLAG) != 0;
+    if (newInterface) eFlags |= INTERFACE_EFLAG; else eFlags &= ~INTERFACE_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XCLASS__INTERFACE, oldInterface, interface_));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XCLASS__INTERFACE, oldInterface, newInterface));
   }
 
   /**
@@ -346,9 +346,9 @@
     switch (featureID)
     {
       case XcorePackage.XCLASS__ABSTRACT:
-        return abstract_ != ABSTRACT_EDEFAULT;
+        return ((eFlags & ABSTRACT_EFLAG) != 0) != ABSTRACT_EDEFAULT;
       case XcorePackage.XCLASS__INTERFACE:
-        return interface_ != INTERFACE_EDEFAULT;
+        return ((eFlags & INTERFACE_EFLAG) != 0) != INTERFACE_EDEFAULT;
       case XcorePackage.XCLASS__MEMBERS:
         return members != null && !members.isEmpty();
       case XcorePackage.XCLASS__SUPER_TYPES:
@@ -367,11 +367,11 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (abstract: ");
-    result.append(abstract_);
+    result.append((eFlags & ABSTRACT_EFLAG) != 0);
     result.append(", interface: ");
-    result.append(interface_);
+    result.append((eFlags & INTERFACE_EFLAG) != 0);
     result.append(')');
     return result.toString();
   }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XClassifierImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XClassifierImpl.java
index e49d5c2..3a258dc 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XClassifierImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XClassifierImpl.java
@@ -36,12 +36,12 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XClassifierImpl#getInstanceType <em>Instance Type</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XClassifierImpl#getPackage <em>Package</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XClassifierImpl#getTypeParameters <em>Type Parameters</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -144,7 +144,7 @@
   public XPackage getPackage()
   {
     if (eContainerFeatureID() != XcorePackage.XCLASSIFIER__PACKAGE) return null;
-    return (XPackage)eContainer();
+    return (XPackage)eInternalContainer();
   }
 
   /**
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XDataTypeImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XDataTypeImpl.java
index ea7dfba..4a6d3e2 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XDataTypeImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XDataTypeImpl.java
@@ -28,12 +28,12 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XDataTypeImpl#isSerializable <em>Serializable</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XDataTypeImpl#getCreateBody <em>Create Body</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XDataTypeImpl#getConvertBody <em>Convert Body</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -50,14 +50,14 @@
   protected static final boolean SERIALIZABLE_EDEFAULT = true;
 
   /**
-   * The cached value of the '{@link #isSerializable() <em>Serializable</em>}' attribute.
+   * The flag representing the value of the '{@link #isSerializable() <em>Serializable</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isSerializable()
    * @generated
    * @ordered
    */
-  protected boolean serializable = SERIALIZABLE_EDEFAULT;
+  protected static final int SERIALIZABLE_EFLAG = 1 << 0;
 
   /**
    * The cached value of the '{@link #getCreateBody() <em>Create Body</em>}' containment reference.
@@ -87,6 +87,7 @@
   protected XDataTypeImpl()
   {
     super();
+    eFlags |= SERIALIZABLE_EFLAG;
   }
 
   /**
@@ -107,7 +108,7 @@
    */
   public boolean isSerializable()
   {
-    return serializable;
+    return (eFlags & SERIALIZABLE_EFLAG) != 0;
   }
 
   /**
@@ -117,10 +118,10 @@
    */
   public void setSerializable(boolean newSerializable)
   {
-    boolean oldSerializable = serializable;
-    serializable = newSerializable;
+    boolean oldSerializable = (eFlags & SERIALIZABLE_EFLAG) != 0;
+    if (newSerializable) eFlags |= SERIALIZABLE_EFLAG; else eFlags &= ~SERIALIZABLE_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XDATA_TYPE__SERIALIZABLE, oldSerializable, serializable));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XDATA_TYPE__SERIALIZABLE, oldSerializable, newSerializable));
   }
 
   /**
@@ -314,7 +315,7 @@
     switch (featureID)
     {
       case XcorePackage.XDATA_TYPE__SERIALIZABLE:
-        return serializable != SERIALIZABLE_EDEFAULT;
+        return ((eFlags & SERIALIZABLE_EFLAG) != 0) != SERIALIZABLE_EDEFAULT;
       case XcorePackage.XDATA_TYPE__CREATE_BODY:
         return createBody != null;
       case XcorePackage.XDATA_TYPE__CONVERT_BODY:
@@ -333,9 +334,9 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (serializable: ");
-    result.append(serializable);
+    result.append((eFlags & SERIALIZABLE_EFLAG) != 0);
     result.append(')');
     return result.toString();
   }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XEnumImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XEnumImpl.java
index defe9aa..6d94589 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XEnumImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XEnumImpl.java
@@ -31,10 +31,10 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XEnumImpl#getLiterals <em>Literals</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XEnumLiteralImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XEnumLiteralImpl.java
index ea14655..fd2126a 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XEnumLiteralImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XEnumLiteralImpl.java
@@ -27,12 +27,12 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XEnumLiteralImpl#getValue <em>Value</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XEnumLiteralImpl#getLiteral <em>Literal</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XEnumLiteralImpl#getEnum <em>Enum</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -153,7 +153,7 @@
   public XEnum getEnum()
   {
     if (eContainerFeatureID() != XcorePackage.XENUM_LITERAL__ENUM) return null;
-    return (XEnum)eContainer();
+    return (XEnum)eInternalContainer();
   }
 
   /**
@@ -296,7 +296,7 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (value: ");
     result.append(value);
     result.append(", literal: ");
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XGenericTypeImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XGenericTypeImpl.java
index 18978a0..0533515 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XGenericTypeImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XGenericTypeImpl.java
@@ -21,8 +21,8 @@
 import org.eclipse.emf.ecore.InternalEObject;
 
 import org.eclipse.emf.ecore.impl.ENotificationImpl;
-import org.eclipse.emf.ecore.impl.EObjectImpl;
 
+import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
 import org.eclipse.emf.ecore.util.EObjectContainmentEList;
 import org.eclipse.emf.ecore.util.InternalEList;
 
@@ -36,19 +36,28 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XGenericTypeImpl#getUpperBound <em>Upper Bound</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XGenericTypeImpl#getTypeArguments <em>Type Arguments</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XGenericTypeImpl#getLowerBound <em>Lower Bound</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XGenericTypeImpl#getType <em>Type</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
-public class XGenericTypeImpl extends EObjectImpl implements XGenericType
+public class XGenericTypeImpl extends MinimalEObjectImpl.Container implements XGenericType
 {
   /**
+   * A set of bit flags representing the values of boolean attributes and whether unsettable features have been set.
+   * <!-- begin-user-doc -->
+   * <!-- end-user-doc -->
+   * @generated
+   * @ordered
+   */
+  protected int eFlags = 0;
+
+  /**
    * The cached value of the '{@link #getUpperBound() <em>Upper Bound</em>}' containment reference.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XImportDirectiveImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XImportDirectiveImpl.java
index 9305c74..9a3ea54 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XImportDirectiveImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XImportDirectiveImpl.java
@@ -32,12 +32,12 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XImportDirectiveImpl#getImportedNamespace <em>Imported Namespace</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XImportDirectiveImpl#getImportedObject <em>Imported Object</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XImportDirectiveImpl#getPackage <em>Package</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -187,7 +187,7 @@
   public XPackage getPackage()
   {
     if (eContainerFeatureID() != XcorePackage.XIMPORT_DIRECTIVE__PACKAGE) return null;
-    return (XPackage)eContainer();
+    return (XPackage)eInternalContainer();
   }
 
   /**
@@ -331,7 +331,7 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (importedNamespace: ");
     result.append(importedNamespace);
     result.append(')');
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XMemberImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XMemberImpl.java
index 634a910..2e96bd7 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XMemberImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XMemberImpl.java
@@ -24,10 +24,10 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XMemberImpl#getContainingClass <em>Containing Class</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -62,7 +62,7 @@
   public XClass getContainingClass()
   {
     if (eContainerFeatureID() != XcorePackage.XMEMBER__CONTAINING_CLASS) return null;
-    return (XClass)eContainer();
+    return (XClass)eInternalContainer();
   }
 
   /**
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XModelElementImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XModelElementImpl.java
index 6e6f641..b8ade1d 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XModelElementImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XModelElementImpl.java
@@ -17,8 +17,7 @@
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.InternalEObject;
 
-import org.eclipse.emf.ecore.impl.EObjectImpl;
-
+import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
 import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
 import org.eclipse.emf.ecore.util.InternalEList;
 
@@ -34,16 +33,24 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XModelElementImpl#getAnnotations <em>Annotations</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
-public abstract class XModelElementImpl extends EObjectImpl implements XModelElement
+public abstract class XModelElementImpl extends MinimalEObjectImpl.Container implements XModelElement
 {
   /**
+   * A set of bit flags representing the values of boolean attributes and whether unsettable features have been set.
+   * <!-- begin-user-doc -->
+   * <!-- end-user-doc -->
+   * @generated
+   * @ordered
+   */
+  protected int eFlags = 0;
+  /**
    * The cached value of the '{@link #getAnnotations() <em>Annotations</em>}' containment reference list.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XNamedElementImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XNamedElementImpl.java
index 56238c4..c7aefb1 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XNamedElementImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XNamedElementImpl.java
@@ -24,10 +24,10 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XNamedElementImpl#getName <em>Name</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -173,7 +173,7 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (name: ");
     result.append(name);
     result.append(')');
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XOperationImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XOperationImpl.java
index 5b3b491..39c8257 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XOperationImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XOperationImpl.java
@@ -39,13 +39,13 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XOperationImpl#getTypeParameters <em>Type Parameters</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XOperationImpl#getParameters <em>Parameters</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XOperationImpl#getExceptions <em>Exceptions</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XOperationImpl#getBody <em>Body</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XPackageImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XPackageImpl.java
index b34f812..7055045 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XPackageImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XPackageImpl.java
@@ -33,12 +33,12 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XPackageImpl#getImportDirectives <em>Import Directives</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XPackageImpl#getAnnotationDirectives <em>Annotation Directives</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XPackageImpl#getClassifiers <em>Classifiers</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XParameterImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XParameterImpl.java
index 71463ea..fa4530d 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XParameterImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XParameterImpl.java
@@ -24,10 +24,10 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XParameterImpl#getOperation <em>Operation</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -62,7 +62,7 @@
   public XOperation getOperation()
   {
     if (eContainerFeatureID() != XcorePackage.XPARAMETER__OPERATION) return null;
-    return (XOperation)eContainer();
+    return (XOperation)eInternalContainer();
   }
 
   /**
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XReferenceImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XReferenceImpl.java
index 1aa17fb..45b143f 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XReferenceImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XReferenceImpl.java
@@ -33,6 +33,7 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XReferenceImpl#isContainer <em>Container</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XReferenceImpl#isContainment <em>Containment</em>}</li>
@@ -41,7 +42,6 @@
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XReferenceImpl#getOpposite <em>Opposite</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XReferenceImpl#getKeys <em>Keys</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -58,14 +58,14 @@
   protected static final boolean CONTAINER_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isContainer() <em>Container</em>}' attribute.
+   * The flag representing the value of the '{@link #isContainer() <em>Container</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isContainer()
    * @generated
    * @ordered
    */
-  protected boolean container = CONTAINER_EDEFAULT;
+  protected static final int CONTAINER_EFLAG = 1 << 8;
 
   /**
    * The default value of the '{@link #isContainment() <em>Containment</em>}' attribute.
@@ -78,14 +78,14 @@
   protected static final boolean CONTAINMENT_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isContainment() <em>Containment</em>}' attribute.
+   * The flag representing the value of the '{@link #isContainment() <em>Containment</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isContainment()
    * @generated
    * @ordered
    */
-  protected boolean containment = CONTAINMENT_EDEFAULT;
+  protected static final int CONTAINMENT_EFLAG = 1 << 9;
 
   /**
    * The default value of the '{@link #isResolveProxies() <em>Resolve Proxies</em>}' attribute.
@@ -98,14 +98,14 @@
   protected static final boolean RESOLVE_PROXIES_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isResolveProxies() <em>Resolve Proxies</em>}' attribute.
+   * The flag representing the value of the '{@link #isResolveProxies() <em>Resolve Proxies</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isResolveProxies()
    * @generated
    * @ordered
    */
-  protected boolean resolveProxies = RESOLVE_PROXIES_EDEFAULT;
+  protected static final int RESOLVE_PROXIES_EFLAG = 1 << 10;
 
   /**
    * The default value of the '{@link #isLocal() <em>Local</em>}' attribute.
@@ -118,14 +118,14 @@
   protected static final boolean LOCAL_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isLocal() <em>Local</em>}' attribute.
+   * The flag representing the value of the '{@link #isLocal() <em>Local</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isLocal()
    * @generated
    * @ordered
    */
-  protected boolean local = LOCAL_EDEFAULT;
+  protected static final int LOCAL_EFLAG = 1 << 11;
 
   /**
    * The cached value of the '{@link #getOpposite() <em>Opposite</em>}' reference.
@@ -175,7 +175,7 @@
    */
   public boolean isContainer()
   {
-    return container;
+    return (eFlags & CONTAINER_EFLAG) != 0;
   }
 
   /**
@@ -185,10 +185,10 @@
    */
   public void setContainer(boolean newContainer)
   {
-    boolean oldContainer = container;
-    container = newContainer;
+    boolean oldContainer = (eFlags & CONTAINER_EFLAG) != 0;
+    if (newContainer) eFlags |= CONTAINER_EFLAG; else eFlags &= ~CONTAINER_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XREFERENCE__CONTAINER, oldContainer, container));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XREFERENCE__CONTAINER, oldContainer, newContainer));
   }
 
   /**
@@ -198,7 +198,7 @@
    */
   public boolean isContainment()
   {
-    return containment;
+    return (eFlags & CONTAINMENT_EFLAG) != 0;
   }
 
   /**
@@ -208,10 +208,10 @@
    */
   public void setContainment(boolean newContainment)
   {
-    boolean oldContainment = containment;
-    containment = newContainment;
+    boolean oldContainment = (eFlags & CONTAINMENT_EFLAG) != 0;
+    if (newContainment) eFlags |= CONTAINMENT_EFLAG; else eFlags &= ~CONTAINMENT_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XREFERENCE__CONTAINMENT, oldContainment, containment));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XREFERENCE__CONTAINMENT, oldContainment, newContainment));
   }
 
   /**
@@ -221,7 +221,7 @@
    */
   public boolean isResolveProxies()
   {
-    return resolveProxies;
+    return (eFlags & RESOLVE_PROXIES_EFLAG) != 0;
   }
 
   /**
@@ -231,10 +231,10 @@
    */
   public void setResolveProxies(boolean newResolveProxies)
   {
-    boolean oldResolveProxies = resolveProxies;
-    resolveProxies = newResolveProxies;
+    boolean oldResolveProxies = (eFlags & RESOLVE_PROXIES_EFLAG) != 0;
+    if (newResolveProxies) eFlags |= RESOLVE_PROXIES_EFLAG; else eFlags &= ~RESOLVE_PROXIES_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XREFERENCE__RESOLVE_PROXIES, oldResolveProxies, resolveProxies));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XREFERENCE__RESOLVE_PROXIES, oldResolveProxies, newResolveProxies));
   }
 
   /**
@@ -244,7 +244,7 @@
    */
   public boolean isLocal()
   {
-    return local;
+    return (eFlags & LOCAL_EFLAG) != 0;
   }
 
   /**
@@ -254,10 +254,10 @@
    */
   public void setLocal(boolean newLocal)
   {
-    boolean oldLocal = local;
-    local = newLocal;
+    boolean oldLocal = (eFlags & LOCAL_EFLAG) != 0;
+    if (newLocal) eFlags |= LOCAL_EFLAG; else eFlags &= ~LOCAL_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XREFERENCE__LOCAL, oldLocal, local));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XREFERENCE__LOCAL, oldLocal, newLocal));
   }
 
   /**
@@ -421,13 +421,13 @@
     switch (featureID)
     {
       case XcorePackage.XREFERENCE__CONTAINER:
-        return container != CONTAINER_EDEFAULT;
+        return ((eFlags & CONTAINER_EFLAG) != 0) != CONTAINER_EDEFAULT;
       case XcorePackage.XREFERENCE__CONTAINMENT:
-        return containment != CONTAINMENT_EDEFAULT;
+        return ((eFlags & CONTAINMENT_EFLAG) != 0) != CONTAINMENT_EDEFAULT;
       case XcorePackage.XREFERENCE__RESOLVE_PROXIES:
-        return resolveProxies != RESOLVE_PROXIES_EDEFAULT;
+        return ((eFlags & RESOLVE_PROXIES_EFLAG) != 0) != RESOLVE_PROXIES_EDEFAULT;
       case XcorePackage.XREFERENCE__LOCAL:
-        return local != LOCAL_EDEFAULT;
+        return ((eFlags & LOCAL_EFLAG) != 0) != LOCAL_EDEFAULT;
       case XcorePackage.XREFERENCE__OPPOSITE:
         return opposite != null;
       case XcorePackage.XREFERENCE__KEYS:
@@ -446,15 +446,15 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (container: ");
-    result.append(container);
+    result.append((eFlags & CONTAINER_EFLAG) != 0);
     result.append(", containment: ");
-    result.append(containment);
+    result.append((eFlags & CONTAINMENT_EFLAG) != 0);
     result.append(", resolveProxies: ");
-    result.append(resolveProxies);
+    result.append((eFlags & RESOLVE_PROXIES_EFLAG) != 0);
     result.append(", local: ");
-    result.append(local);
+    result.append((eFlags & LOCAL_EFLAG) != 0);
     result.append(')');
     return result.toString();
   }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XStringToStringMapEntryImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XStringToStringMapEntryImpl.java
index b0ebac1..9aed53a 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XStringToStringMapEntryImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XStringToStringMapEntryImpl.java
@@ -17,8 +17,8 @@
 import org.eclipse.emf.ecore.EObject;
 
 import org.eclipse.emf.ecore.impl.ENotificationImpl;
-import org.eclipse.emf.ecore.impl.EObjectImpl;
 
+import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
 import org.eclipse.emf.ecore.xcore.XcorePackage;
 
 
@@ -28,17 +28,26 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XStringToStringMapEntryImpl#getTypedKey <em>Key</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XStringToStringMapEntryImpl#getTypedValue <em>Value</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
-public class XStringToStringMapEntryImpl extends EObjectImpl implements BasicEMap.Entry<String,String>
+public class XStringToStringMapEntryImpl extends MinimalEObjectImpl.Container implements BasicEMap.Entry<String,String>
 {
   /**
+   * A set of bit flags representing the values of boolean attributes and whether unsettable features have been set.
+   * <!-- begin-user-doc -->
+   * <!-- end-user-doc -->
+   * @generated
+   * @ordered
+   */
+  protected int eFlags = 0;
+
+  /**
    * The default value of the '{@link #getTypedKey() <em>Key</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
@@ -231,7 +240,7 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (key: ");
     result.append(key);
     result.append(", value: ");
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XStructuralFeatureImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XStructuralFeatureImpl.java
index 4b34b51..ac840f5 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XStructuralFeatureImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XStructuralFeatureImpl.java
@@ -28,6 +28,7 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XStructuralFeatureImpl#isReadonly <em>Readonly</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XStructuralFeatureImpl#isVolatile <em>Volatile</em>}</li>
@@ -39,7 +40,6 @@
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XStructuralFeatureImpl#getIsSetBody <em>Is Set Body</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XStructuralFeatureImpl#getUnsetBody <em>Unset Body</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -56,14 +56,14 @@
   protected static final boolean READONLY_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isReadonly() <em>Readonly</em>}' attribute.
+   * The flag representing the value of the '{@link #isReadonly() <em>Readonly</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isReadonly()
    * @generated
    * @ordered
    */
-  protected boolean readonly = READONLY_EDEFAULT;
+  protected static final int READONLY_EFLAG = 1 << 3;
 
   /**
    * The default value of the '{@link #isVolatile() <em>Volatile</em>}' attribute.
@@ -76,14 +76,14 @@
   protected static final boolean VOLATILE_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isVolatile() <em>Volatile</em>}' attribute.
+   * The flag representing the value of the '{@link #isVolatile() <em>Volatile</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isVolatile()
    * @generated
    * @ordered
    */
-  protected boolean volatile_ = VOLATILE_EDEFAULT;
+  protected static final int VOLATILE_EFLAG = 1 << 4;
 
   /**
    * The default value of the '{@link #isTransient() <em>Transient</em>}' attribute.
@@ -96,14 +96,14 @@
   protected static final boolean TRANSIENT_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isTransient() <em>Transient</em>}' attribute.
+   * The flag representing the value of the '{@link #isTransient() <em>Transient</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isTransient()
    * @generated
    * @ordered
    */
-  protected boolean transient_ = TRANSIENT_EDEFAULT;
+  protected static final int TRANSIENT_EFLAG = 1 << 5;
 
   /**
    * The default value of the '{@link #isUnsettable() <em>Unsettable</em>}' attribute.
@@ -116,14 +116,14 @@
   protected static final boolean UNSETTABLE_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isUnsettable() <em>Unsettable</em>}' attribute.
+   * The flag representing the value of the '{@link #isUnsettable() <em>Unsettable</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isUnsettable()
    * @generated
    * @ordered
    */
-  protected boolean unsettable = UNSETTABLE_EDEFAULT;
+  protected static final int UNSETTABLE_EFLAG = 1 << 6;
 
   /**
    * The default value of the '{@link #isDerived() <em>Derived</em>}' attribute.
@@ -136,14 +136,14 @@
   protected static final boolean DERIVED_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isDerived() <em>Derived</em>}' attribute.
+   * The flag representing the value of the '{@link #isDerived() <em>Derived</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isDerived()
    * @generated
    * @ordered
    */
-  protected boolean derived = DERIVED_EDEFAULT;
+  protected static final int DERIVED_EFLAG = 1 << 7;
 
   /**
    * The cached value of the '{@link #getGetBody() <em>Get Body</em>}' containment reference.
@@ -213,7 +213,7 @@
    */
   public boolean isReadonly()
   {
-    return readonly;
+    return (eFlags & READONLY_EFLAG) != 0;
   }
 
   /**
@@ -223,10 +223,10 @@
    */
   public void setReadonly(boolean newReadonly)
   {
-    boolean oldReadonly = readonly;
-    readonly = newReadonly;
+    boolean oldReadonly = (eFlags & READONLY_EFLAG) != 0;
+    if (newReadonly) eFlags |= READONLY_EFLAG; else eFlags &= ~READONLY_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__READONLY, oldReadonly, readonly));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__READONLY, oldReadonly, newReadonly));
   }
 
   /**
@@ -236,7 +236,7 @@
    */
   public boolean isVolatile()
   {
-    return volatile_;
+    return (eFlags & VOLATILE_EFLAG) != 0;
   }
 
   /**
@@ -246,10 +246,10 @@
    */
   public void setVolatile(boolean newVolatile)
   {
-    boolean oldVolatile = volatile_;
-    volatile_ = newVolatile;
+    boolean oldVolatile = (eFlags & VOLATILE_EFLAG) != 0;
+    if (newVolatile) eFlags |= VOLATILE_EFLAG; else eFlags &= ~VOLATILE_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__VOLATILE, oldVolatile, volatile_));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__VOLATILE, oldVolatile, newVolatile));
   }
 
   /**
@@ -259,7 +259,7 @@
    */
   public boolean isTransient()
   {
-    return transient_;
+    return (eFlags & TRANSIENT_EFLAG) != 0;
   }
 
   /**
@@ -269,10 +269,10 @@
    */
   public void setTransient(boolean newTransient)
   {
-    boolean oldTransient = transient_;
-    transient_ = newTransient;
+    boolean oldTransient = (eFlags & TRANSIENT_EFLAG) != 0;
+    if (newTransient) eFlags |= TRANSIENT_EFLAG; else eFlags &= ~TRANSIENT_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__TRANSIENT, oldTransient, transient_));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__TRANSIENT, oldTransient, newTransient));
   }
 
   /**
@@ -282,7 +282,7 @@
    */
   public boolean isUnsettable()
   {
-    return unsettable;
+    return (eFlags & UNSETTABLE_EFLAG) != 0;
   }
 
   /**
@@ -292,10 +292,10 @@
    */
   public void setUnsettable(boolean newUnsettable)
   {
-    boolean oldUnsettable = unsettable;
-    unsettable = newUnsettable;
+    boolean oldUnsettable = (eFlags & UNSETTABLE_EFLAG) != 0;
+    if (newUnsettable) eFlags |= UNSETTABLE_EFLAG; else eFlags &= ~UNSETTABLE_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__UNSETTABLE, oldUnsettable, unsettable));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__UNSETTABLE, oldUnsettable, newUnsettable));
   }
 
   /**
@@ -305,7 +305,7 @@
    */
   public boolean isDerived()
   {
-    return derived;
+    return (eFlags & DERIVED_EFLAG) != 0;
   }
 
   /**
@@ -315,10 +315,10 @@
    */
   public void setDerived(boolean newDerived)
   {
-    boolean oldDerived = derived;
-    derived = newDerived;
+    boolean oldDerived = (eFlags & DERIVED_EFLAG) != 0;
+    if (newDerived) eFlags |= DERIVED_EFLAG; else eFlags &= ~DERIVED_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__DERIVED, oldDerived, derived));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XSTRUCTURAL_FEATURE__DERIVED, oldDerived, newDerived));
   }
 
   /**
@@ -660,15 +660,15 @@
     switch (featureID)
     {
       case XcorePackage.XSTRUCTURAL_FEATURE__READONLY:
-        return readonly != READONLY_EDEFAULT;
+        return ((eFlags & READONLY_EFLAG) != 0) != READONLY_EDEFAULT;
       case XcorePackage.XSTRUCTURAL_FEATURE__VOLATILE:
-        return volatile_ != VOLATILE_EDEFAULT;
+        return ((eFlags & VOLATILE_EFLAG) != 0) != VOLATILE_EDEFAULT;
       case XcorePackage.XSTRUCTURAL_FEATURE__TRANSIENT:
-        return transient_ != TRANSIENT_EDEFAULT;
+        return ((eFlags & TRANSIENT_EFLAG) != 0) != TRANSIENT_EDEFAULT;
       case XcorePackage.XSTRUCTURAL_FEATURE__UNSETTABLE:
-        return unsettable != UNSETTABLE_EDEFAULT;
+        return ((eFlags & UNSETTABLE_EFLAG) != 0) != UNSETTABLE_EDEFAULT;
       case XcorePackage.XSTRUCTURAL_FEATURE__DERIVED:
-        return derived != DERIVED_EDEFAULT;
+        return ((eFlags & DERIVED_EFLAG) != 0) != DERIVED_EDEFAULT;
       case XcorePackage.XSTRUCTURAL_FEATURE__GET_BODY:
         return getBody != null;
       case XcorePackage.XSTRUCTURAL_FEATURE__SET_BODY:
@@ -691,17 +691,17 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (readonly: ");
-    result.append(readonly);
+    result.append((eFlags & READONLY_EFLAG) != 0);
     result.append(", volatile: ");
-    result.append(volatile_);
+    result.append((eFlags & VOLATILE_EFLAG) != 0);
     result.append(", transient: ");
-    result.append(transient_);
+    result.append((eFlags & TRANSIENT_EFLAG) != 0);
     result.append(", unsettable: ");
-    result.append(unsettable);
+    result.append((eFlags & UNSETTABLE_EFLAG) != 0);
     result.append(", derived: ");
-    result.append(derived);
+    result.append((eFlags & DERIVED_EFLAG) != 0);
     result.append(')');
     return result.toString();
   }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XTypeParameterImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XTypeParameterImpl.java
index 46ad43b..9f9ca62 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XTypeParameterImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XTypeParameterImpl.java
@@ -31,10 +31,10 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XTypeParameterImpl#getBounds <em>Bounds</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XTypedElementImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XTypedElementImpl.java
index e794093..1491586 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XTypedElementImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XTypedElementImpl.java
@@ -27,13 +27,13 @@
  * <!-- end-user-doc -->
  * <p>
  * The following features are implemented:
+ * </p>
  * <ul>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XTypedElementImpl#isUnordered <em>Unordered</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XTypedElementImpl#isUnique <em>Unique</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XTypedElementImpl#getType <em>Type</em>}</li>
  *   <li>{@link org.eclipse.emf.ecore.xcore.impl.XTypedElementImpl#getMultiplicity <em>Multiplicity</em>}</li>
  * </ul>
- * </p>
  *
  * @generated
  */
@@ -50,14 +50,14 @@
   protected static final boolean UNORDERED_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isUnordered() <em>Unordered</em>}' attribute.
+   * The flag representing the value of the '{@link #isUnordered() <em>Unordered</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isUnordered()
    * @generated
    * @ordered
    */
-  protected boolean unordered = UNORDERED_EDEFAULT;
+  protected static final int UNORDERED_EFLAG = 1 << 0;
 
   /**
    * The default value of the '{@link #isUnique() <em>Unique</em>}' attribute.
@@ -70,14 +70,14 @@
   protected static final boolean UNIQUE_EDEFAULT = false;
 
   /**
-   * The cached value of the '{@link #isUnique() <em>Unique</em>}' attribute.
+   * The flag representing the value of the '{@link #isUnique() <em>Unique</em>}' attribute.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @see #isUnique()
    * @generated
    * @ordered
    */
-  protected boolean unique = UNIQUE_EDEFAULT;
+  protected static final int UNIQUE_EFLAG = 1 << 1;
 
   /**
    * The cached value of the '{@link #getType() <em>Type</em>}' containment reference.
@@ -90,13 +90,13 @@
   protected XGenericType type;
 
   /**
-   * This is true if the Type containment reference has been set.
+   * The flag representing whether the Type containment reference has been set.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
    * @generated
    * @ordered
    */
-  protected boolean typeESet;
+  protected static final int TYPE_ESETFLAG = 1 << 2;
 
   /**
    * The default value of the '{@link #getMultiplicity() <em>Multiplicity</em>}' attribute.
@@ -146,7 +146,7 @@
    */
   public boolean isUnordered()
   {
-    return unordered;
+    return (eFlags & UNORDERED_EFLAG) != 0;
   }
 
   /**
@@ -156,10 +156,10 @@
    */
   public void setUnordered(boolean newUnordered)
   {
-    boolean oldUnordered = unordered;
-    unordered = newUnordered;
+    boolean oldUnordered = (eFlags & UNORDERED_EFLAG) != 0;
+    if (newUnordered) eFlags |= UNORDERED_EFLAG; else eFlags &= ~UNORDERED_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XTYPED_ELEMENT__UNORDERED, oldUnordered, unordered));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XTYPED_ELEMENT__UNORDERED, oldUnordered, newUnordered));
   }
 
   /**
@@ -169,7 +169,7 @@
    */
   public boolean isUnique()
   {
-    return unique;
+    return (eFlags & UNIQUE_EFLAG) != 0;
   }
 
   /**
@@ -179,10 +179,10 @@
    */
   public void setUnique(boolean newUnique)
   {
-    boolean oldUnique = unique;
-    unique = newUnique;
+    boolean oldUnique = (eFlags & UNIQUE_EFLAG) != 0;
+    if (newUnique) eFlags |= UNIQUE_EFLAG; else eFlags &= ~UNIQUE_EFLAG;
     if (eNotificationRequired())
-      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XTYPED_ELEMENT__UNIQUE, oldUnique, unique));
+      eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XTYPED_ELEMENT__UNIQUE, oldUnique, newUnique));
   }
 
   /**
@@ -204,8 +204,8 @@
   {
     XGenericType oldType = type;
     type = newType;
-    boolean oldTypeESet = typeESet;
-    typeESet = true;
+    boolean oldTypeESet = (eFlags & TYPE_ESETFLAG) != 0;
+    eFlags |= TYPE_ESETFLAG;
     if (eNotificationRequired())
     {
       ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, XcorePackage.XTYPED_ELEMENT__TYPE, oldType, newType, !oldTypeESet);
@@ -233,8 +233,8 @@
     }
     else
     {
-      boolean oldTypeESet = typeESet;
-      typeESet = true;
+      boolean oldTypeESet = (eFlags & TYPE_ESETFLAG) != 0;
+      eFlags |= TYPE_ESETFLAG;
       if (eNotificationRequired())
         eNotify(new ENotificationImpl(this, Notification.SET, XcorePackage.XTYPED_ELEMENT__TYPE, newType, newType, !oldTypeESet));
     }
@@ -249,8 +249,8 @@
   {
     XGenericType oldType = type;
     type = null;
-    boolean oldTypeESet = typeESet;
-    typeESet = false;
+    boolean oldTypeESet = (eFlags & TYPE_ESETFLAG) != 0;
+    eFlags &= ~TYPE_ESETFLAG;
     if (eNotificationRequired())
     {
       ENotificationImpl notification = new ENotificationImpl(this, Notification.UNSET, XcorePackage.XTYPED_ELEMENT__TYPE, oldType, null, oldTypeESet);
@@ -275,8 +275,8 @@
     }
     else
     {
-      boolean oldTypeESet = typeESet;
-      typeESet = false;
+      boolean oldTypeESet = (eFlags & TYPE_ESETFLAG) != 0;
+      eFlags &= ~TYPE_ESETFLAG;
       if (eNotificationRequired())
         eNotify(new ENotificationImpl(this, Notification.UNSET, XcorePackage.XTYPED_ELEMENT__TYPE, null, null, oldTypeESet));
     }
@@ -289,7 +289,7 @@
    */
   public boolean isSetType()
   {
-    return typeESet;
+    return (eFlags & TYPE_ESETFLAG) != 0;
   }
 
   /**
@@ -416,9 +416,9 @@
     switch (featureID)
     {
       case XcorePackage.XTYPED_ELEMENT__UNORDERED:
-        return unordered != UNORDERED_EDEFAULT;
+        return ((eFlags & UNORDERED_EFLAG) != 0) != UNORDERED_EDEFAULT;
       case XcorePackage.XTYPED_ELEMENT__UNIQUE:
-        return unique != UNIQUE_EDEFAULT;
+        return ((eFlags & UNIQUE_EFLAG) != 0) != UNIQUE_EDEFAULT;
       case XcorePackage.XTYPED_ELEMENT__TYPE:
         return isSetType();
       case XcorePackage.XTYPED_ELEMENT__MULTIPLICITY:
@@ -437,11 +437,11 @@
   {
     if (eIsProxy()) return super.toString();
 
-    StringBuffer result = new StringBuffer(super.toString());
+    StringBuilder result = new StringBuilder(super.toString());
     result.append(" (unordered: ");
-    result.append(unordered);
+    result.append((eFlags & UNORDERED_EFLAG) != 0);
     result.append(", unique: ");
-    result.append(unique);
+    result.append((eFlags & UNIQUE_EFLAG) != 0);
     result.append(", multiplicity: ");
     result.append(multiplicity);
     result.append(')');
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XcoreFactoryImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XcoreFactoryImpl.java
index 240f6f8..55e8f37 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XcoreFactoryImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XcoreFactoryImpl.java
@@ -40,7 +40,7 @@
   {
     try
     {
-      XcoreFactory theXcoreFactory = (XcoreFactory)EPackage.Registry.INSTANCE.getEFactory("http://www.eclipse.org/emf/2011/Xcore"); 
+      XcoreFactory theXcoreFactory = (XcoreFactory)EPackage.Registry.INSTANCE.getEFactory(XcorePackage.eNS_URI);
       if (theXcoreFactory != null)
       {
         return theXcoreFactory;
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XcorePackageImpl.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XcorePackageImpl.java
index 8bc1760..5c6caf0 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XcorePackageImpl.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/impl/XcorePackageImpl.java
@@ -239,7 +239,7 @@
 
   /**
    * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
-   * 
+   *
    * <p>This method is used to initialize {@link XcorePackage#eINSTANCE} when that field is accessed.
    * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package.
    * <!-- begin-user-doc -->
@@ -254,12 +254,15 @@
     if (isInited) return (XcorePackage)EPackage.Registry.INSTANCE.getEPackage(XcorePackage.eNS_URI);
 
     // Obtain or create and register package
-    XcorePackageImpl theXcorePackage = (XcorePackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof XcorePackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new XcorePackageImpl());
+    Object registeredXcorePackage = EPackage.Registry.INSTANCE.get(eNS_URI);
+    XcorePackageImpl theXcorePackage = registeredXcorePackage instanceof XcorePackageImpl ? (XcorePackageImpl)registeredXcorePackage : new XcorePackageImpl();
 
     isInited = true;
 
     // Initialize simple dependencies
+    EcorePackage.eINSTANCE.eClass();
     GenModelPackage.eINSTANCE.eClass();
+    TypesPackage.eINSTANCE.eClass();
     XbasePackage.eINSTANCE.eClass();
 
     // Create package meta-data objects
@@ -271,7 +274,6 @@
     // Mark meta-data to indicate it can't be changed
     theXcorePackage.freeze();
 
-  
     // Update the registry and return the package
     EPackage.Registry.INSTANCE.put(XcorePackage.eNS_URI, theXcorePackage);
     return theXcorePackage;
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreImportedNamespaceAwareScopeProvider.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreImportedNamespaceAwareScopeProvider.java
index 91b27f6..b4c14ea 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreImportedNamespaceAwareScopeProvider.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreImportedNamespaceAwareScopeProvider.java
@@ -46,7 +46,6 @@
 import org.eclipse.xtext.common.types.JvmGenericType;
 import org.eclipse.xtext.common.types.JvmOperation;
 import org.eclipse.xtext.common.types.JvmTypeParameter;
-import org.eclipse.xtext.common.types.TypesPackage;
 import org.eclipse.xtext.naming.IQualifiedNameConverter;
 import org.eclipse.xtext.naming.IQualifiedNameProvider;
 import org.eclipse.xtext.naming.QualifiedName;
@@ -107,13 +106,9 @@
     {
       return getAnnotationScope(context);
     }
-    else if (TypesPackage.Literals.JVM_TYPE.isSuperTypeOf(reference.getEReferenceType()))
-    {
-      return getJvmTypeScope(context, reference);
-    }
     else
     {
-      throw new IllegalArgumentException("Scope for unknown reference " + reference + " requested");
+      return getJvmTypeScope(context, reference);
     }
   }
 
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreLogicalContainerAwareReentrantTypeResolver.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreLogicalContainerAwareReentrantTypeResolver.java
index 1ee4958..21acc67 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreLogicalContainerAwareReentrantTypeResolver.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreLogicalContainerAwareReentrantTypeResolver.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2013 Eclipse contributors and others.
+ * Copyright (c) 2013-2018 Eclipse contributors 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
@@ -7,14 +7,34 @@
  */
 package org.eclipse.emf.ecore.xcore.scoping;
 
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.xcore.mappings.XcoreMapper;
 import org.eclipse.xtext.common.types.JvmDeclaredType;
 import org.eclipse.xtext.common.types.JvmGenericType;
+import org.eclipse.xtext.common.types.JvmIdentifiableElement;
 import org.eclipse.xtext.common.types.JvmType;
 import org.eclipse.xtext.common.types.JvmTypeReference;
+import org.eclipse.xtext.xbase.XBlockExpression;
+import org.eclipse.xtext.xbase.XExpression;
+import org.eclipse.xtext.xbase.scoping.batch.IFeatureScopeSession;
 import org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver;
+import org.eclipse.xtext.xbase.typesystem.internal.ResolvedTypes;
+
+import com.google.inject.Inject;
 
 public class XcoreLogicalContainerAwareReentrantTypeResolver extends LogicalContainerAwareReentrantTypeResolver
 {
+  @Inject
+  protected XcoreMapper mapper;
+
+  protected Set<EObject> handledExpressions;
+
   @Override
   public JvmTypeReference getExtendedClass(JvmDeclaredType type)
   {
@@ -38,4 +58,40 @@
     }
     return result;
   }
+
+  @Override
+  protected boolean isHandled(XExpression expression)
+  {
+    return handledExpressions != null && handledExpressions.contains(expression);
+  }
+
+  @Override
+  protected Map<JvmIdentifiableElement, ResolvedTypes> prepare(ResolvedTypes resolvedTypes, IFeatureScopeSession featureScopeSession)
+  {
+    handledExpressions = null;
+    Map<JvmIdentifiableElement, ResolvedTypes> result = super.prepare(resolvedTypes, featureScopeSession);
+    for (EObject eObject : rootedInstances)
+    {
+      if (eObject instanceof XBlockExpression)
+      {
+        if (handledExpressions == null)
+        {
+          handledExpressions = new HashSet<EObject>();
+        }
+        handledExpressions.add(eObject);
+        for (Iterator<EObject> i = eObject.eAllContents(); i.hasNext(); )
+        {
+          handledExpressions.add(i.next());
+        }
+      }
+    }
+    return result;
+  }
+
+  @Override
+  protected void clear()
+  {
+    super.clear();
+    handledExpressions = null;
+  }
 }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/EcoreXcoreBuilder.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/EcoreXcoreBuilder.java
index 5d137ec..ebdaff8 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/EcoreXcoreBuilder.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/EcoreXcoreBuilder.java
@@ -26,7 +26,6 @@
 import org.eclipse.emf.codegen.ecore.genmodel.GenParameter;
 import org.eclipse.emf.codegen.ecore.genmodel.GenTypeParameter;
 import org.eclipse.emf.codegen.util.CodeGenUtil;
-import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EAnnotation;
@@ -407,8 +406,8 @@
         {
           public void run()
           {
-            Diagnostic diagnostic = EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(finalInstanceTypeName);
-            xClassifier.setInstanceType(jvmInferrer.getJvmTypeReference((EGenericType)diagnostic.getData().get(0), eClassifier));
+            EGenericType eGenericType = EcoreValidator.EGenericTypeBuilder.INSTANCE.buildEGenericType(finalInstanceTypeName);
+            xClassifier.setInstanceType(jvmInferrer.getJvmTypeReference(eGenericType, eClassifier));
           }
         });
     }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreEcoreBuilder.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreEcoreBuilder.java
index 5850a53..80ba23b 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreEcoreBuilder.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreEcoreBuilder.java
@@ -752,8 +752,7 @@
         if (instanceType != null)
         {
           String instanceTypeName = instanceType.getIdentifier();
-          String normalizedInstanceTypeName = EcoreUtil.toJavaInstanceTypeName(
-            (EGenericType)EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(instanceTypeName).getData().get(0));
+          String normalizedInstanceTypeName = EcoreUtil.toJavaInstanceTypeName((EGenericType)EcoreValidator.EGenericTypeBuilder.INSTANCE.buildEGenericType(instanceTypeName));
           setInstanceTypeName(normalizedInstanceTypeName);
           if (classLoader != null)
           {
@@ -836,8 +835,7 @@
         if (instanceType != null)
         {
           String instanceTypeName = instanceType.getIdentifier();
-          String normalizedInstanceTypeName = EcoreUtil.toJavaInstanceTypeName(
-            (EGenericType)EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(instanceTypeName).getData().get(0));
+          String normalizedInstanceTypeName = EcoreUtil.toJavaInstanceTypeName(EcoreValidator.EGenericTypeBuilder.INSTANCE.buildEGenericType(instanceTypeName));
           setInstanceTypeName(normalizedInstanceTypeName);
           if (classLoader != null)
           {
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreJvmInferrer.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreJvmInferrer.java
index ce85196..f2b9695 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreJvmInferrer.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreJvmInferrer.java
@@ -108,6 +108,7 @@
 
   public static void inferName(GenBase genBase)
   {
+    genBase.getGenModel().clearCache();
     Adapter adapter = EcoreUtil.getAdapter(genBase.eAdapters(), InferenceAdapter.class);
     if (adapter != null)
     {
@@ -230,6 +231,7 @@
       }
     }
 
+    genModel.clearCache();
     cache.clear(genModel.eResource());
   }
 
@@ -384,7 +386,6 @@
                     public void inferName()
                     {
                       inferredElement.setSimpleName("case" + genPackage.getClassUniqueName(genClass));
-                      genPackage.clearCache();
                     }
                   };
                 associate(genClass, caseMethodInferrer);
@@ -974,7 +975,6 @@
                       public void inferName()
                       {
                         inferredElement.setSimpleName("test" + genClass.getUniqueName(genOperation));
-                        genClass.clearCache();
                       }
                     };
                   associate(genOperation, operationTestInferrer);
@@ -1322,7 +1322,6 @@
                               public void inferName()
                               {
                                 inferredElement.setSimpleName(genClass.getOperationID(genOperation, false));
-                                genClass.clearCache();
                               }
                             };
                           associate(genOperation, operationFieldInferrer);
@@ -1507,7 +1506,6 @@
                         public void inferName()
                         {
                           inferredElement.setSimpleName(genClass.getOperationID(genOperation, false));
-                          genClass.clearCache();
                         }
                       };
                     associate(genOperation, operationFieldInferrer);
@@ -1532,7 +1530,6 @@
                         public void inferName()
                         {
                           inferredElement.setSimpleName("get" + genOperation.getOperationAccessorName());
-                          genClass.clearCache();
                         }
                       };
                     associate(genOperation, operationAccessorInferrer);
@@ -2380,7 +2377,12 @@
           @Override
           public void inferName()
           {
-            inferredElement.setSimpleName(genFeature.getGetAccessor() + (isImplementation && genClass.hasCollidingGetAccessorOperation(genFeature) ? "_" : ""));
+            String getAccessor = genFeature.getGetAccessor();
+            if (isImplementation && genClass.hasCollidingGetAccessorOperation(genFeature))
+            {
+              getAccessor += "_";
+            }
+            inferredElement.setSimpleName(getAccessor);
           }
         };
       associate(genFeature, getAccessorInferrer);
@@ -2674,8 +2676,7 @@
       EGenericType eGenericType = eGenericTypes.get(instanceTypeName);
       if (eGenericType == null)
       {
-        Diagnostic diagnostic = EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(instanceTypeName);
-        eGenericType = (EGenericType)diagnostic.getData().get(0);
+        eGenericType = EcoreValidator.EGenericTypeBuilder.INSTANCE.buildEGenericType(instanceTypeName);
         eGenericTypes.put(instanceTypeName, eGenericType);
       }
       return eGenericType;
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreSwitch.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreSwitch.java
index 46a70c1..548a121 100644
--- a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreSwitch.java
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/util/XcoreSwitch.java
@@ -59,7 +59,7 @@
    * Checks whether this is a switch for the given package.
    * <!-- begin-user-doc -->
    * <!-- end-user-doc -->
-   * @parameter ePackage the package in question.
+   * @param ePackage the package in question.
    * @return whether this is a switch for the given package.
    * @generated
    */
diff --git a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/util/EcoreValidator.java b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/util/EcoreValidator.java
index 7300344..78c1c6a 100644
--- a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/util/EcoreValidator.java
+++ b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/util/EcoreValidator.java
@@ -4616,6 +4616,19 @@
     }
 
     /**
+     * Parses an instance type name and returns its representation as an {@link EGenericType generic type}.
+     * @param instanceTypeName an instance type name.
+     * @return the generic type representation.
+     * @since 2.15
+     */
+    public EGenericType buildEGenericType(String instanceTypeName)
+    {
+      char [] instanceTypeNameCharacterArray = instanceTypeName == null ? NO_CHARS: instanceTypeName.toCharArray();
+      EGenericType eGenericType = handleInstanceTypeName(instanceTypeNameCharacterArray, 0, instanceTypeNameCharacterArray.length, null);
+      return eGenericType;
+    }
+
+    /**
      * Parses a list of type parameters and returns a diagnostic representing the result of the analysis.
      * The {@link Diagnostic#getData() data} of the diagnostic will contain as the first object, the resulting list of {@link ETypeParameter type parameters}.
      * @param typeParameterList a comma separated list of type parameters delimited by '&lt;' and '>'.
@@ -4639,6 +4652,19 @@
     }
 
     /**
+     * Parses a list of type parameters and returns its representation as a list of {@link ETypeParameter type parameters}.
+     * @param typeParameterList a comma separated list of type parameters delimited by '&lt;' and '>'.
+     * @return the typed parameter list representation.
+     * @since 2.15
+     */
+    public List<ETypeParameter> buildETypeParameters(String typeParameterList)
+    {
+      char [] instanceTypeNameCharacterArray = typeParameterList == null ? NO_CHARS : typeParameterList.toCharArray();
+      List<ETypeParameter> eTypeParameters = handleTypeParameters(instanceTypeNameCharacterArray, 0, instanceTypeNameCharacterArray.length, null);
+      return eTypeParameters;
+    }
+
+    /**
      * Parses a list of type arguments and returns a diagnostic representing the result of the analysis.
      * The {@link Diagnostic#getData() data} of the diagnostic will contain as the first object, the resulting list of {@link EGenericType type arguments}.
      * @param typeArgumentList a comma separated list of type arguments.
@@ -4663,9 +4689,22 @@
     }
 
     /**
+     * Parses a list of type arguments and returns its representation as a list of {@link EGenericType type arguments}.
+     * @param typeArgumentList a comma separated list of type arguments.
+     * @return the generic type list representation.
+     * @since 2.15
+     */
+    public List<EGenericType> buildEGenericTypes(String typeArgumentList)
+    {
+      char [] instanceTypeNameCharacterArray = typeArgumentList == null ? NO_CHARS : typeArgumentList.toCharArray();
+      List<EGenericType> eTypeArguments = handleTypeArguments(instanceTypeNameCharacterArray, 0, instanceTypeNameCharacterArray.length, null);
+      return eTypeArguments;
+    }
+
+    /**
      * Parses a type parameter and returns a diagnostic representing the result of the analysis.
      * The {@link Diagnostic#getData() data} of the diagnostic will contain as the first object, the resulting {@link ETypeParameter type parameter}.
-     * @param typeParameter comma separated list of type parameters delimited by '&lt;' and '>'.
+     * @param typeParameter a type parameter.
      * @return the diagnostic result of the analysis.
      */
     public Diagnostic parseTypeParameter(final String typeParameter)
@@ -4686,6 +4725,19 @@
     }
 
     /**
+     * Parses a type parameter and returns its representation as {@link ETypeParameter type parameter}.
+     * @param typeParameter a type parameter.
+     * @return the diagnostic result of the analysis.
+     * @since 2.15
+     */
+    public ETypeParameter buildETypeParameter(String typeParameter)
+    {
+      char [] instanceTypeNameCharacterArray = typeParameter == null ? NO_CHARS : typeParameter.toCharArray();
+      ETypeParameter eTypeParameter = handleTypeParameter(instanceTypeNameCharacterArray, 0, instanceTypeNameCharacterArray.length, null);
+      return eTypeParameter;
+    }
+
+    /**
      * Finds or creates an {@link EClassifier classifier} with the given instance type name.
      * @param instanceTypeName the instance type name for which a classifier is needed.
      * @return a classifier with the instance type name.
diff --git a/plugins/org.eclipse.emf.importer.java/src/org/eclipse/emf/importer/java/builder/JavaEcoreBuilder.java b/plugins/org.eclipse.emf.importer.java/src/org/eclipse/emf/importer/java/builder/JavaEcoreBuilder.java
index 92df5c0..ead8ecc 100644
--- a/plugins/org.eclipse.emf.importer.java/src/org/eclipse/emf/importer/java/builder/JavaEcoreBuilder.java
+++ b/plugins/org.eclipse.emf.importer.java/src/org/eclipse/emf/importer/java/builder/JavaEcoreBuilder.java
@@ -1682,8 +1682,8 @@
       {
         if (depth == 0 && start != -1)
         {
-          Diagnostic diagnostic = EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(genericTypes.substring(start, i));
-          result.add((EGenericType)diagnostic.getData().get(0));
+          EGenericType eGenericType = EcoreValidator.EGenericTypeBuilder.INSTANCE.buildEGenericType(genericTypes.substring(start, i));
+          result.add(eGenericType);
           start = -1;
         }
       }
@@ -1694,8 +1694,8 @@
     }
     if (start != -1)
     {
-      Diagnostic diagnostic = EcoreValidator.EGenericTypeBuilder.INSTANCE.parseInstanceTypeName(genericTypes.substring(start));
-      result.add((EGenericType)diagnostic.getData().get(0));
+      EGenericType eGenericType = EcoreValidator.EGenericTypeBuilder.INSTANCE.buildEGenericType(genericTypes.substring(start));
+      result.add(eGenericType);
     }
     return result;
   }