Improved original extension point.
diff --git a/plugins/org.eclipse.acceleo.engine/schema/dynamic.templates.exsd b/plugins/org.eclipse.acceleo.engine/schema/dynamic.templates.exsd
index 113fe1e..464939e 100644
--- a/plugins/org.eclipse.acceleo.engine/schema/dynamic.templates.exsd
+++ b/plugins/org.eclipse.acceleo.engine/schema/dynamic.templates.exsd
@@ -1,111 +1,103 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Schema file written by PDE -->
-<schema targetNamespace="org.eclipse.acceleo.engine" xmlns="http://www.w3.org/2001/XMLSchema">
-<annotation>
-      <appinfo>
-         <meta.schema plugin="org.eclipse.acceleo.engine" id="org.eclipse.acceleo.engine.dynamic.templates" name="org.eclipse.acceleo.engine.dynamic.templates"/>
-      </appinfo>
-      <documentation>
-         This extension point allows a third-party plugin to indicate it defines dynamic overrides for a generation.
-      </documentation>
-   </annotation>
-
-   <element name="extension">
-      <annotation>
-         <appinfo>
-            <meta.element />
-         </appinfo>
-      </annotation>
-      <complexType>
-         <sequence minOccurs="1" maxOccurs="unbounded">
-            <element ref="templates"/>
-         </sequence>
-         <attribute name="point" type="string" use="required">
-            <annotation>
-               <documentation>
-                  
-               </documentation>
-            </annotation>
-         </attribute>
-         <attribute name="id" type="string">
-            <annotation>
-               <documentation>
-                  
-               </documentation>
-            </annotation>
-         </attribute>
-         <attribute name="name" type="string">
-            <annotation>
-               <documentation>
-                  
-               </documentation>
-               <appinfo>
-                  <meta.attribute translatable="true"/>
-               </appinfo>
-            </annotation>
-         </attribute>
-      </complexType>
-   </element>
-
-   <element name="templates">
-      <complexType>
-         <attribute name="path" type="string" use="required">
-            <annotation>
-               <documentation>
-                  Path to the directory containing the templates.
-               </documentation>
-               <appinfo>
-                  <meta.attribute kind="resource"/>
-               </appinfo>
-            </annotation>
-         </attribute>
-      </complexType>
-   </element>
-
-   <annotation>
-      <appinfo>
-         <meta.section type="since"/>
-      </appinfo>
-      <documentation>
-         0.8
-      </documentation>
-   </annotation>
-
-   <annotation>
-      <appinfo>
-         <meta.section type="examples"/>
-      </appinfo>
-      <documentation>
-      </documentation>
-   </annotation>
-
-   <annotation>
-      <appinfo>
-         <meta.section type="apiinfo"/>
-      </appinfo>
-      <documentation>
-      </documentation>
-   </annotation>
-
-   <annotation>
-      <appinfo>
-         <meta.section type="implementation"/>
-      </appinfo>
-      <documentation>
-      </documentation>
-   </annotation>
-
-   <annotation>
-      <appinfo>
-         <meta.section type="copyright"/>
-      </appinfo>
-      <documentation>
-         Copyright (c) 2009, 2011 Obeo.
-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
-      </documentation>
-   </annotation>
-
-</schema>
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.acceleo.engine" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appInfo>

+         <meta.schema plugin="org.eclipse.acceleo.engine" id="org.eclipse.acceleo.engine.dynamic.templates" name="org.eclipse.acceleo.engine.dynamic.templates"/>

+      </appInfo>

+      <documentation>

+         This extension point allows a third-party plugin to indicate it defines dynamic overrides for a generation.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appInfo>

+            <meta.element />

+         </appInfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="templates"/>

+            <element ref="generator" minOccurs="0" maxOccurs="1"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appInfo>

+                  <meta.attribute translatable="true"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="templates">

+      <complexType>

+         <attribute name="path" type="string" use="required">

+            <annotation>

+               <documentation>

+                  Path to the directory containing the templates.

+               </documentation>

+               <appInfo>

+                  <meta.attribute kind="resource"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="generator">

+      <complexType>

+         <attribute name="generatorID" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="since"/>

+      </appInfo>

+      <documentation>

+         0.8

+      </documentation>

+   </annotation>

+

+

+

+

+   <annotation>

+      <appInfo>

+         <meta.section type="copyright"/>

+      </appInfo>

+      <documentation>

+         Copyright (c) 2009, 2011 Obeo.

+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

+      </documentation>

+   </annotation>

+

+</schema>

diff --git a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/environment/AcceleoEvaluationEnvironment.java b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/environment/AcceleoEvaluationEnvironment.java
index b42d69c..169eafc 100644
--- a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/environment/AcceleoEvaluationEnvironment.java
+++ b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/environment/AcceleoEvaluationEnvironment.java
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.eclipse.acceleo.common.internal.utils.workspace.BundleURLConverter;
 import org.eclipse.acceleo.common.utils.CircularArrayDeque;
 import org.eclipse.acceleo.common.utils.CompactHashSet;
 import org.eclipse.acceleo.common.utils.CompactLinkedHashSet;
@@ -41,6 +42,7 @@
 import org.eclipse.emf.common.util.BasicEList;
 import org.eclipse.emf.common.util.ECollections;
 import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EClassifier;
 import org.eclipse.emf.ecore.EDataType;
@@ -721,40 +723,66 @@
 	 * @return The set of loaded modules.
 	 */
 	private Set<Module> loadDynamicModules() {
-		final Set<File> dynamicModuleFiles = AcceleoDynamicTemplatesRegistry.INSTANCE.getRegisteredModules();
+		final Set<File> dynamicModuleFiles = new CompactLinkedHashSet<File>();
 		final Set<Module> dynamicModules = new CompactLinkedHashSet<Module>();
 		// shortcut
-		if (dynamicModuleFiles.size() > 0) {
-			ResourceSet resourceSet = null;
-			for (Module module : currentModules) {
-				if (module.eResource() != null && module.eResource().getResourceSet() != null) {
-					resourceSet = module.eResource().getResourceSet();
-					break;
+		ResourceSet resourceSet = null;
+		for (Module module : currentModules) {
+			if (module.eResource() != null && module.eResource().getResourceSet() != null) {
+				resourceSet = module.eResource().getResourceSet();
+				break;
+			}
+		}
+		// If we couldn't find a resourceSet, break the loading loop and log an exception
+		if (resourceSet == null) {
+			// set as a blocker so that it is logged as an error
+			AcceleoEnginePlugin.log(AcceleoEngineMessages
+					.getString("AcceleoEvaluationEnvironment.DynamicModulesLoadingFailure"), true); //$NON-NLS-1$
+			return dynamicModules;
+		}
+		if (!(resourceSet.getURIConverter() instanceof DynamicModulesURIConverter)) {
+			resourceSet.setURIConverter(new DynamicModulesURIConverter(resourceSet.getURIConverter(), this));
+		}
+		// We have a resource set, let's find out where its module are coming from
+		List<Resource> resources = resourceSet.getResources();
+		for (Resource resource : resources) {
+			URI uri = resource.getURI();
+			String generatorID = uri.toString();
+
+			// Chicken sacrifice done right! /!\ Warning voodoo magic /!\
+			if (uri.isPlatformPlugin() && uri.segments().length > 2) {
+				generatorID = uri.segment(1);
+			} else if (uri.isPlatformResource() && uri.segments().length > 2) {
+				// Not supposed to happen since extension point works only when deployed in eclipse
+				generatorID = uri.segment(1);
+			} else if (uri.isPlatform() && uri.segments().length > 2) {
+				// Not supposed to happen since extension point works only when deployed in eclipse
+				generatorID = uri.segment(1);
+			} else if (uri.isFile()) {
+				BundleURLConverter converter = new BundleURLConverter(generatorID);
+				generatorID = converter.resolveAsPlatformPlugin();
+				// generatorID = AcceleoWorkspaceUtil.resolveAsPlatformPlugin(generatorID);
+				if (generatorID != null
+						&& generatorID.startsWith("platform:/plugin/") && URI.createURI(generatorID).segments().length > 2) { //$NON-NLS-1$
+					URI tmpURI = URI.createURI(generatorID);
+					generatorID = tmpURI.segment(1);
 				}
 			}
-			// If we couldn't find a resourceSet, break the loading loop and log an exception
-			if (resourceSet == null) {
-				// set as a blocker so that it is logged as an error
-				AcceleoEnginePlugin.log(AcceleoEngineMessages
-						.getString("AcceleoEvaluationEnvironment.DynamicModulesLoadingFailure"), true); //$NON-NLS-1$
-				return dynamicModules;
-			}
-			if (!(resourceSet.getURIConverter() instanceof DynamicModulesURIConverter)) {
-				resourceSet.setURIConverter(new DynamicModulesURIConverter(resourceSet.getURIConverter(),
-						this));
-			}
-			for (File moduleFile : dynamicModuleFiles) {
-				if (moduleFile.exists() && moduleFile.canRead()) {
-					try {
-						Resource res = ModelUtils.load(moduleFile, resourceSet).eResource();
-						for (EObject root : res.getContents()) {
-							if (root instanceof Module) {
-								dynamicModules.add((Module)root);
-							}
+			final Set<File> dynamicAcceleoModulesFiles = AcceleoDynamicTemplatesRegistry.INSTANCE
+					.getRegisteredModules(generatorID);
+			dynamicModuleFiles.addAll(dynamicAcceleoModulesFiles);
+		}
+		for (File moduleFile : dynamicModuleFiles) {
+			if (moduleFile.exists() && moduleFile.canRead()) {
+				try {
+					Resource res = ModelUtils.load(moduleFile, resourceSet).eResource();
+					for (EObject root : res.getContents()) {
+						if (root instanceof Module) {
+							dynamicModules.add((Module)root);
 						}
-					} catch (IOException e) {
-						AcceleoEnginePlugin.log(e, false);
 					}
+				} catch (IOException e) {
+					AcceleoEnginePlugin.log(e, false);
 				}
 			}
 		}
diff --git a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/AcceleoDynamicModulesDescriptor.java b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/AcceleoDynamicModulesDescriptor.java
new file mode 100644
index 0000000..1068e27
--- /dev/null
+++ b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/AcceleoDynamicModulesDescriptor.java
@@ -0,0 +1,63 @@
+/*******************************************************************************

+ * Copyright (c) 2008, 2011 Obeo.

+ * 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

+ * 

+ * Contributors:

+ *     Obeo - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.acceleo.engine.internal.utils;

+

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * Utility class to represent a contribution from the dynamic module extension point.

+ * 

+ * @author <a href="mailto:stephane.begaudeau@obeo.fr">Stephane Begaudeau</a>

+ */

+public class AcceleoDynamicModulesDescriptor {

+

+	/**

+	 * The generator IDs.

+	 */

+	private List<String> generatorIDs = new ArrayList<String>();

+

+	/**

+	 * The module paths.

+	 */

+	private List<String> paths = new ArrayList<String>();

+

+	/**

+	 * The constructor.

+	 * 

+	 * @param generatorIDs

+	 *            The generator ID.

+	 * @param paths

+	 *            The paths of the dynamic modules.

+	 */

+	public AcceleoDynamicModulesDescriptor(List<String> generatorIDs, List<String> paths) {

+		this.generatorIDs = generatorIDs;

+		this.paths = paths;

+	}

+

+	/**

+	 * Returns the generator IDs.

+	 * 

+	 * @return the generator IDs.

+	 */

+	public List<String> getGeneratorIDs() {

+		return generatorIDs;

+	}

+

+	/**

+	 * Returns the paths of the dynamic modules.

+	 * 

+	 * @return The paths of the dynamic modules.

+	 */

+	public List<String> getPaths() {

+		return paths;

+	}

+}

diff --git a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/AcceleoDynamicTemplatesEclipseUtil.java b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/AcceleoDynamicTemplatesEclipseUtil.java
index 2607f02..af70489 100644
--- a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/AcceleoDynamicTemplatesEclipseUtil.java
+++ b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/AcceleoDynamicTemplatesEclipseUtil.java
@@ -36,10 +36,10 @@
  */
 public final class AcceleoDynamicTemplatesEclipseUtil {
 	/** Keeps track of the bundles extending this extension point. */
-	protected static final Map<Bundle, List<String>> EXTENDING_BUNDLES = new HashMap<Bundle, List<String>>();
+	protected static final Map<Bundle, AcceleoDynamicModulesDescriptor> EXTENDING_BUNDLES = new HashMap<Bundle, AcceleoDynamicModulesDescriptor>();
 
 	/** This will contain the modules contained by this registry. */
-	private static final Set<File> REGISTERED_MODULES = new CompactLinkedHashSet<File>();
+	private static final Set<DynamicModuleContribution> REGISTERED_MODULES = new CompactLinkedHashSet<DynamicModuleContribution>();
 
 	/**
 	 * Utility classes don't need a default constructor.
@@ -57,12 +57,33 @@
 	 *            Paths where dynamic modules are located.
 	 */
 	public static void addExtendingBundle(Bundle bundle, List<String> paths) {
-		List<String> currentPaths = EXTENDING_BUNDLES.get(bundle);
-		if (currentPaths == null) {
-			currentPaths = new ArrayList<String>();
+		AcceleoDynamicModulesDescriptor descriptor = EXTENDING_BUNDLES.get(bundle);
+		if (descriptor == null) {
+			descriptor = new AcceleoDynamicModulesDescriptor(new ArrayList<String>(), new ArrayList<String>());
 		}
-		currentPaths.addAll(paths);
-		EXTENDING_BUNDLES.put(bundle, currentPaths);
+		descriptor.getPaths().addAll(paths);
+		EXTENDING_BUNDLES.put(bundle, descriptor);
+	}
+
+	/**
+	 * Adds a bundle in the extending bundles map.
+	 * 
+	 * @param bundle
+	 *            The extending bundle.
+	 * @param acceleoDynamicModulesDescriptor
+	 *            The extension point descriptor
+	 */
+	public static void addExtendingBundle(Bundle bundle,
+			AcceleoDynamicModulesDescriptor acceleoDynamicModulesDescriptor) {
+		AcceleoDynamicModulesDescriptor descriptor = EXTENDING_BUNDLES.get(bundle);
+		if (descriptor == null) {
+			descriptor = new AcceleoDynamicModulesDescriptor(new ArrayList<String>(), new ArrayList<String>());
+		}
+
+		descriptor.getGeneratorIDs().addAll(acceleoDynamicModulesDescriptor.getGeneratorIDs());
+		descriptor.getPaths().addAll(acceleoDynamicModulesDescriptor.getPaths());
+
+		EXTENDING_BUNDLES.put(bundle, descriptor);
 	}
 
 	/**
@@ -78,9 +99,9 @@
 	 * 
 	 * @return A copy of the registered modules set.
 	 */
-	public static Set<File> getRegisteredModules() {
+	public static Set<DynamicModuleContribution> getRegisteredModules() {
 		refreshModules();
-		return new CompactLinkedHashSet<File>(REGISTERED_MODULES);
+		return new CompactLinkedHashSet<DynamicModuleContribution>(REGISTERED_MODULES);
 	}
 
 	/**
@@ -92,14 +113,15 @@
 		REGISTERED_MODULES.clear();
 		final List<Bundle> uninstalledBundles = new ArrayList<Bundle>();
 		final String pathSeparator = "/"; //$NON-NLS-1$
-		for (java.util.Map.Entry<Bundle, List<String>> entry : new CompactLinkedHashSet<java.util.Map.Entry<Bundle, List<String>>>(
+		for (java.util.Map.Entry<Bundle, AcceleoDynamicModulesDescriptor> entry : new CompactLinkedHashSet<java.util.Map.Entry<Bundle, AcceleoDynamicModulesDescriptor>>(
 				EXTENDING_BUNDLES.entrySet())) {
 			Bundle bundle = entry.getKey();
 			if (bundle.getState() == Bundle.UNINSTALLED) {
 				uninstalledBundles.add(bundle);
 				continue;
 			}
-			for (String path : entry.getValue()) {
+			AcceleoDynamicModulesDescriptor descriptor = entry.getValue();
+			for (String path : descriptor.getPaths()) {
 				String actualPath = path;
 				if (actualPath.charAt(0) != '/') {
 					actualPath = '/' + actualPath;
@@ -126,23 +148,26 @@
 					return;
 				}
 				try {
+					List<File> modules = new ArrayList<File>();
 					while (emtlFiles.hasMoreElements()) {
 						final URL next = emtlFiles.nextElement();
 						if (actualPath == pathSeparator) {
 							final File moduleFile = new File(FileLocator.toFileURL(next).getFile());
 							if (!moduleFile.isDirectory() && moduleFile.exists() && moduleFile.canRead()) {
-								REGISTERED_MODULES.add(moduleFile);
+								modules.add(moduleFile);
 							}
 						} else {
 							String emtlPath = next.getPath();
 							if (emtlPath.substring(0, emtlPath.lastIndexOf('/')).contains(actualPath)) {
 								final File moduleFile = new File(FileLocator.toFileURL(next).getFile());
 								if (!moduleFile.isDirectory() && moduleFile.exists() && moduleFile.canRead()) {
-									REGISTERED_MODULES.add(moduleFile);
+									modules.add(moduleFile);
 								}
 							}
 						}
 					}
+					REGISTERED_MODULES.add(new DynamicModuleContribution(descriptor.getGeneratorIDs(),
+							modules));
 				} catch (IOException e) {
 					AcceleoEnginePlugin.log(e, false);
 				}
diff --git a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/DynamicModuleContribution.java b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/DynamicModuleContribution.java
new file mode 100644
index 0000000..bd90e42
--- /dev/null
+++ b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/DynamicModuleContribution.java
@@ -0,0 +1,63 @@
+/*******************************************************************************

+ * Copyright (c) 2008, 2011 Obeo.

+ * 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

+ * 

+ * Contributors:

+ *     Obeo - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.acceleo.engine.internal.utils;

+

+import java.io.File;

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * A dynamic module contribution.

+ * 

+ * @author <a href="mailto:stephane.begaudeau@obeo.fr">Stephane Begaudeau</a>

+ */

+public class DynamicModuleContribution {

+	/**

+	 * The generator IDs.

+	 */

+	private List<String> generatorIDs = new ArrayList<String>();

+

+	/**

+	 * The module files.

+	 */

+	private List<File> files = new ArrayList<File>();

+

+	/**

+	 * The constructor.

+	 * 

+	 * @param generatorIDs

+	 *            The generator ID.

+	 * @param files

+	 *            The files of the dynamic modules.

+	 */

+	public DynamicModuleContribution(List<String> generatorIDs, List<File> files) {

+		this.generatorIDs = generatorIDs;

+		this.files = files;

+	}

+

+	/**

+	 * Returns the generator IDs.

+	 * 

+	 * @return the generator IDs.

+	 */

+	public List<String> getGeneratorIDs() {

+		return generatorIDs;

+	}

+

+	/**

+	 * Returns the files of the dynamic modules.

+	 * 

+	 * @return The files of the dynamic modules.

+	 */

+	public List<File> getFiles() {

+		return files;

+	}

+}

diff --git a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/DynamicTemplatesRegistryListener.java b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/DynamicTemplatesRegistryListener.java
index 5efcfea..e170ac0 100644
--- a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/DynamicTemplatesRegistryListener.java
+++ b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/internal/utils/DynamicTemplatesRegistryListener.java
@@ -37,6 +37,12 @@
 	/** Name of the extension point's "templates" tag. */
 	private static final String DYNAMIC_TEMPLATES_TAG_TEMPLATES = "templates"; //$NON-NLS-1$
 
+	/** Name of the extension point's "generator" tag. */
+	private static final String DYNAMIC_TEMPLATES_TAG_GENERATOR = "generator"; //$NON-NLS-1$
+
+	/** Name of the extension point's "generator ID" tag. */
+	private static final String DYNAMIC_MODULES_TAG_GENERATOR_ID = "generatorID"; //$NON-NLS-1$
+
 	/**
 	 * {@inheritDoc}
 	 * 
@@ -101,12 +107,18 @@
 	private void parseExtension(IExtension extension) {
 		final IConfigurationElement[] configElements = extension.getConfigurationElements();
 		final List<String> paths = new ArrayList<String>(configElements.length);
+		final List<String> generators = new ArrayList<String>(configElements.length);
 		for (IConfigurationElement elem : configElements) {
 			if (DYNAMIC_TEMPLATES_TAG_TEMPLATES.equals(elem.getName())) {
 				String path = elem.getAttribute(DYNAMIC_TEMPLATES_ATTRIBUTE_PATH);
 				if (path != null) {
 					paths.add(path);
 				}
+			} else if (DYNAMIC_TEMPLATES_TAG_GENERATOR.equals(elem.getName())) {
+				String generator = elem.getAttribute(DYNAMIC_MODULES_TAG_GENERATOR_ID);
+				if (generator != null) {
+					generators.add(generator);
+				}
 			}
 		}
 		final Bundle bundle = Platform.getBundle(extension.getContributor().getName());
@@ -115,7 +127,9 @@
 			if (paths.size() == 0) {
 				paths.add("/"); //$NON-NLS-1$
 			}
-			AcceleoDynamicTemplatesEclipseUtil.addExtendingBundle(bundle, paths);
+			AcceleoDynamicModulesDescriptor acceleoDynamicModulesDescriptor = new AcceleoDynamicModulesDescriptor(
+					generators, paths);
+			AcceleoDynamicTemplatesEclipseUtil.addExtendingBundle(bundle, acceleoDynamicModulesDescriptor);
 		}
 	}
 }
diff --git a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/service/AcceleoDynamicTemplatesRegistry.java b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/service/AcceleoDynamicTemplatesRegistry.java
index e195ae6..79b0d9c 100644
--- a/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/service/AcceleoDynamicTemplatesRegistry.java
+++ b/plugins/org.eclipse.acceleo.engine/src/org/eclipse/acceleo/engine/service/AcceleoDynamicTemplatesRegistry.java
@@ -13,11 +13,13 @@
 import java.io.File;
 import java.io.FileFilter;
 import java.util.Collection;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.acceleo.common.IAcceleoConstants;
 import org.eclipse.acceleo.common.utils.CompactLinkedHashSet;
 import org.eclipse.acceleo.engine.internal.utils.AcceleoDynamicTemplatesEclipseUtil;
+import org.eclipse.acceleo.engine.internal.utils.DynamicModuleContribution;
 import org.eclipse.emf.common.EMFPlugin;
 
 /**
@@ -121,7 +123,42 @@
 	public Set<File> getRegisteredModules() {
 		final Set<File> compound = new CompactLinkedHashSet<File>();
 		if (EMFPlugin.IS_ECLIPSE_RUNNING) {
-			compound.addAll(AcceleoDynamicTemplatesEclipseUtil.getRegisteredModules());
+			Set<DynamicModuleContribution> modules = AcceleoDynamicTemplatesEclipseUtil
+					.getRegisteredModules();
+			for (DynamicModuleContribution dynamicModuleContribution : modules) {
+				compound.addAll(dynamicModuleContribution.getFiles());
+			}
+		}
+		compound.addAll(registeredModules);
+		return compound;
+	}
+
+	/**
+	 * Returns all registered modules that are contributing to the generation of the generator with the given
+	 * ID. The returned set is a copy of this instance's.
+	 * 
+	 * @param generatorID
+	 *            The generator ID.
+	 * @return A copy of the registered modules set.
+	 * @since 3.1
+	 */
+	public Set<File> getRegisteredModules(String generatorID) {
+		final Set<File> compound = new CompactLinkedHashSet<File>();
+		if (EMFPlugin.IS_ECLIPSE_RUNNING) {
+			Set<DynamicModuleContribution> modules = AcceleoDynamicTemplatesEclipseUtil
+					.getRegisteredModules();
+			for (DynamicModuleContribution dynamicModuleContribution : modules) {
+				List<String> generatorIDs = dynamicModuleContribution.getGeneratorIDs();
+				if (generatorIDs.size() > 0) {
+					for (String genID : generatorIDs) {
+						if (genID.equals(generatorID)) {
+							compound.addAll(dynamicModuleContribution.getFiles());
+						}
+					}
+				} else {
+					compound.addAll(dynamicModuleContribution.getFiles());
+				}
+			}
 		}
 		compound.addAll(registeredModules);
 		return compound;