[431307] Fix problems with large sets of interdependant Xcore models
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 d3a55fb..61322b2 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
@@ -1924,7 +1924,8 @@
 
     // A single set of special packages should be cached by the main GenModel.
     //
-    if (!isMainGenModel() &&
+    boolean isMainGenModel = isMainGenModel();
+    if (!isMainGenModel &&
         (ePackage == EcorePackage.eINSTANCE || ePackage == XMLTypePackage.eINSTANCE || ePackage == XMLNamespacePackage.eINSTANCE))
     {
       result = getMainGenModel().findGenPackage(ePackage);
@@ -1982,6 +1983,14 @@
         GenPackage genPackage = pIter.next();
         result = findGenPackageHelper(genPackage, ePackage);
       }
+
+      // With Xcore the GenModel might be in a state where the usedGenPackages aren't populated yet for the dependency
+      // so also try to look up the GenPackage in the main GenModel.
+      //
+      if (result == null && !isMainGenModel)
+      {
+        result = getMainGenModel().findGenPackage(ePackage);
+      }
     }
 
     ePackageToGenPackageMap.put(ePackage, result);
diff --git a/plugins/org.eclipse.emf.ecore.xcore.ui/src/org/eclipse/emf/ecore/xcore/ui/XcoreJavaProjectProvider.java b/plugins/org.eclipse.emf.ecore.xcore.ui/src/org/eclipse/emf/ecore/xcore/ui/XcoreJavaProjectProvider.java
index 6040d2c..7e3dae0 100644
--- a/plugins/org.eclipse.emf.ecore.xcore.ui/src/org/eclipse/emf/ecore/xcore/ui/XcoreJavaProjectProvider.java
+++ b/plugins/org.eclipse.emf.ecore.xcore.ui/src/org/eclipse/emf/ecore/xcore/ui/XcoreJavaProjectProvider.java
@@ -21,6 +21,7 @@
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
 import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
@@ -123,14 +124,16 @@
     IJavaProject project = getJavaProject(resourceSet);
     if (project != null)
     {
-      IWorkspaceRoot workspaceRoot = project.getProject().getWorkspace().getRoot();
+      IProject iProject = project.getProject();
+      IWorkspaceRoot workspaceRoot = iProject.getWorkspace().getRoot();
       List<URL> libraryURLs = new UniqueEList<URL>();
       try
       {
-        getAllReferencedProjects(libraryURLs, new IProject[] { project.getProject() });
+        getAllReferencedProjects(libraryURLs, new IProject[] { iProject });
         IClasspathEntry [] classpath = project.getResolvedClasspath(true);
         if (classpath != null)
         {
+          String projectName = iProject.getName();
           for (int i = 0; i < classpath.length; ++i)
           {
             IClasspathEntry classpathEntry =  classpath[i];
@@ -139,12 +142,18 @@
               case IClasspathEntry.CPE_LIBRARY:
               case IClasspathEntry.CPE_CONTAINER:
               {
-                libraryURLs.add(new URL(URI.createFileURI(classpathEntry.getPath().toString()).toString()));
+                IPath path = classpathEntry.getPath();
+                if (path.segment(0).equals(projectName))
+                {
+                  path = iProject.getLocation().append(path.removeFirstSegments(1));
+                }
+                libraryURLs.add(new URL(URI.createFileURI(path.toString()).toString()));
                 break;
               }
               case IClasspathEntry.CPE_PROJECT:
               {
-                IProject referencedProject = workspaceRoot.getProject(classpathEntry.getPath().segment(0));
+                IPath path = classpathEntry.getPath();
+                IProject referencedProject = workspaceRoot.getProject(path.segment(0));
                 IJavaProject referencedJavaProject = JavaCore.create(referencedProject);
                 IContainer container = workspaceRoot.getFolder(referencedJavaProject.getOutputLocation());
                 libraryURLs.add(new URL(URI.createFileURI(container.getLocation().toString() + "/").toString()));
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 84b9ae4..7faac0c 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
@@ -21,6 +21,7 @@
 import org.eclipse.emf.ecore.xcore.scoping.XcoreIdentifableSimpleNameProvider;
 import org.eclipse.emf.ecore.xcore.scoping.XcoreImplicitlyImportedTypes;
 import org.eclipse.emf.ecore.xcore.scoping.XcoreImportedNamespaceAwareScopeProvider;
+import org.eclipse.emf.ecore.xcore.scoping.XcoreImportsConfiguration;
 import org.eclipse.emf.ecore.xcore.scoping.XcoreLogicalContainerAwareReentrantTypeResolver;
 import org.eclipse.emf.ecore.xcore.scoping.XcoreQualifiedNameProvider;
 import org.eclipse.emf.ecore.xcore.scoping.XcoreResourceDescriptionManager;
@@ -53,6 +54,7 @@
 import org.eclipse.xtext.xbase.compiler.XbaseCompiler;
 import org.eclipse.xtext.xbase.featurecalls.IdentifiableSimpleNameProvider;
 import org.eclipse.xtext.xbase.formatting.IBasicFormatter;
+import org.eclipse.xtext.xbase.imports.IImportsConfiguration;
 import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations;
 import org.eclipse.xtext.xbase.jvmmodel.ILogicalContainerProvider;
 import org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedTypes;
@@ -231,4 +233,9 @@
   {
     return XcoreLogicalContainerAwareReentrantTypeResolver.class;
   }
+
+  public Class<? extends IImportsConfiguration> bindIImportsConfiguration() 
+  {
+    return XcoreImportsConfiguration.class;
+  }
 }
diff --git a/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreImportsConfiguration.java b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreImportsConfiguration.java
new file mode 100644
index 0000000..8ba5401
--- /dev/null
+++ b/plugins/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreImportsConfiguration.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2014 Eclipse contributors and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.emf.ecore.xcore.scoping;
+
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.xbase.imports.DefaultImportsConfiguration;
+import org.eclipse.xtext.xtype.XImportSection;
+
+public class XcoreImportsConfiguration extends DefaultImportsConfiguration
+{
+  @Override
+  public XImportSection getImportSection(XtextResource resource)
+  {
+    return null;
+  }
+  
+  @Override
+  public int getImportSectionOffset(XtextResource resource)
+  {
+    return 0;
+  }
+}
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 7739c03..d932bd9 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
@@ -61,6 +61,7 @@
 import org.eclipse.emf.ecore.xcore.XTypeParameter;
 import org.eclipse.emf.ecore.xcore.XTypedElement;
 import org.eclipse.emf.ecore.xcore.XcorePackage;
+import org.eclipse.emf.ecore.xcore.XcorePlugin;
 import org.eclipse.emf.ecore.xcore.interpreter.IClassLoaderProvider;
 import org.eclipse.emf.ecore.xcore.interpreter.XcoreConversionDelegate;
 import org.eclipse.emf.ecore.xcore.interpreter.XcoreInterpreter;
@@ -120,11 +121,25 @@
     runnables.clear();
     for (Runnable runnable : currentRunnables)
     {
-      runnable.run();
+      try
+      {
+        runnable.run();
+      }
+      catch (Throwable throwable)
+      {
+        XcorePlugin.INSTANCE.log(throwable);
+      }
     }
     for (Runnable runnable : runnables)
     {
-      runnable.run();
+      try
+      {
+        runnable.run();
+      }
+      catch (Throwable throwable)
+      {
+        XcorePlugin.INSTANCE.log(throwable);
+      }
     }
   }
 
@@ -134,7 +149,14 @@
     //
     for (Runnable runnable : instanceTypeRunnables)
     {
-      runnable.run();
+      try
+      {
+        runnable.run();
+      }
+      catch (Throwable throwable)
+      {
+        XcorePlugin.INSTANCE.log(throwable);
+      }
     }
   }
 
@@ -382,6 +404,19 @@
         //
         eClassifier.setInstanceTypeName("java.lang.Cloneable");
       }
+
+      // Populate the instance type early because GenOperation IDs depend on the data type's unqualified instance type and it might not be set so early.
+      List<INode> nodes = NodeModelUtils.findNodesForFeature(xClassifier, XcorePackage.Literals.XCLASSIFIER__INSTANCE_TYPE);
+      if (!nodes.isEmpty())
+      {
+        StringBuilder instanceTypeLiteral = new StringBuilder();
+        for (INode node : nodes)
+        {
+          instanceTypeLiteral.append(NodeModelUtils.getTokenText(node));
+        }
+        eClassifier.setInstanceTypeName(instanceTypeLiteral.toString());
+      }
+
       instanceTypeRunnables.add
         (new Runnable()
          {
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 2c11744..5d74308 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
@@ -44,6 +44,7 @@
 import org.eclipse.emf.ecore.util.EcoreValidator;
 import org.eclipse.emf.ecore.xcore.XDataType;
 import org.eclipse.emf.ecore.xcore.XNamedElement;
+import org.eclipse.emf.ecore.xcore.XcorePlugin;
 import org.eclipse.emf.ecore.xcore.mappings.ToXcoreMapping;
 import org.eclipse.emf.ecore.xcore.mappings.XcoreMapper;
 import org.eclipse.emf.ecore.xcore.scoping.LazyCreationProxyURIConverter;
@@ -245,8 +246,15 @@
     {
       for (JvmElementInferrer<?> jvmElementInferrer : Lists.newArrayList(((InferenceAdapter)adapter).jvmElementInferrers))
       {
-        jvmElementInferrer.inferDeepStructure();
-        jvmElementInferrer.resolveTypeParameterReferences();
+        try
+        {
+          jvmElementInferrer.inferDeepStructure();
+          jvmElementInferrer.resolveTypeParameterReferences();
+        }
+        catch (Throwable throwable)
+        {
+          XcorePlugin.INSTANCE.log(throwable);
+        }
       }
     }
   }