[581496] Improve support for locating models registered via
dyanmic_package registrations
diff --git a/plugins/org.eclipse.emf.ecore.editor/src/org/eclipse/emf/ecore/presentation/EcoreActionBarContributor.java b/plugins/org.eclipse.emf.ecore.editor/src/org/eclipse/emf/ecore/presentation/EcoreActionBarContributor.java
index f81260b..84236d7 100644
--- a/plugins/org.eclipse.emf.ecore.editor/src/org/eclipse/emf/ecore/presentation/EcoreActionBarContributor.java
+++ b/plugins/org.eclipse.emf.ecore.editor/src/org/eclipse/emf/ecore/presentation/EcoreActionBarContributor.java
@@ -15,6 +15,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
@@ -263,10 +264,11 @@
                  Resource dummyResource = domain == null ? null : resourceSet.createResource(domain.getResourceSet().getResources().get(0).getURI());
 
                  StringBuffer uris = new StringBuffer();
-                 Map<String, URI> ePackageNsURItoGenModelLocationMap = EcorePlugin.getEPackageNsURIToGenModelLocationMap(true);
+                 Map<String, URI> ePackageNsURItoModelLocationMap = new HashMap<String, URI>(EcorePlugin.getEPackageNsURIToGenModelLocationMap(true));
+                 ePackageNsURItoModelLocationMap.putAll(EcorePlugin.getEPackageNsURIToDynamicModelLocationMap(true));
                  for (int i = 0, length = result.length; i < length; i++)
                  {
-                   URI location = ePackageNsURItoGenModelLocationMap.get(result[i]);
+                   URI location = ePackageNsURItoModelLocationMap.get(result[i]);
                    Resource resource = resourceSet.getResource(location, true);
                    EcoreUtil.resolveAll(resource);
                  }
@@ -316,10 +318,11 @@
                    Resource dummyResource = domain == null ? null : resourceSet.createResource(domain.getResourceSet().getResources().get(0).getURI());
 
                    StringBuffer uris = new StringBuffer();
-                   Map<String, URI> ePackageNsURItoGenModelLocationMap = EcorePlugin.getEPackageNsURIToGenModelLocationMap(false);
+                   Map<String, URI> ePackageNsURItoModelLocationMap = new HashMap<String, URI>(EcorePlugin.getEPackageNsURIToGenModelLocationMap(false));
+                   ePackageNsURItoModelLocationMap.putAll(EcorePlugin.getEPackageNsURIToDynamicModelLocationMap(false));
                    for (int i = 0, length = result.length; i < length; i++)
                    {
-                     URI location = ePackageNsURItoGenModelLocationMap.get(result[i]);
+                     URI location = ePackageNsURItoModelLocationMap.get(result[i]);
                      Resource resource = resourceSet.getResource(location, true);
                      EcoreUtil.resolveAll(resource);
                    }
@@ -383,8 +386,9 @@
 
       protected void updateElements()
       {
-        Map<String, URI> ePackageNsURItoGenModelLocationMap = EcorePlugin.getEPackageNsURIToGenModelLocationMap(true);
-        Object [] result = ePackageNsURItoGenModelLocationMap.keySet().toArray(new Object[ePackageNsURItoGenModelLocationMap.size()]);
+        Map<String, URI> ePackageNsURItoModelLocationMap = new HashMap<String, URI>(EcorePlugin.getEPackageNsURIToGenModelLocationMap(true));
+        ePackageNsURItoModelLocationMap.putAll(EcorePlugin.getEPackageNsURIToDynamicModelLocationMap(true));
+        Object [] result = ePackageNsURItoModelLocationMap.keySet().toArray(new Object[ePackageNsURItoModelLocationMap.size()]);
         Arrays.sort(result);
         setListElements(result);
       }
@@ -430,8 +434,9 @@
       {
         if (isDevelopmentTimeVersion)
         {
-          Map<String, URI> ePackageNsURItoGenModelLocationMap = EcorePlugin.getEPackageNsURIToGenModelLocationMap(false);
-          Object [] result = ePackageNsURItoGenModelLocationMap.keySet().toArray(new Object[ePackageNsURItoGenModelLocationMap.size()]);
+          Map<String, URI> ePackageNsURItoModelLocationMap = new HashMap<String, URI>(EcorePlugin.getEPackageNsURIToGenModelLocationMap(false));
+          ePackageNsURItoModelLocationMap.putAll(EcorePlugin.getEPackageNsURIToDynamicModelLocationMap(false));
+          Object [] result = ePackageNsURItoModelLocationMap.keySet().toArray(new Object[ePackageNsURItoModelLocationMap.size()]);
           Arrays.sort(result);
           setListElements(result);
         }
diff --git a/plugins/org.eclipse.emf.ecore.editor/src/org/eclipse/emf/ecore/presentation/EcoreEditor.java b/plugins/org.eclipse.emf.ecore.editor/src/org/eclipse/emf/ecore/presentation/EcoreEditor.java
index e3fb7ff..edae41a 100644
--- a/plugins/org.eclipse.emf.ecore.editor/src/org/eclipse/emf/ecore/presentation/EcoreEditor.java
+++ b/plugins/org.eclipse.emf.ecore.editor/src/org/eclipse/emf/ecore/presentation/EcoreEditor.java
@@ -2166,7 +2166,7 @@
 
     private final ResourceSet modelResourceSet;
 
-    private Map<String, URI> ePackageNsURItoGenModelLocationMap;
+    private Map<String, URI> ePackageNsURItoModelLocationMap;
 
     public DynamicLoadingEPackageRegistryImpl(ResourceSet editorResourceSet)
     {
@@ -2187,12 +2187,13 @@
 
       if (ePackage == null)
       {
-        if (ePackageNsURItoGenModelLocationMap == null)
+        if (ePackageNsURItoModelLocationMap == null)
         {
-          ePackageNsURItoGenModelLocationMap = EcorePlugin.getEPackageNsURIToGenModelLocationMap(true);
+          ePackageNsURItoModelLocationMap = new HashMap<String, URI>(EcorePlugin.getEPackageNsURIToGenModelLocationMap(true));
+          ePackageNsURItoModelLocationMap.putAll(EcorePlugin.getEPackageNsURIToDynamicModelLocationMap(true));
         }
 
-        URI location = ePackageNsURItoGenModelLocationMap.get(nsURI);
+        URI location = ePackageNsURItoModelLocationMap.get(nsURI);
         if (location != null)
         {
           EList<Resource> modelResources = modelResourceSet.getResources();
diff --git a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/plugin/DynamicPackageRegistryReader.java b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/plugin/DynamicPackageRegistryReader.java
index e5f8c77..0c3b746 100644
--- a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/plugin/DynamicPackageRegistryReader.java
+++ b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/plugin/DynamicPackageRegistryReader.java
@@ -11,9 +11,12 @@
 package org.eclipse.emf.ecore.plugin;
 
 
+import java.util.Map;
+
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.RegistryFactory;
 
+import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EPackage;
 
 /**
@@ -27,6 +30,11 @@
   static final String ATT_URI = "uri";
   static final String ATT_LOCATION = "location";
 
+  /**
+   * @since 2.33
+   */
+  protected Map<String, URI> ePackageNsURIToDynamicModelLocationMap;
+
   public DynamicPackageRegistryReader()
   {
     super
@@ -35,6 +43,15 @@
        EcorePlugin.DYNAMIC_PACKAGE_PPID);
   }
 
+  /**
+   * @since 2.33
+   */
+  public DynamicPackageRegistryReader(Map<String, URI> ePackageNsURIToDynamicModelLocationMap)
+  {
+    this();
+    this.ePackageNsURIToDynamicModelLocationMap = ePackageNsURIToDynamicModelLocationMap;
+  }
+
   @Override
   protected boolean readElement(IConfigurationElement element, boolean add)
   {
@@ -58,12 +75,28 @@
           EcorePlugin.INSTANCE.log
             ("Both '" + descriptor.element.getContributor().getName() + "' and '" + element.getContributor().getName() + "' register a package for '" + packageURI + "'");
         }
-        
+        if (ePackageNsURIToDynamicModelLocationMap != null)
+        {
+          String dynamicModel = element.getAttribute(ATT_LOCATION);
+          if (dynamicModel != null)
+          {
+            URI dynamicModelURI = URI.createURI(dynamicModel);
+            if (dynamicModelURI.isRelative())
+            {
+              dynamicModelURI = URI.createPlatformPluginURI(element.getDeclaringExtension().getContributor().getName() + "/" + dynamicModel, true);
+            }
+            ePackageNsURIToDynamicModelLocationMap.put(packageURI, dynamicModelURI);
+          }
+        }
         return true;
       }
       else
       {
         EPackage.Registry.INSTANCE.remove(packageURI);
+        if (ePackageNsURIToDynamicModelLocationMap != null)
+        {
+          ePackageNsURIToDynamicModelLocationMap.remove(packageURI);
+        }
         return true;
       }
     }
diff --git a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/plugin/EcorePlugin.java b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/plugin/EcorePlugin.java
index 1654121..c3af32b 100644
--- a/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/plugin/EcorePlugin.java
+++ b/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/plugin/EcorePlugin.java
@@ -584,6 +584,42 @@
     }
     return result;
   }
+
+  /**
+   * Returns a map from {@link EPackage#getNsURI() package namespace URI} (represented as a String) 
+   * to the location of the dynamic model for the package (represented as a {@link URI URI})
+   * for either the target platform or the environment itself.
+   * If there is no target platform, i.e., if the PDE is not installed, it defaults back to the environment.
+   * It's generally expected that an application using these URIs will also {@link URIConverter#getURIMap() register} the mappings returned by {@link #computePlatformURIMap(boolean)}.
+   * @param targetPlatform whether to get locations for the target platform or for the environment itself; the former is preferred.
+   * @return a map from package namespace to dynamic model location.
+   * @see #computePlatformURIMap(boolean)
+   * @since 2.33
+   */
+  public static Map<String, URI> getEPackageNsURIToDynamicModelLocationMap(boolean targetPlatform)
+  {
+    if (!targetPlatform || !IS_RESOURCES_BUNDLE_AVAILABLE || !PDEHelper.IS_PDE_BUNDLE_AVAILABLE)
+    {
+      if (ePackageNsURIToDynamicModelLocationMap == null)
+      {
+        ePackageNsURIToDynamicModelLocationMap = new HashMap<String, URI>();
+      }
+      return ePackageNsURIToDynamicModelLocationMap;
+    }
+    else
+    {
+      Map<String, URI> nsURIMap = new HashMap<String, URI>();
+      try
+      {
+        PDEHelper.computeModels(null, null, nsURIMap);
+      }
+      catch (Exception exception)
+      {
+        INSTANCE.log(exception);
+      }
+      return nsURIMap;
+    }
+  }
   
   /**
    * The platform resource map.
@@ -593,10 +629,16 @@
   
   /**
    * The map from package namespace URIs to the location of the GenModel for that package.
-   * @see #getPlatformResourceMap
+   * @see #getEPackageNsURIToGenModelLocationMap(boolean)
    */
   private static Map<String, URI> ePackageNsURIToGenModelLocationMap;
 
+  /**
+   * The map from package namespace URIs to the location of the GenModel for that package.
+   * @see #getEPackageNsURIToDynamicModelLocationMap(boolean)
+   */
+  private static Map<String, URI> ePackageNsURIToDynamicModelLocationMap;
+
   /** 
    * A plugin implementation that handles Ecore plugin registration.
    * @see #startup()
@@ -913,7 +955,7 @@
       }.readRegistry();
 
       new GeneratedPackageRegistryReader(getEPackageNsURIToGenModelLocationMap(false)).readRegistry();
-      new DynamicPackageRegistryReader().readRegistry();
+      new DynamicPackageRegistryReader(getEPackageNsURIToDynamicModelLocationMap(false)).readRegistry();
       new FactoryOverrideRegistryReader().readRegistry();
       new ExtensionParserRegistryReader().readRegistry();
       new ProtocolParserRegistryReader().readRegistry();
@@ -1171,7 +1213,12 @@
       IS_PDE_BUNDLE_AVAILABLE = isPDEBundleAvailable && !"true".equals(System.getProperty("org.eclipse.emf.common.CommonPlugin.doNotUsePDE"));
     }
 
-    private static void computeModels(Map<URI, URI> pluginMap, Map<String, URI> nsURIMap)
+    private static void computeModels(Map<URI, URI> pluginMap, Map<String, URI> nsURIToGenModelLocationMap)
+    {
+      computeModels(pluginMap, nsURIToGenModelLocationMap, null);
+    }
+
+    private static void computeModels(Map<URI, URI> pluginMap, Map<String, URI> nsURIToGenModelLocationMap, Map<String, URI> nsURIToDynamicModelLocationMap)
     {
       // Cache the workspace for use in the loop.
       //
@@ -1273,20 +1320,25 @@
                   }
                 }
 
-                // If we're not computing the nsURI map, we're done with this plugin.
+                // If we're not computing nsURI maps, we're done with this plugin.
                 //
-                if (nsURIMap == null)
+                if (nsURIToGenModelLocationMap == null && nsURIToDynamicModelLocationMap == null)
                 {
                   continue LOOP;
                 }
 
                 // Map the nsURI to the logical location URI of the registered GenModel, if we're dealing with a generated package extension point.
                 //
-                // nsURIMap.put(uri.getValue(), logicalLocation.appendSegments(new Path(genModel.getValue()).segments()));
-                //
-                if (isGenerated)
+                if (nsURIToGenModelLocationMap != null && isGenerated)
                 {
-                  nsURIMap.put(uri, logicalLocation.appendSegments(new Path(modelLocation).segments()));
+                  nsURIToGenModelLocationMap.put(uri, logicalLocation.appendSegments(new Path(modelLocation).segments()));
+                }
+
+                // Map the nsURI to the logical location URI of the registered dynamic model, if we're dealing with a dynamic package extension point.
+                //
+                if (nsURIToDynamicModelLocationMap != null && !isGenerated)
+                {
+                  nsURIToDynamicModelLocationMap.put(uri, logicalLocation.appendSegments(new Path(modelLocation).segments()));
                 }
               }
             }