Index: TXM/trunk/bundles/org.txm.groovy.rcp/plugin.xml
===================================================================
--- TXM/trunk/bundles/org.txm.groovy.rcp/plugin.xml	(revision 3669)
+++ TXM/trunk/bundles/org.txm.groovy.rcp/plugin.xml	(revision 3670)
@@ -4,8 +4,9 @@
    <extension
          point="org.eclipse.ui.preferencePages">
       <page
-            class="org.txm.groovy.rcp.WorkbenchPreferencePage1"
-            id="org.txm.groovy.rcp.page1"
+            category="org.txm.rcp.preferences.ScriptPreferencePage"
+            class="org.txm.groovy.rcp.GroovyPreferencePage"
+            id="org.txm.groovy.rcp.GroovyPreferencePage"
             name="Groovy">
       </page>
    </extension>
Index: TXM/trunk/bundles/org.txm.groovy.rcp/META-INF/MANIFEST.MF
===================================================================
--- TXM/trunk/bundles/org.txm.groovy.rcp/META-INF/MANIFEST.MF	(revision 3669)
+++ TXM/trunk/bundles/org.txm.groovy.rcp/META-INF/MANIFEST.MF	(revision 3670)
@@ -3,6 +3,7 @@
 Bundle-Name: org.txm.groovy.rcp
 Bundle-SymbolicName: org.txm.groovy.rcp;singleton:=true
 Bundle-Version: 1.0.0.qualifier
+Export-Package: org.txm.groovy.rcp
 Bundle-Vendor: textometrie.org
 Automatic-Module-Name: org.txm.groovy.rcp
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Index: TXM/trunk/bundles/org.txm.groovy.rcp/src/org/txm/groovy/rcp/GroovyPreferencePage.java
===================================================================
--- TXM/trunk/bundles/org.txm.groovy.rcp/src/org/txm/groovy/rcp/GroovyPreferencePage.java	(revision 3669)
+++ TXM/trunk/bundles/org.txm.groovy.rcp/src/org/txm/groovy/rcp/GroovyPreferencePage.java	(revision 3670)
@@ -1,5 +1,6 @@
 package org.txm.groovy.rcp;
 
+import org.eclipse.jface.preference.BooleanFieldEditor;
 import org.eclipse.jface.preference.StringFieldEditor;
 import org.eclipse.ui.IWorkbench;
 import org.txm.groovy.core.GroovyPreferences;
@@ -15,6 +16,8 @@
 	@Override
 	protected void createFieldEditors() {
 		//this.addField(new StringFieldEditor(GroovyPreferences.ADDITIONAL_ROOT_DIRECTORY, "Additional root directory", this.getFieldEditorParent()));
+		
+		this.addField(new BooleanFieldEditor(GroovyPreferences.FAST_PACKAGE_INDEX, "Use fast package index (speed-up scripts compilation)", this.getFieldEditorParent()));
 	}
 	
 	@Override
Index: TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/GroovyPreferences.java
===================================================================
--- TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/GroovyPreferences.java	(revision 3669)
+++ TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/GroovyPreferences.java	(revision 3670)
@@ -7,6 +7,8 @@
 	public static final String PREFERENCES_NODE = GroovyPreferences.class.getName();// FrameworkUtil.getBundle(RPreferences.class).getSymbolicName();
 	
 	public static final String VERSION = "version"; //$NON-NLS-1$
+
+	public static String FAST_PACKAGE_INDEX = "fast_package_index";
 	
 	/**
 	 * Gets the instance.
@@ -23,5 +25,7 @@
 	@Override
 	public void initializeDefaultPreferences() {
 		super.initializeDefaultPreferences();
+		
+		this.put(FAST_PACKAGE_INDEX, true);
 	}
 }
Index: TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/GSERunner.java
===================================================================
--- TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/GSERunner.java	(revision 3669)
+++ TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/GSERunner.java	(revision 3670)
@@ -3,7 +3,11 @@
 import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
+import java.io.Reader;
+import java.lang.reflect.Field;
 import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -17,10 +21,12 @@
 import org.osgi.framework.wiring.BundleWiring;
 import org.txm.Toolbox;
 import org.txm.utils.BundleUtils;
+import org.txm.utils.DeleteDir;
 import org.txm.utils.logger.Log;
 
 import cern.colt.Arrays;
 import groovy.lang.Binding;
+import groovy.lang.GroovyClassLoader;
 import groovy.lang.GroovyShell;
 import groovy.util.GroovyScriptEngine;
 import groovy.util.ResourceException;
@@ -93,6 +99,13 @@
 		configuration.addCompilationCustomizers(imports);
 		
 		defaultGSE.setConfig(configuration);
+
+		// FIXME MD classes file are created but the GSE don't read from it and rewrite the class files
+//		File classesDir = new File(Toolbox.getTxmHomePath()+"/scripts/groovy/classes");
+//		classesDir.mkdirs();
+//		configuration.setTargetDirectory(classesDir);
+//		configuration.setRecompileGroovySource(false);
+//		defaultGSE.reloadCaches();	
 		
 		File jardir = new File(rootDir, "lib"); //$NON-NLS-1$
 		try {
@@ -128,6 +141,39 @@
 		return defaultGSE;
 	}
 	
+	/**
+	 * reload classes from the target directory in the sourceCache
+	 */
+	public void reloadCaches() {
+		GroovyClassLoader gcl = this.getGroovyClassLoader();
+		// get field sourceCache
+		Field field;
+		try {
+			field = gcl.getClass().getSuperclass().getDeclaredField("sourceCache");
+			field.setAccessible(true);
+			Map<String, Class> sourceCache = (Map<String, Class>) field.get(gcl);
+			
+			File target = this.getConfig().getTargetDirectory();
+			URLClassLoader classLoader = new URLClassLoader(new URL[]{target.toURI().toURL()}, Thread.currentThread().getContextClassLoader());
+					
+			for (File clazzFile : DeleteDir.scanDirectory(target, true, true)) {
+				if (!clazzFile.getName().endsWith(".class")) continue;
+				String fullclassname = clazzFile.getAbsolutePath().substring(target.getAbsolutePath().length()+1);
+				fullclassname = fullclassname.replace("/", ".");
+				fullclassname = fullclassname.replace("\\", ".");
+				fullclassname = fullclassname.substring(0, fullclassname.length()-6);
+				Class<?> clazz = Class.forName(fullclassname, true, classLoader);
+				sourceCache.put(clazzFile.getAbsolutePath(), clazz);
+			}
+			
+			//this.getConfig().setTargetDirectory((File)null);
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+	}
+
 	public Object evaluate(String code) {
 		return new GroovyShell(this.getGroovyClassLoader(), new Binding()).evaluate(code);
 	}
@@ -171,15 +217,15 @@
 		for (Bundle b : bundles) {
 			if (b == null) continue;
 			String name = b.getSymbolicName();
-			if (!name.startsWith("org.txm")) continue; // only keep txm plugins (they contains the necessary plugins deps)
-			if (name.endsWith(".core")) continue; // usually TXM *.rcp plugins depends on the *.core plugins
+			//if (!name.startsWith("org.txm")) continue; // only keep txm plugins (they contains the necessary plugins deps)
+			//if (name.endsWith(".core")) continue; // usually TXM *.rcp plugins depends on the *.core plugins
 			if (defaultPlugins.contains(name)) continue;
 			
 			BundleWiring bundleWiring = b.adapt(BundleWiring.class);
 			if (bundleWiring == null) {
 				// System.out.println("GSERunner.createGSERunner(): NO wiring: " + b.getSymbolicName());
 			}
-			else if (bundleWiring.getClassLoader() != null) {
+			else if (bundleWiring.getClassLoader() != null  && bundleWiring.getClassLoader() instanceof EquinoxClassLoader) {
 				EquinoxClassLoader loader = (EquinoxClassLoader) bundleWiring.getClassLoader();
 				
 				loaders.add(loader);
Index: TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/TXMClassLoader.java
===================================================================
--- TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/TXMClassLoader.java	(revision 3669)
+++ TXM/trunk/bundles/org.txm.groovy.core/src/java/org/txm/groovy/core/TXMClassLoader.java	(revision 3670)
@@ -1,10 +1,13 @@
 package org.txm.groovy.core;
 
+import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.HashSet;
 
 import org.eclipse.osgi.internal.loader.EquinoxClassLoader;
 
+import cern.colt.Arrays;
+
 /**
  * Class loader that looking for a class in all installed RCP Bundle then load it.
  * 
@@ -12,90 +15,134 @@
  *
  */
 public class TXMClassLoader extends ClassLoader {
-	
+
 	private HashMap<String, EquinoxClassLoader> loaders;
-	
+
+	private HashMap<String, HashSet<EquinoxClassLoader>> packageToLoaders = new HashMap<String, HashSet<EquinoxClassLoader>>();
+
 	ClassLoader defaultLoader;
-	
+
 	public TXMClassLoader(ClassLoader defaultLoader, HashSet<EquinoxClassLoader> loaders2) {
 		this.loaders = new HashMap<>();
+		
+		boolean useFastIndex = GroovyPreferences.getInstance().getBoolean(GroovyPreferences.FAST_PACKAGE_INDEX);
+		
 		for (EquinoxClassLoader loader : loaders2) {
+
 			String k = loader.getBundle().getSymbolicName();
+
 			loaders.put(k, loader);
+
+			if (useFastIndex) {
+				Dictionary<String, String> d = loader.getBundle().getHeaders();
+				String packagesString = d.get("Export-Package");
+				if (packagesString != null) {
+					packagesString = packagesString.replace("\n", "");
+					for (String p : packagesString.split(",")) {
+						p = p.trim();
+						if (p.contains(";")) p = p.substring(p.indexOf(";"));
+						if (!packageToLoaders.containsKey(p)) {
+							HashSet<EquinoxClassLoader> tmp = new HashSet<EquinoxClassLoader>();
+							packageToLoaders.put(p, tmp);
+						}
+						packageToLoaders.get(p).add(loader);
+					}
+				}
+			}
 		}
+		//		for(String p : packageToLoaders.keySet()) System.out.println(p);
 		this.defaultLoader = defaultLoader;
 	}
-	
+
 	@Override
 	public Class<?> findClass(String name) throws ClassNotFoundException {
 
 		// try with the System class loader
 		try {
-			return defaultLoader.loadClass(name);
+			Class<?> c =  defaultLoader.loadClass(name);
+			return c;
 		}
 		catch (Exception e) {
 		}
 
+		String p = null;
+		int idx = name.lastIndexOf(".");
+		if (idx > 0) {
+			p = name.substring(0, idx);
+		} else {
+			p = "";
+		}
+
+		if (packageToLoaders.containsKey(p)) {
+			for (EquinoxClassLoader loader : packageToLoaders.get(p)) {
+				if (loader != null) {
+					Class<?> c = loader.loadClass(name);
+					//System.out.println("load from "+loaderName+": "+name);
+					return c;
+				}
+			}
+		}
+
 		//TODO first tests did not boost the class loading
-//		// try using the class package name
-//		if (name.startsWith("org.txm.")) {
-//			int idx = name.indexOf(".rcp.");
-//			if (idx > 0) {
-//				String loaderName = name.substring(0, idx+4);
-//				EquinoxClassLoader loader = loaders.get(loaderName);
-//				try {
-//					if (loader != null) {
-//						Class<?> c = loader.loadClass(name);
-//						//System.out.println("load from "+loaderName+": "+name);
-//						return c;
-//					}
-//				}
-//				catch (Exception e) {
-//					//System.out.println("can't load from "+loaderName+": "+name+" "+e);
-//					if (e instanceof NullPointerException) {
-//						e.printStackTrace();
-//					}
-//				}
-//			}
-//			idx = name.indexOf(".core.");
-//			if (idx > 0) {
-//				String loaderName =name.substring(0, idx)+".rcp";
-//				EquinoxClassLoader loader = loaders.get(name.substring(0, idx)+".rcp");
-//				try {
-//					if (loader != null) {
-//						Class<?> c = loader.loadClass(name);
-//						//System.out.println("load from "+loaderName+": "+name);
-//						return c;
-//					}
-//				}
-//				catch (Exception e) {
-//					//System.out.println("can't load from "+loaderName+": "+name+" "+e);
-//					if (e instanceof NullPointerException) {
-//						e.printStackTrace();
-//					}
-//				}
-//				
-//				loaderName = name.substring(0, idx+5);
-//				loader = loaders.get(loaderName);
-//				try {
-//					if (loader != null) {
-//						Class<?> c = loader.loadClass(name);
-//						//System.out.println("load from "+loaderName+": "+name);
-//						return c;
-//					}
-//				}
-//				catch (Exception e) {
-//					//System.out.println("can't load from "+loaderName+": "+name+" "+e);
-//					if (e instanceof NullPointerException) {
-//						e.printStackTrace();
-//					}
-//				}
-//			}
-//		}
-		
+		//		// try using the class package name
+		//		if (name.startsWith("org.txm.")) {
+		//			int idx = name.indexOf(".rcp.");
+		//			if (idx > 0) {
+		//				String loaderName = name.substring(0, idx+4);
+		//				EquinoxClassLoader loader = loaders.get(loaderName);
+		//				try {
+		//					if (loader != null) {
+		//						Class<?> c = loader.loadClass(name);
+		//						//System.out.println("load from "+loaderName+": "+name);
+		//						return c;
+		//					}
+		//				}
+		//				catch (Exception e) {
+		//					//System.out.println("can't load from "+loaderName+": "+name+" "+e);
+		//					if (e instanceof NullPointerException) {
+		//						e.printStackTrace();
+		//					}
+		//				}
+		//			}
+		//			idx = name.indexOf(".core.");
+		//			if (idx > 0) {
+		//				String loaderName =name.substring(0, idx)+".rcp";
+		//				EquinoxClassLoader loader = loaders.get(name.substring(0, idx)+".rcp");
+		//				try {
+		//					if (loader != null) {
+		//						Class<?> c = loader.loadClass(name);
+		//						//System.out.println("load from "+loaderName+": "+name);
+		//						return c;
+		//					}
+		//				}
+		//				catch (Exception e) {
+		//					//System.out.println("can't load from "+loaderName+": "+name+" "+e);
+		//					if (e instanceof NullPointerException) {
+		//						e.printStackTrace();
+		//					}
+		//				}
+		//				
+		//				loaderName = name.substring(0, idx+5);
+		//				loader = loaders.get(loaderName);
+		//				try {
+		//					if (loader != null) {
+		//						Class<?> c = loader.loadClass(name);
+		//						//System.out.println("load from "+loaderName+": "+name);
+		//						return c;
+		//					}
+		//				}
+		//				catch (Exception e) {
+		//					//System.out.println("can't load from "+loaderName+": "+name+" "+e);
+		//					if (e instanceof NullPointerException) {
+		//						e.printStackTrace();
+		//					}
+		//				}
+		//			}
+		//		}
+
 		// last resort test all loaders
 		for (EquinoxClassLoader cl : loaders.values()) {
-			
+
 			// FIXME: SJ: tests to speed up this very long process
 			// if(cl instanceof EquinoxClassLoader) {
 			// EquinoxClassLoader ecl = (EquinoxClassLoader) cl;
@@ -111,7 +158,7 @@
 			// }
 			// }
 			//
-			
+
 			try {
 				return cl.loadClass(name);
 			}
Index: TXM/trunk/bundles/org.txm.groovy.core/plugin.xml
===================================================================
--- TXM/trunk/bundles/org.txm.groovy.core/plugin.xml	(revision 3669)
+++ TXM/trunk/bundles/org.txm.groovy.core/plugin.xml	(revision 3670)
@@ -23,5 +23,11 @@
             name="Groovy">
       </ScriptEngine>
    </extension>
+   <extension
+         point="org.eclipse.core.runtime.preferences">
+      <initializer
+            class="org.txm.groovy.core.GroovyPreferences">
+      </initializer>
+   </extension>
 
 </plugin>
Index: TXM/trunk/bundles/org.txm.groovy.core/META-INF/MANIFEST.MF
===================================================================
--- TXM/trunk/bundles/org.txm.groovy.core/META-INF/MANIFEST.MF	(revision 3669)
+++ TXM/trunk/bundles/org.txm.groovy.core/META-INF/MANIFEST.MF	(revision 3670)
@@ -1,5 +1,6 @@
 Manifest-Version: 1.0
-Export-Package: org.txm.groovy.core
+Export-Package: org.txm.groovy.core,
+ org.txm.groovy.core.messages
 Bundle-SymbolicName: org.txm.groovy.core;singleton:=true
 Bundle-Version: 1.0.0.qualifier
 Bundle-Name: Macro
