diff --git a/src/main/java/plugins/tprovoost/scripteditor/scriptinghandlers/ScriptEngineManager.java b/src/main/java/plugins/tprovoost/scripteditor/scriptinghandlers/ScriptEngineManager.java
index b36bbd63d9151a3d0922fb93e3ee9c732ac0fab7..069e56360ef08f9c757293981ee005e405418263 100644
--- a/src/main/java/plugins/tprovoost/scripteditor/scriptinghandlers/ScriptEngineManager.java
+++ b/src/main/java/plugins/tprovoost/scripteditor/scriptinghandlers/ScriptEngineManager.java
@@ -1,15 +1,17 @@
 package plugins.tprovoost.scripteditor.scriptinghandlers;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.TreeSet;
-import java.util.function.Function;
-import java.util.stream.Stream;
 
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
 import javax.script.ScriptEngineFactory;
+import javax.script.SimpleBindings;
 
 import icy.plugin.PluginDescriptor;
 import icy.plugin.PluginLauncher;
@@ -18,20 +20,20 @@ import icy.plugin.interface_.PluginScriptFactory;
 
 public class ScriptEngineManager
 {
-    private static final Comparator<ScriptEngineFactory> COMPARATOR = Comparator.comparing(ScriptEngineFactory::getEngineName,
-            Comparator.nullsLast(Comparator.naturalOrder()));
-
     /** Set of script engine factories discovered. */
-    private final TreeSet<ScriptEngineFactory> engineSpis = new TreeSet<>(COMPARATOR);
+    private HashSet<ScriptEngineFactory> engineSpis = new HashSet<>();
 
     /** Map of engine name to script engine factory. */
-    private final HashMap<String, ScriptEngineFactory> nameAssociations = new HashMap<>();
+    private HashMap<String, ScriptEngineFactory> nameAssociations = new HashMap<>();
 
     /** Map of script file extension to script engine factory. */
-    private final HashMap<String, ScriptEngineFactory> extensionAssociations = new HashMap<>();
+    private HashMap<String, ScriptEngineFactory> extensionAssociations = new HashMap<>();
+
+    /** Map of script script MIME type to script engine factory. */
+    private HashMap<String, ScriptEngineFactory> mimeTypeAssociations = new HashMap<>();
 
-    /** Map of script MIME type to script engine factory. */
-    private final HashMap<String, ScriptEngineFactory> mimeTypeAssociations = new HashMap<>();
+    /** Global bindings associated with script engines created by this manager. */
+    private Bindings globalScope = new SimpleBindings();
 
     public ScriptEngineManager()
     {
@@ -54,6 +56,68 @@ public class ScriptEngineManager
         }
     }
 
+    /**
+     * <code>setBindings</code> stores the specified <code>Bindings</code>
+     * in the <code>globalScope</code> field. ScriptEngineManager sets this
+     * <code>Bindings</code> as global bindings for <code>ScriptEngine</code>
+     * objects created by it.
+     *
+     * @param bindings
+     *        The specified <code>Bindings</code>
+     * @throws IllegalArgumentException
+     *         if bindings is null.
+     */
+    public void setBindings(Bindings bindings)
+    {
+        if (bindings == null)
+        {
+            throw new IllegalArgumentException("Global scope cannot be null.");
+        }
+
+        globalScope = bindings;
+    }
+
+    /**
+     * <code>getBindings</code> returns the value of the <code>globalScope</code> field.
+     * ScriptEngineManager sets this <code>Bindings</code> as global bindings for
+     * <code>ScriptEngine</code> objects created by it.
+     *
+     * @return The globalScope field.
+     */
+    public Bindings getBindings()
+    {
+        return globalScope;
+    }
+
+    /**
+     * Sets the specified key/value pair in the Global Scope.
+     * 
+     * @param key
+     *        Key to set
+     * @param value
+     *        Value to set.
+     * @throws NullPointerException
+     *         if key is null.
+     * @throws IllegalArgumentException
+     *         if key is empty string.
+     */
+    public void put(String key, Object value)
+    {
+        globalScope.put(key, value);
+    }
+
+    /**
+     * Gets the value for the specified key in the Global Scope
+     * 
+     * @param key
+     *        The key whose value is to be returned.
+     * @return The value for the specified key.
+     */
+    public Object get(String key)
+    {
+        return globalScope.get(key);
+    }
+
     /**
      * Looks up and creates a <code>ScriptEngine</code> for a given name.
      * The algorithm first searches for a <code>ScriptEngineFactory</code> that has been
@@ -77,7 +141,59 @@ public class ScriptEngineManager
      */
     public javax.script.ScriptEngine getEngineByName(String shortName)
     {
-        return getEngineBy(shortName, nameAssociations, ScriptEngineFactory::getNames);
+        if (shortName == null)
+            throw new NullPointerException();
+        // look for registered name first
+        Object obj;
+        if (null != (obj = nameAssociations.get(shortName)))
+        {
+            ScriptEngineFactory spi = (ScriptEngineFactory) obj;
+            try
+            {
+                ScriptEngine engine = spi.getScriptEngine();
+                engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
+                return engine;
+            }
+            catch (Exception exp)
+            {
+                debugPrint(exp);
+            }
+        }
+
+        for (ScriptEngineFactory spi : engineSpis)
+        {
+            List<String> names = null;
+            try
+            {
+                names = spi.getNames();
+            }
+            catch (Exception exp)
+            {
+                debugPrint(exp);
+            }
+
+            if (names != null)
+            {
+                for (String name : names)
+                {
+                    if (shortName.equals(name))
+                    {
+                        try
+                        {
+                            ScriptEngine engine = spi.getScriptEngine();
+                            engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
+                            return engine;
+                        }
+                        catch (Exception exp)
+                        {
+                            debugPrint(exp);
+                        }
+                    }
+                }
+            }
+        }
+
+        return null;
     }
 
     /**
@@ -93,9 +209,58 @@ public class ScriptEngineManager
      * @throws NullPointerException
      *         if extension is null.
      */
-    public javax.script.ScriptEngine getEngineByExtension(String extension)
+    public ScriptEngine getEngineByExtension(String extension)
     {
-        return getEngineBy(extension, extensionAssociations, ScriptEngineFactory::getExtensions);
+        if (extension == null)
+            throw new NullPointerException();
+        // look for registered extension first
+        Object obj;
+        if (null != (obj = extensionAssociations.get(extension)))
+        {
+            ScriptEngineFactory spi = (ScriptEngineFactory) obj;
+            try
+            {
+                ScriptEngine engine = spi.getScriptEngine();
+                engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
+                return engine;
+            }
+            catch (Exception exp)
+            {
+                debugPrint(exp);
+            }
+        }
+
+        for (ScriptEngineFactory spi : engineSpis)
+        {
+            List<String> exts = null;
+            try
+            {
+                exts = spi.getExtensions();
+            }
+            catch (Exception exp)
+            {
+                debugPrint(exp);
+            }
+            if (exts == null)
+                continue;
+            for (String ext : exts)
+            {
+                if (extension.equals(ext))
+                {
+                    try
+                    {
+                        ScriptEngine engine = spi.getScriptEngine();
+                        engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
+                        return engine;
+                    }
+                    catch (Exception exp)
+                    {
+                        debugPrint(exp);
+                    }
+                }
+            }
+        }
+        return null;
     }
 
     /**
@@ -111,48 +276,58 @@ public class ScriptEngineManager
      * @throws NullPointerException
      *         if mimeType is null.
      */
-    public javax.script.ScriptEngine getEngineByMimeType(String mimeType)
+    public ScriptEngine getEngineByMimeType(String mimeType)
     {
-        return getEngineBy(mimeType, mimeTypeAssociations, ScriptEngineFactory::getMimeTypes);
-    }
-
-    private javax.script.ScriptEngine getEngineBy(String selector, Map<String, ScriptEngineFactory> associations,
-            Function<ScriptEngineFactory, List<String>> valuesFn)
-    {
-        Objects.requireNonNull(selector);
-        Stream<ScriptEngineFactory> spis = Stream.concat(
-                // look for registered types first
-                Stream.ofNullable(associations.get(selector)),
-
-                engineSpis.stream().filter(spi -> {
-                    try
-                    {
-                        List<String> matches = valuesFn.apply(spi);
-                        return matches != null && matches.contains(selector);
-                    }
-                    catch (Exception exp)
-                    {
-                        debugPrint(exp);
-                        return false;
-                    }
-                }));
-        return spis.map(spi -> {
+        if (mimeType == null)
+            throw new NullPointerException();
+        // look for registered types first
+        Object obj;
+        if (null != (obj = mimeTypeAssociations.get(mimeType)))
+        {
+            ScriptEngineFactory spi = (ScriptEngineFactory) obj;
             try
             {
-                javax.script.ScriptEngine engine = spi.getScriptEngine();
+                ScriptEngine engine = spi.getScriptEngine();
+                engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
                 return engine;
             }
             catch (Exception exp)
             {
                 debugPrint(exp);
-                return null;
             }
-        }).filter(Objects::nonNull).findFirst().orElse(null);
-    }
+        }
 
-    private static void debugPrint(Throwable exp)
-    {
-        exp.printStackTrace();
+        for (ScriptEngineFactory spi : engineSpis)
+        {
+            List<String> types = null;
+            try
+            {
+                types = spi.getMimeTypes();
+            }
+            catch (Exception exp)
+            {
+                debugPrint(exp);
+            }
+            if (types == null)
+                continue;
+            for (String type : types)
+            {
+                if (mimeType.equals(type))
+                {
+                    try
+                    {
+                        ScriptEngine engine = spi.getScriptEngine();
+                        engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
+                        return engine;
+                    }
+                    catch (Exception exp)
+                    {
+                        debugPrint(exp);
+                    }
+                }
+            }
+        }
+        return null;
     }
 
     /**
@@ -163,6 +338,72 @@ public class ScriptEngineManager
      */
     public List<ScriptEngineFactory> getEngineFactories()
     {
-        return List.copyOf(engineSpis);
+        List<ScriptEngineFactory> res = new ArrayList<ScriptEngineFactory>(engineSpis.size());
+        for (ScriptEngineFactory spi : engineSpis)
+        {
+            res.add(spi);
+        }
+        return Collections.unmodifiableList(res);
+    }
+
+    /**
+     * Registers a <code>ScriptEngineFactory</code> to handle a language
+     * name. Overrides any such association found using the Discovery mechanism.
+     * 
+     * @param name
+     *        The name to be associated with the <code>ScriptEngineFactory</code>.
+     * @param factory
+     *        The class to associate with the given name.
+     * @throws NullPointerException
+     *         if any of the parameters is null.
+     */
+    public void registerEngineName(String name, ScriptEngineFactory factory)
+    {
+        if (name == null || factory == null)
+            throw new NullPointerException();
+        nameAssociations.put(name, factory);
+    }
+
+    /**
+     * Registers a <code>ScriptEngineFactory</code> to handle a mime type.
+     * Overrides any such association found using the Discovery mechanism.
+     *
+     * @param type
+     *        The mime type to be associated with the
+     *        <code>ScriptEngineFactory</code>.
+     * @param factory
+     *        The class to associate with the given mime type.
+     * @throws NullPointerException
+     *         if any of the parameters is null.
+     */
+    public void registerEngineMimeType(String type, ScriptEngineFactory factory)
+    {
+        if (type == null || factory == null)
+            throw new NullPointerException();
+        mimeTypeAssociations.put(type, factory);
+    }
+
+    /**
+     * Registers a <code>ScriptEngineFactory</code> to handle an extension.
+     * Overrides any such association found using the Discovery mechanism.
+     *
+     * @param extension
+     *        The extension type to be associated with the
+     *        <code>ScriptEngineFactory</code>.
+     * @param factory
+     *        The class to associate with the given extension.
+     * @throws NullPointerException
+     *         if any of the parameters is null.
+     */
+    public void registerEngineExtension(String extension, ScriptEngineFactory factory)
+    {
+        if (extension == null || factory == null)
+            throw new NullPointerException();
+        extensionAssociations.put(extension, factory);
+    }
+
+    private static void debugPrint(Throwable exp)
+    {
+        exp.printStackTrace();
     }
 }