diff a/build.gradle b/build.gradle
--- a/build.gradle
+++ b/build.gradle
@@ -3570,10 +3570,11 @@
         testapp3
         testapp4
         testapp5
         testapp6
         testscriptapp1
+        testscriptapp2
     }
 
     def nonModSrcSets = [
         sourceSets.test,
         sourceSets.testapp1
@@ -3583,11 +3584,12 @@
         sourceSets.testapp2,
         sourceSets.testapp3,
         sourceSets.testapp4,
         sourceSets.testapp5,
         sourceSets.testapp6,
-        sourceSets.testscriptapp1
+        sourceSets.testscriptapp1,
+        sourceSets.testscriptapp2
     ]
 
     project.ext.buildModule = false
     project.ext.moduleRuntime = false
     project.ext.moduleName = "systemTests"
@@ -3683,11 +3685,11 @@
         dependsOn(createTestapp1Jar1)
         dependsOn(createTestapp1Jar2)
     }
     test.dependsOn(createTestApps);
 
-    def modtestapps = [ "testapp2", "testapp3", "testapp4", "testapp5", "testapp6", "testscriptapp1" ]
+    def modtestapps = [ "testapp2", "testapp3", "testapp4", "testapp5", "testapp6", "testscriptapp1", "testscriptapp2" ]
     modtestapps.each { testapp ->
         def testappCapital = testapp.capitalize()
         def copyTestAppTask = task("copy${testappCapital}", type: Copy) {
             from project.sourceSets."${testapp}".java.outputDir
             from project.sourceSets."${testapp}".output.resourcesDir
diff a/modules/javafx.fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html b/modules/javafx.fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html
--- a/modules/javafx.fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html
+++ b/modules/javafx.fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html
@@ -27,11 +27,11 @@
  */
 -->
 
 <html lang="en">
 <head>
-<link href="fxml.css" type="text/css" rel="stylesheet"/>    
+<link href="fxml.css" type="text/css" rel="stylesheet"/>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <title>Introduction to FXML | JavaFX @FXVERSION@</title>
 <meta name="description" content="The document introduces FXML, an XML-based declarative markup language for defining user interfaces in JavaFX @FXVERSION@ applications."/>
 <meta name="keywords" content="JavaFX, FXML, JavaFX GUI development, web development, Java application development, GUI applications, rich internet applications, RIA, expressive content"/>
 </head>
@@ -595,17 +595,17 @@
  <tr><th scope="row">null</th><td>A constant representing the null value</td></tr>
  <tr><th scope="row">50.0<br />3e5<br />42</th><td>A numerical constant</td></tr>
  <tr><th scope="row">- <br/>(unary operator)</th><td>Unary minus operator, applied on a number</td>
  <tr><th scope="row">! <br/>(unary operator)</th><td>Unary negation of a boolean</td></tr>
  <tr><th scope="row">+ - <br />
- 			* /
- 			%</th> <td>Numerical binary operators</td></tr>
+                        * /
+                        %</th> <td>Numerical binary operators</td></tr>
  <tr><th scope="row">&amp;&amp; ||</th><td>Boolean binary operators</td></tr>
  <tr><th scope="row">&gt; &gt;= <br />
- 		   &lt; &lt;= <br />
- 		   == !=</th>
- 		   <td>Binary operators of comparison.<br/> Both arguments must be of type Comparable</td></tr>
+                   &lt; &lt;= <br />
+                   == !=</th>
+                   <td>Binary operators of comparison.<br/> Both arguments must be of type Comparable</td></tr>
 </table>
 
 <h3><a id="static_property_attributes">Static Properties</a></h3>
 <p>Attributes representing static properties are handled similarly to static property elements and use a similar syntax. For example, the earlier <span class="code">GridPane</span> markup shown earlier to demonstrate static property elements could be rewritten as follows:</p>
 
@@ -639,10 +639,12 @@
 &lt;/VBox&gt;
 </pre>
 
 <p>Note the use of the language processing instruction at the beginning of the code snippet. This PI tells the FXML loader which scripting language should be used to execute the event handler. A page language must be specified whenever inline script is used in an FXML document, and can only be specified once per document. However, this does not apply to external scripts, which may be implemented using any number of supported scripting languages. Scripting is discussed in more detail in the next section.</p>
 
+<p>Note: to turn off automatic compilation of script code place the processing instruction <span class="code">&lt;?compile false?&gt;</span> before the element that contains the script. To turn on compilation of script code again use the processing instruction <span class="code">&lt;?compile true?&gt;</span> (or short: <span class="code">&lt;?compile?&gt;</span>). The compile processing instruction can be used repeatedly to turn compilation of script code off and on.</p>
+
 <h4><a id="controller_method_event_handlers">Controller Method Event Handlers</a></h4>
 <p>A controller method event handler is a method defined by a document's "controller". A controller is an object that is associated with the deserialized contents of an FXML document and is responsible for coordinating the behaviors of the objects (often user interface elements) defined by the document.</p>
 
 <p>A controller method event handler is specified by a leading hash symbol followed by the name of the handler method. For example:</p>
 
@@ -698,19 +700,19 @@
     &lt;/children&gt;
 &lt;/VBox&gt;
 </pre>
 
 <p> With the controller that contains a field like this </p>
-    
+
 <pre class="code">
 public class MyController {
-    
+
     &#64;FXML
     public EventHandler&lt;ActionEvent&gt; onActionHandler = new EventHandler&lt;&gt;() { ... }
 
     ...
-}  
+}
 </pre>
 
 <p> Note that other kinds of expressions, like <a href="#expression_binding">binding expressions</a>
     are not supported in this context. </p>
 
@@ -761,18 +763,22 @@
 
 <pre class="code">
 &lt;VBox fx:controller="com.foo.MyController"
     xmlns:fx="http://javafx.com/fxml" onParentChange="#handleParentChange"/&gt;
 </pre>
-    
+
 <p>Note that collections and properties do not currently support scripting handlers.</p>
 
 <h2><a id="scripting">Scripting</a></h2>
 <p>
 The <span class="code">&lt;fx:script&gt;</span> tag allows a caller to import scripting code into or embed script within a FXML file. Any JVM scripting language can be used, including JavaScript, Groovy, and Clojure, among others. Script code is often used to define event handlers directly in markup or in an associated source file, since event handlers can often be written more concisely in more loosely-typed scripting languages than they can in a statically-typed language such as Java.</p>
 
-<p>For example, the following markup defines a function called <span class="code">handleButtonAction()</span> that is called by the action handler attached to the <span class="code">Button</span> element:</p>
+<p>Scripts are compiled by default, when they are first loaded, if the <span class="code">ScriptEngine</span> implements the <span class="code">javax.script.Compilable</span> interface. If compilation fails, the <span class="code">FXMLLoader</span> will fall back to interpreted mode.</p>
+
+<p>Note: to turn off automatic compilation of script code place the processing instruction <span class="code">&lt;?compile false?&gt;</span> before the script element. To turn on compilation of script code again use the processing instruction <span class="code">&lt;?compile true?&gt;</span> (or short: <span class="code">&lt;?compile?&gt;</span>). The compile processing instruction can be used repeatedly to turn compilation of script code off and on.</p>
+
+<p>The following example markup defines a function called <span class="code">handleButtonAction()</span> that is called by the action handler attached to the <span class="code">Button</span> element:</p>
 
 <pre class="code">
 &lt;?language javascript?&gt;
 
 &lt;?import javafx.scene.control.*?&gt;
@@ -796,10 +802,12 @@
 
 <p>Script code may also be defined in external files. The previous example could be split into an FXML file and a JavaScript source file with no difference in functionality:</p>
 
 <div class="caption">example.fxml</div>
 <pre class="code">
+&lt;?language javascript?&gt;
+
 &lt;?import javafx.scene.control.*?&gt;
 &lt;?import javafx.scene.layout.*?&gt;
 
 &lt;VBox xmlns:fx="http://javafx.com/fxml"&gt;
     &lt;fx:script source="example.js" charset="cp1252"/&gt;
@@ -831,21 +839,20 @@
 ...
 
 &lt;Label text="$myText"/&gt;
 </pre>
 
-
-<p><strong>Warning:</strong>As of JavaFX 8, <span class="code">importClass()</span> javascript function is no longer supported. You have to use fully qualified names as in the example above or load a nashorn compatibility script.</p>
+<p><strong>Warning:</strong> As of JavaFX 8, <span class="code">importClass()</span> javascript function is no longer supported. You have to use fully qualified names as in the example above or load a nashorn compatibility script.</p>
 
 <pre class="code">
 load("nashorn:mozilla_compat.js");
 importClass(java.lang.System);
 
 function handleButtonAction(event) {
    System.out.println('You clicked me!');
 }
-</pre> 
+</pre>
 
 <h2><a id="controllers">Controllers</a></h2>
 <p>While it can be convenient to write simple event handlers in script, either inline or defined in external files, it is often preferable to define more complex application logic in a compiled, strongly-typed language such as Java. As discussed earlier, the <span class="code">fx:controller</span> attribute allows a caller to associate a "controller" class with an FXML document. A controller is a compiled class that implements the "code behind" the object hierarchy defined by the document.</p>
 
 <p>As shown earlier, controllers are often used to implement event handlers for user interface elements defined in markup:</p>
diff a/modules/javafx.fxml/src/main/java/javafx/fxml/FXMLLoader.java b/modules/javafx.fxml/src/main/java/javafx/fxml/FXMLLoader.java
--- a/modules/javafx.fxml/src/main/java/javafx/fxml/FXMLLoader.java
+++ b/modules/javafx.fxml/src/main/java/javafx/fxml/FXMLLoader.java
@@ -61,10 +61,12 @@
 import javafx.util.Builder;
 import javafx.util.BuilderFactory;
 import javafx.util.Callback;
 
 import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
 import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
 import javax.script.SimpleBindings;
@@ -1556,42 +1558,94 @@
                         }
 
                         location = new URL(FXMLLoader.this.location, source);
                     }
                     Bindings engineBindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
-                    engineBindings.put(engine.FILENAME, location.getPath());
+                    String filename = location.getPath();
+                    engineBindings.put(engine.FILENAME, filename);
 
                     InputStreamReader scriptReader = null;
+                    String script=null;
                     try {
                         scriptReader = new InputStreamReader(location.openStream(), charset);
-                        engine.eval(scriptReader);
-                    } catch(ScriptException exception) {
-                        exception.printStackTrace();
+                        StringBuilder sb = new StringBuilder();
+                        final int bufSize = 4096;
+                        char[] charBuffer = new char[bufSize];
+                        int n;
+                        do {
+                            n = scriptReader.read(charBuffer,0,bufSize);
+                            if (n > 0) {
+                                sb.append(new String(charBuffer,0,n));
+                          }
+                        } while (n > -1);
+                        script = sb.toString();
+                    } catch (IOException exception) {
+                        throw constructLoadException(exception);
                     } finally {
                         if (scriptReader != null) {
                             scriptReader.close();
                         }
                     }
-                } catch (IOException exception) {
-                    throw constructLoadException(exception);
+                    try {
+                        if (engine instanceof Compilable && compileScript) {
+                            CompiledScript compiledScript = null;
+                            try {
+                                compiledScript=((Compilable) engine).compile(script);
+                            } catch (ScriptException compileExc) {
+                                Logging.getJavaFXLogger().warning(filename + ": compiling caused \"" + compileExc +
+                                    "\", falling back to evaluating script in uncompiled mode");
+                            }
+                            if (compiledScript != null) {
+                                compiledScript.eval();
+                            } else { // fallback to uncompiled mode
+                                engine.eval(script);
+                            }
+                        } else {
+                            engine.eval(script);
+                        }
+                    } catch (ScriptException exception) {
+                        System.err.println(filename + ": caused ScriptException");
+                        exception.printStackTrace();
+                    }
+                }
+                catch (IOException exception) {
+                  throw constructLoadException(exception);
                 }
             }
         }
 
         @Override
         public void processEndElement() throws IOException {
             super.processEndElement();
 
             if (value != null && !staticLoad) {
                 // Evaluate the script
+                String filename = null;
                 try {
                     Bindings engineBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
-                    engineBindings.put(scriptEngine.FILENAME, location.getPath() + "-script_starting_at_line_"
-                                       + (getLineNumber() - (int) ((String) value).codePoints().filter(c -> c == '\n').count()));
-                    scriptEngine.eval((String)value);
+                    String script = (String) value;
+                    filename = location.getPath() + "-script_starting_at_line_"
+                                       + (getLineNumber() - (int) script.codePoints().filter(c -> c == '\n').count());
+                    engineBindings.put(scriptEngine.FILENAME, filename);
+                    if (scriptEngine instanceof Compilable && compileScript) {
+                        CompiledScript compiledScript = null;
+                        try {
+                            compiledScript=((Compilable) scriptEngine).compile(script);
+                        } catch (ScriptException compileExc) {
+                            Logging.getJavaFXLogger().warning(filename + ": compiling caused \"" + compileExc +
+                                "\", falling back to evaluating script in uncompiled mode");
+                        }
+                        if (compiledScript != null) {
+                            compiledScript.eval();
+                        } else { // fallback to uncompiled mode
+                            scriptEngine.eval(script);
+                        }
+                    } else {
+                        scriptEngine.eval(script);
+                    }
                 } catch (ScriptException exception) {
-                    System.err.println(exception.getMessage());
+                    System.err.println(filename + ": caused ScriptException\n" + exception.getMessage());
                 }
             }
         }
 
         @Override
@@ -1679,15 +1733,28 @@
     // Event handler implemented in script code
     private static class ScriptEventHandler implements EventHandler<Event> {
         public final String script;
         public final ScriptEngine scriptEngine;
         public final String filename;
+        public CompiledScript compiledScript;
+        public boolean isCompiled=false;
 
         public ScriptEventHandler(String script, ScriptEngine scriptEngine, String filename) {
             this.script = script;
             this.scriptEngine = scriptEngine;
             this.filename = filename;
+            if (scriptEngine instanceof Compilable  && compileScript) {
+                try {
+                    // supply the filename to the scriptEngine engine scope Bindings in case it is needed for compilation
+                    scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).put(scriptEngine.FILENAME, filename);
+                    this.compiledScript = ((Compilable) scriptEngine).compile(script);
+                    this.isCompiled = true;
+                } catch (ScriptException compileExc) {
+                    Logging.getJavaFXLogger().warning(filename + ": compiling caused \"" + compileExc +
+                        "\", falling back to evaluating script in uncompiled mode");
+                }
+            }
         }
 
         @Override
         public void handle(Event event) {
             // Don't pollute the page namespace with values defined in the script
@@ -1697,13 +1764,17 @@
             localBindings.put(EVENT_KEY, event);
             localBindings.put(scriptEngine.ARGV, new Object[]{event});
             localBindings.put(scriptEngine.FILENAME, filename);
             // Execute the script
             try {
-                scriptEngine.eval(script, localBindings);
-            } catch (ScriptException exception){
-                throw new RuntimeException(exception);
+                if (isCompiled) {
+                   compiledScript.eval(localBindings);
+                } else {
+                   scriptEngine.eval(script, localBindings);
+                }
+            } catch (ScriptException exception) {
+                throw new RuntimeException(filename + ": caused ScriptException", exception);
             }
         }
     }
 
     // Observable list change listener
@@ -1817,10 +1888,11 @@
 
     private XMLStreamReader xmlStreamReader = null;
     private Element current = null;
 
     private ScriptEngine scriptEngine = null;
+    private static boolean compileScript = true;
 
     private List<String> packages = new LinkedList<String>();
     private Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
 
     private ScriptEngineManager scriptEngineManager = null;
@@ -1843,10 +1915,16 @@
     /**
      * The tag name of import processing instruction.
      */
     public static final String IMPORT_PROCESSING_INSTRUCTION = "import";
 
+    /**
+     * The tag name of the compile processing instruction.
+     * @since 15
+     */
+    public static final String COMPILE_PROCESSING_INSTRUCTION = "compile";
+
     /**
      * Prefix of 'fx' namespace.
      */
     public static final String FX_NAMESPACE_PREFIX = "fx";
     /**
@@ -2676,10 +2754,14 @@
 
         if (piTarget.equals(LANGUAGE_PROCESSING_INSTRUCTION)) {
             processLanguage();
         } else if (piTarget.equals(IMPORT_PROCESSING_INSTRUCTION)) {
             processImport();
+        } else if (piTarget.equals(COMPILE_PROCESSING_INSTRUCTION)) {
+            String strCompile=xmlStreamReader.getPIData().trim();
+            // if PIData() is empty string then default to true, otherwise use Boolean.parseBoolean(string) to determine the boolean value
+            compileScript = (strCompile.length()==0 ? true : Boolean.parseBoolean(strCompile));
         }
     }
 
     private void processLanguage() throws LoadException {
         if (scriptEngine != null) {
diff a/tests/system/src/test/java/test/launchertest/ModuleLauncherTest.java b/tests/system/src/test/java/test/launchertest/ModuleLauncherTest.java
--- a/tests/system/src/test/java/test/launchertest/ModuleLauncherTest.java
+++ b/tests/system/src/test/java/test/launchertest/ModuleLauncherTest.java
@@ -42,10 +42,11 @@
     private static final String modulePath3 = System.getProperty("launchertest.testapp3.module.path");
     private static final String modulePath4 = System.getProperty("launchertest.testapp4.module.path");
     private static final String modulePath5 = System.getProperty("launchertest.testapp5.module.path");
     private static final String modulePath6 = System.getProperty("launchertest.testapp6.module.path");
     private static final String modulePathScript1 = System.getProperty("launchertest.testscriptapp1.module.path");
+    private static final String modulePathScript2 = System.getProperty("launchertest.testscriptapp2.module.path");
 
     private static final String moduleName = "mymod";
 
     private final int testExitCode = ERROR_NONE;
 
@@ -279,6 +280,31 @@
     @Test (timeout = 15000)
     public void testFXMLScriptDeployment() throws Exception {
         doTestLaunchModule(modulePathScript1, "myapp1.FXMLScriptDeployment");
     }
 
+    @Test (timeout = 15000)
+    public void testFXMLScriptDeployment2Compile_On() throws Exception {
+        doTestLaunchModule(modulePathScript2, "myapp2.FXMLScriptDeployment2Compile_On");
+    }
+
+    @Test (timeout = 15000)
+    public void testFXMLScriptDeployment2Compile_Off() throws Exception {
+        doTestLaunchModule(modulePathScript2, "myapp2.FXMLScriptDeployment2Compile_Off");
+    }
+
+    @Test (timeout = 15000)
+    public void testFXMLScriptDeployment2Compile_On_Off() throws Exception {
+        doTestLaunchModule(modulePathScript2, "myapp2.FXMLScriptDeployment2Compile_On_Off");
+    }
+
+    @Test (timeout = 15000)
+    public void testFXMLScriptDeployment2Compile_Off_On() throws Exception {
+        doTestLaunchModule(modulePathScript2, "myapp2.FXMLScriptDeployment2Compile_Off_On");
+    }
+    @Test (timeout = 15000)
+    public void testFXMLScriptDeployment2Compile_Fail_Compilation() throws Exception {
+        doTestLaunchModule(modulePathScript2, "myapp2.FXMLScriptDeployment2Compile_Fail_Compilation");
+    }
 }
+
+
diff a/tests/system/src/testscriptapp1/resources/mymod/META-INF/services/javax.script.ScriptEngineFactory b/tests/system/src/testscriptapp1/resources/mymod/META-INF/services/javax.script.ScriptEngineFactory
--- a/tests/system/src/testscriptapp1/resources/mymod/META-INF/services/javax.script.ScriptEngineFactory
+++ b/tests/system/src/testscriptapp1/resources/mymod/META-INF/services/javax.script.ScriptEngineFactory
@@ -1,2 +1,1 @@
 pseudoScriptEngine.RgfPseudoScriptEngineFactory
-
diff a/tests/system/src/testscriptapp2/java/mymod/module-info.java b/tests/system/src/testscriptapp2/java/mymod/module-info.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/module-info.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module mymod {
+    requires javafx.controls;
+    requires javafx.fxml;
+
+    requires java.scripting;
+    provides javax.script.ScriptEngineFactory with pseudoScriptEngineCompilable.RgfPseudoScriptEngineCompilableFactory;
+    exports pseudoScriptEngineCompilable;
+    exports myapp2;
+}
diff a/tests/system/src/testscriptapp2/java/mymod/myapp2/Constants.java b/tests/system/src/testscriptapp2/java/mymod/myapp2/Constants.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/myapp2/Constants.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myapp2;     // verbatim from myapp6
+
+public class Constants {
+
+    public static final int SHOWTIME = 2500;
+
+    // NOTE: these constants must match those in test.launchertest.Constants
+    public static final int ERROR_NONE = 2;
+    public static final int ERROR_UNEXPECTED_EXCEPTION = 4;
+
+    public static final int ERROR_ASSERTION_FAILURE = 28;
+}
diff a/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Fail_Compilation.java b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Fail_Compilation.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Fail_Compilation.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myapp2;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+
+import static myapp2.Constants.*;
+import pseudoScriptEngineCompilable.InvocationInfos;
+import pseudoScriptEngineCompilable.RgfPseudoScriptEngineCompilable;
+
+/**
+ * Modular test application for testing FXML.
+ * This is launched by ModuleLauncherTest.
+ */
+public class FXMLScriptDeployment2Compile_Fail_Compilation extends Application {
+
+    static boolean bDebug = false; // true; // display invocation list
+
+    /** Runs the application and invokes the tests.
+     *  @param args the command line arguments, if any given the RgfPseudoScriptEngine invocation logs get displayed
+     *              which are used in the asserCorrectInvocations() method
+     */
+    public static void main(String[] args) {
+        try {
+            // any argument will cause the bDebug flag to be set to true
+            if (args.length > 0) {
+               bDebug = true;
+            }
+            new FXMLScriptDeployment2Compile_Fail_Compilation().launch();
+            // for debugging, allows to study invocation logs in detail
+            if (bDebug) { dumpEvalInformation(); }
+            assertCorrectInvocations();
+        } catch (AssertionError ex) {
+            System.err.println("ASSERTION ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_ASSERTION_FAILURE);
+        } catch (Error | Exception ex) {
+            System.err.println("ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+        System.exit(ERROR_NONE);    // not in stop() method as we need to run the assertions first
+    }
+
+    @Override
+    public void start(Stage mainStage) {
+        URL fxmlUrl = null;
+        Parent rootNode = null;
+        Scene scene = null;
+        Button btn = null;
+        try {
+             fxmlUrl = Util.getURL(FXMLScriptDeployment2Compile_Fail_Compilation.class, "demo_03_fail_compile");
+             rootNode = FXMLLoader.load(fxmlUrl);
+             scene = new Scene(rootNode);
+             btn = (Button) scene.lookup("#idButton");
+        }
+        catch (Exception ioe) {
+            ioe.printStackTrace();
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+            // fire three events on the button
+        btn.fire();
+        btn.fireEvent(new ActionEvent());
+        btn.fireEvent(new MouseEvent(MouseEvent.MOUSE_CLICKED,
+                                       0,       // double x,
+                                       0,       // double y,
+                                       0,       // double screenX,
+                                       0,       // double screenY,
+                                       MouseButton.PRIMARY,         // MouseButton button,
+                                       0,       // int clickCount,
+                                       false,   // boolean shiftDown,
+                                       false,   // boolean controlDown,
+                                       false,   // boolean altDown,
+                                       false,   // boolean metaDown,
+                                       true,    // boolean primaryButtonDown,
+                                       false,   // boolean middleButtonDown,
+                                       false,   // boolean secondaryButtonDown,
+                                       false,   // boolean synthesized,
+                                       false,   // boolean popupTrigger,
+                                       false,   // boolean stillSincePress,
+                                       null     // PickResult pickResult
+                                     )
+                      );
+
+        // mainStage.setScene(scene);
+        // mainStage.show();
+        Platform.exit();
+    }
+
+    // show engine invocations with script text and their Bindings
+    static void dumpEvalInformation() {
+        System.err.println("\nListing eval() invocation information (invocationList):");
+
+        Iterator<RgfPseudoScriptEngineCompilable> it = RgfPseudoScriptEngineCompilable.getEnginesUsed().iterator();
+        while (it.hasNext()) {
+            RgfPseudoScriptEngineCompilable rpse = it.next();
+            ArrayList invocationList = rpse.getInvocationList();
+            System.err.println("ScriptEngine: [" + rpse + "]");
+
+            Iterator<InvocationInfos> itEval = invocationList.iterator();
+            int count = 1;
+            while (itEval.hasNext()) {
+                System.err.println("\teval() invocation # " + count + ": ");
+                InvocationInfos entry = itEval.next();
+                System.err.println(entry.toDebugFormat("\t\t"));    // indentation
+                count++;
+                System.err.println();
+            }
+        }
+    }
+
+    static void assertCorrectInvocations() {
+            // test only creates one engine for a script controller
+        Util.assertTrue("exactly one pseudo script engine instance",
+                        RgfPseudoScriptEngineCompilable.getEnginesUsed().size() == 1);
+        RgfPseudoScriptEngineCompilable rpse = RgfPseudoScriptEngineCompilable.getEnginesUsed().get(0);
+
+        ArrayList invocationList = rpse.getInvocationList();
+        Util.assertTrue("exactly nine script engine invocations", invocationList.size() == 9);
+
+        final String FILENAME = "javax.script.filename";
+        final String ARGV = "javax.script.argv";
+        final String EVENT = "event";
+        final String IDBUTTON = "idButton";
+        final String IDROOT = "idRoot";
+        final String LOCATION = "location";    // always FXML File hosting script controller code
+        final String RESOURCES = "resources";   // always null in this test
+
+        for (Integer invocation = 1; invocation <= invocationList.size(); invocation++) {
+            InvocationInfos entry = (InvocationInfos) invocationList.get(invocation - 1);
+            String script = entry.script;
+            TreeMap<Integer,TreeMap> scopes = (TreeMap) entry.bindings;
+
+            TreeMap<String,Object> engineBindings = scopes.get(100);
+            TreeMap<String,Object> globalBindings = scopes.get(200);
+
+            Object obj = null;
+            Button btn = null;
+
+            // global Bindings
+            Util.assertExists(IDROOT + " in global scope Bindings", globalBindings.containsKey(IDROOT));
+            obj = globalBindings.get(IDROOT);
+            Util.assertType(IDROOT, AnchorPane.class, obj);
+
+            Util.assertExists(LOCATION + " in global scope Bindings", globalBindings.containsKey(LOCATION));
+            obj = globalBindings.get(LOCATION);
+            Util.assertType(LOCATION, URL.class, obj);
+
+            Util.assertExists(RESOURCES + " in global scope Bindings", globalBindings.containsKey(RESOURCES));
+            obj = globalBindings.get(RESOURCES);
+            Util.assertNull(RESOURCES,obj);
+
+            if (invocation == 1) {
+                Util.assertNotExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+            }
+            else {
+                Util.assertExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+                obj = globalBindings.get(IDBUTTON);
+                Util.assertType(IDBUTTON, Button.class, obj);
+                btn = (Button) obj;
+            }
+
+            // engine Bindings
+            Util.assertExists(FILENAME + " in engine scope Bindings", engineBindings.containsKey(FILENAME));
+            if (invocation < 7) {  // no event objects, no arguments
+                Util.assertNotExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Util.assertNotExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+            }
+            else {    // this has events on the Button
+                Util.assertExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Object[] argv = (Object[]) engineBindings.get(ARGV);
+
+                Util.assertExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+                obj = engineBindings.get(EVENT);
+
+                Util.assertSame("argv[0] == event", argv[0], obj);
+
+                if (invocation == 9) {
+                    Util.assertType(EVENT, MouseEvent.class, obj);
+                    MouseEvent ev = (MouseEvent) obj;
+                    Util.assertSame("MouseEvent.getSource() == btn", ev.getSource(), btn);
+                    Util.assertSame("MouseEvent.MOUSE_CLICKED", MouseEvent.MOUSE_CLICKED, ev.getEventType());
+                } else {
+                    Util.assertType(EVENT, ActionEvent.class, obj);
+                    ActionEvent ev = (ActionEvent) obj;
+                    Util.assertSame("ActionEvent.getSource() == btn", ev.getSource(), btn);
+                }
+            }
+
+            // check filename and script
+            String filename = (String) engineBindings.get(FILENAME);
+            boolean ok = false;
+            switch (invocation) {
+                case 1:
+                    Util.assertEndsWith  ("demo_03_topscript.sqtmc", filename);
+                    Util.assertStartsWith("demo_03_topscript.sqtmc file - pseudo script in external file, starts with the filename", script);
+                    break;
+
+                case 2:
+                    Util.assertEndsWith  ("demo_03_middlescript.sqtmc", filename);
+                    Util.assertStartsWith("demo_03_middlescript.sqtmc file - pseudo script in external file, starts with the filename", script);
+                    break;
+
+                case 3:
+                    Util.assertEndsWith("demo_03_fail_compile.fxml-script_starting_at_line_52", filename);
+                    Util.assertStartsWith("demo_03_fail_compile.fxml embedded script sqtmc - line # 52", script);
+                    break;
+
+                case 4:
+                    Util.assertEndsWith  ("demo_03_bottomscript.sqtmc", filename);
+                    Util.assertStartsWith("demo_03_bottomscript.sqtmc file - pseudo script in external file, starts with the filename", script);
+                    break;
+
+                case 5:
+                    Util.assertEndsWith("demo_03_fail_compile.fxml-script_starting_at_line_56", filename);
+                    Util.assertStartsWith("something (line # 56)(PCDATA)", script);
+                    break;
+
+                case 6:
+                    Util.assertEndsWith("demo_03_fail_compile.fxml-script_starting_at_line_59", filename);
+                    Util.assertStartsWith("demo_03_fail_compile.fxml (line # 59):", script);
+                    break;
+
+                case 7:     // same as case 8 (same button clicked)
+                    Util.assertEndsWith("demo_03_fail_compile.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_03_fail_compile.fxml embedded event - ActionEvent - line # 45 - LF entity (&#10;) forces linebreak in attribute value:", script);
+                    break;
+
+                case 8:     // same as case 7 (same button clicked)
+                    Util.assertEndsWith("demo_03_fail_compile.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_03_fail_compile.fxml embedded event - ActionEvent - line # 45 - LF entity (&#10;) forces linebreak in attribute value:", script);
+                    break;
+
+                case 9:
+                    Util.assertEndsWith("demo_03_fail_compile.fxml-onMouseClicked_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_03_fail_compile.fxml embedded event - MouseClicked - line # 44 (PCDATA)", script);
+                    break;
+            }
+        }
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Off.java b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Off.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Off.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myapp2;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+
+import static myapp2.Constants.*;
+import pseudoScriptEngineCompilable.InvocationInfos;
+import pseudoScriptEngineCompilable.RgfPseudoScriptEngineCompilable;
+
+/**
+ * Modular test application for testing FXML.
+ * This is launched by ModuleLauncherTest.
+ */
+public class FXMLScriptDeployment2Compile_Off extends Application {
+
+    static boolean bDebug = false; // true; // display invocation list
+
+    /** Runs the application and invokes the tests.
+     *  @param args the command line arguments, if any given the RgfPseudoScriptEngine invocation logs get displayed
+     *              which are used in the asserCorrectInvocations() method
+     */
+    public static void main(String[] args) {
+        try {
+            // any argument will cause the bDebug flag to be set to true
+            if (args.length > 0) {
+               bDebug = true;
+            }
+            new FXMLScriptDeployment2Compile_Off().launch();
+            // for debugging, allows to study invocation logs in detail
+            if (bDebug) { dumpEvalInformation(); }
+            assertCorrectInvocations();
+        } catch (AssertionError ex) {
+            System.err.println("ASSERTION ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_ASSERTION_FAILURE);
+        } catch (Error | Exception ex) {
+            System.err.println("ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+        System.exit(ERROR_NONE);    // not in stop() method as we need to run the assertions first
+    }
+
+    @Override
+    public void start(Stage mainStage) {
+        URL fxmlUrl = null;
+        Parent rootNode = null;
+        Scene scene = null;
+        Button btn = null;
+        try {
+             fxmlUrl = Util.getURL(FXMLScriptDeployment2Compile_Off.class, "demo_02_off");
+             rootNode = FXMLLoader.load(fxmlUrl);
+             scene = new Scene(rootNode);
+             btn = (Button) scene.lookup("#idButton");
+        }
+        catch (Exception ioe) {
+            ioe.printStackTrace();
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+            // fire three events on the button
+        btn.fire();
+        btn.fireEvent(new ActionEvent());
+        btn.fireEvent(new MouseEvent(MouseEvent.MOUSE_CLICKED,
+                                       0,       // double x,
+                                       0,       // double y,
+                                       0,       // double screenX,
+                                       0,       // double screenY,
+                                       MouseButton.PRIMARY,         // MouseButton button,
+                                       0,       // int clickCount,
+                                       false,   // boolean shiftDown,
+                                       false,   // boolean controlDown,
+                                       false,   // boolean altDown,
+                                       false,   // boolean metaDown,
+                                       true,    // boolean primaryButtonDown,
+                                       false,   // boolean middleButtonDown,
+                                       false,   // boolean secondaryButtonDown,
+                                       false,   // boolean synthesized,
+                                       false,   // boolean popupTrigger,
+                                       false,   // boolean stillSincePress,
+                                       null     // PickResult pickResult
+                                     )
+                      );
+
+        // mainStage.setScene(scene);
+        // mainStage.show();
+        Platform.exit();
+    }
+
+    // show engine invocations with script text and their Bindings
+    static void dumpEvalInformation() {
+        System.err.println("\nListing eval() invocation information (invocationList):");
+
+        Iterator<RgfPseudoScriptEngineCompilable> it = RgfPseudoScriptEngineCompilable.getEnginesUsed().iterator();
+        while (it.hasNext()) {
+            RgfPseudoScriptEngineCompilable rpse = it.next();
+            ArrayList invocationList = rpse.getInvocationList();
+            System.err.println("ScriptEngine: [" + rpse + "]");
+
+            Iterator<InvocationInfos> itEval = invocationList.iterator();
+            int count = 1;
+            while (itEval.hasNext()) {
+                System.err.println("\teval() invocation # " + count + ": ");
+                InvocationInfos entry = itEval.next();
+                System.err.println(entry.toDebugFormat("\t\t"));    // indentation
+                count++;
+                System.err.println();
+            }
+        }
+    }
+
+    static void assertCorrectInvocations() {
+            // test only creates one engine for a script controller
+        Util.assertTrue("exactly one pseudo script engine instance",
+                        RgfPseudoScriptEngineCompilable.getEnginesUsed().size() == 1);
+        RgfPseudoScriptEngineCompilable rpse = RgfPseudoScriptEngineCompilable.getEnginesUsed().get(0);
+
+        ArrayList invocationList = rpse.getInvocationList();
+        Util.assertTrue("exactly nine script engine invocations", invocationList.size() == 9);
+
+        final String FILENAME = "javax.script.filename";
+        final String ARGV = "javax.script.argv";
+        final String EVENT = "event";
+        final String IDBUTTON = "idButton";
+        final String IDROOT = "idRoot";
+        final String LOCATION = "location";    // always FXML File hosting script controller code
+        final String RESOURCES = "resources";   // always null in this test
+
+        for (Integer invocation = 1; invocation <= invocationList.size(); invocation++) {
+            InvocationInfos entry = (InvocationInfos) invocationList.get(invocation - 1);
+            String script = entry.script;
+            TreeMap<Integer,TreeMap> scopes = (TreeMap) entry.bindings;
+
+            TreeMap<String,Object> engineBindings = scopes.get(100);
+            TreeMap<String,Object> globalBindings = scopes.get(200);
+
+            Object obj = null;
+            Button btn = null;
+
+            // global Bindings
+            Util.assertExists(IDROOT + " in global scope Bindings", globalBindings.containsKey(IDROOT));
+            obj = globalBindings.get(IDROOT);
+            Util.assertType(IDROOT, AnchorPane.class, obj);
+
+            Util.assertExists(LOCATION + " in global scope Bindings", globalBindings.containsKey(LOCATION));
+            obj = globalBindings.get(LOCATION);
+            Util.assertType(LOCATION, URL.class, obj);
+
+            Util.assertExists(RESOURCES + " in global scope Bindings", globalBindings.containsKey(RESOURCES));
+            obj = globalBindings.get(RESOURCES);
+            Util.assertNull(RESOURCES,obj);
+
+            if (invocation == 1) {
+                Util.assertNotExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+            }
+            else {
+                Util.assertExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+                obj = globalBindings.get(IDBUTTON);
+                Util.assertType(IDBUTTON, Button.class, obj);
+                btn = (Button) obj;
+            }
+
+            // engine Bindings
+            Util.assertExists(FILENAME + " in engine scope Bindings", engineBindings.containsKey(FILENAME));
+            if (invocation < 7) {  // no event objects, no arguments
+                Util.assertNotExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Util.assertNotExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+            }
+            else {    // this has events on the Button
+                Util.assertExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Object[] argv = (Object[]) engineBindings.get(ARGV);
+
+                Util.assertExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+                obj = engineBindings.get(EVENT);
+
+                Util.assertSame("argv[0] == event", argv[0], obj);
+
+                if (invocation == 9) {
+                    Util.assertType(EVENT, MouseEvent.class, obj);
+                    MouseEvent ev = (MouseEvent) obj;
+                    Util.assertSame("MouseEvent.getSource() == btn", ev.getSource(), btn);
+                    Util.assertSame("MouseEvent.MOUSE_CLICKED", MouseEvent.MOUSE_CLICKED, ev.getEventType());
+                } else {
+                    Util.assertType(EVENT, ActionEvent.class, obj);
+                    ActionEvent ev = (ActionEvent) obj;
+                    Util.assertSame("ActionEvent.getSource() == btn", ev.getSource(), btn);
+                }
+            }
+
+            // check filename and script
+            String filename = (String) engineBindings.get(FILENAME);
+            boolean ok = false;
+            switch (invocation) {
+                case 1:
+                    Util.assertEndsWith  ("demo_02_topscript.sqtmc", filename);
+                    Util.assertStartsWith("demo_02_topscript.sqtmc file - pseudo script in external file, starts with the filename", script);
+                    break;
+
+                case 2:
+                    Util.assertEndsWith  ("demo_02_middlescript.sqtmc", filename);
+                    Util.assertStartsWith("demo_02_middlescript.sqtmc file - pseudo script in external file, starts with the filename", script);
+                    break;
+
+                case 3:
+                    Util.assertEndsWith("demo_02_off.fxml-script_starting_at_line_52", filename);
+                    Util.assertStartsWith("demo_02_off.fxml embedded script sqtmc - line # 52", script);
+                    break;
+
+                case 4:
+                    Util.assertEndsWith  ("demo_02_bottomscript.sqtmc", filename);
+                    Util.assertStartsWith("demo_02_bottomscript.sqtmc file - pseudo script in external file, starts with the filename", script);
+                    break;
+
+                case 5:
+                    Util.assertEndsWith("demo_02_off.fxml-script_starting_at_line_56", filename);
+                    Util.assertStartsWith("something (line # 56)(PCDATA)", script);
+                    break;
+
+                case 6:
+                    Util.assertEndsWith("demo_02_off.fxml-script_starting_at_line_59", filename);
+                    Util.assertStartsWith("demo_02_off.fxml (line # 59):", script);
+                    break;
+
+                case 7:     // same as case 8 (same button clicked)
+                    Util.assertEndsWith("demo_02_off.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_02_off.fxml embedded event - ActionEvent - line # 45 - LF entity (&#10;) forces linebreak in attribute value:", script);
+                    break;
+
+                case 8:     // same as case 7 (same button clicked)
+                    Util.assertEndsWith("demo_02_off.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_02_off.fxml embedded event - ActionEvent - line # 45 - LF entity (&#10;) forces linebreak in attribute value:", script);
+                    break;
+
+                case 9:
+                    Util.assertEndsWith("demo_02_off.fxml-onMouseClicked_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_02_off.fxml embedded event - MouseClicked - line # 44 (PCDATA)", script);
+                    break;
+            }
+        }
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Off_On.java b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Off_On.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Off_On.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myapp2;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+
+import static myapp2.Constants.*;
+import pseudoScriptEngineCompilable.InvocationInfos;
+import pseudoScriptEngineCompilable.RgfPseudoScriptEngineCompilable;
+
+/**
+ * Modular test application for testing FXML.
+ * This is launched by ModuleLauncherTest.
+ */
+public class FXMLScriptDeployment2Compile_Off_On extends Application {
+
+    static boolean bDebug = false; // true; // display invocation list
+
+    /** Runs the application and invokes the tests.
+     *  @param args the command line arguments, if any given the RgfPseudoScriptEngine invocation logs get displayed
+     *              which are used in the asserCorrectInvocations() method
+     */
+    public static void main(String[] args) {
+        try {
+            // any argument will cause the bDebug flag to be set to true
+            if (args.length > 0) {
+               bDebug = true;
+            }
+            new FXMLScriptDeployment2Compile_Off_On().launch();
+            // for debugging, allows to study invocation logs in detail
+            if (bDebug) { dumpEvalInformation(); }
+            assertCorrectInvocations();
+        } catch (AssertionError ex) {
+            System.err.println("ASSERTION ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_ASSERTION_FAILURE);
+        } catch (Error | Exception ex) {
+            System.err.println("ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+        System.exit(ERROR_NONE);    // not in stop() method as we need to run the assertions first
+    }
+
+    @Override
+    public void start(Stage mainStage) {
+        URL fxmlUrl = null;
+        Parent rootNode = null;
+        Scene scene = null;
+        Button btn = null;
+        try {
+             fxmlUrl = Util.getURL(FXMLScriptDeployment2Compile_Off_On.class, "demo_02_off_on");
+             rootNode = FXMLLoader.load(fxmlUrl);
+             scene = new Scene(rootNode);
+             btn = (Button) scene.lookup("#idButton");
+        }
+        catch (Exception ioe) {
+            ioe.printStackTrace();
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+            // fire three events on the button
+        btn.fire();
+        btn.fireEvent(new ActionEvent());
+        btn.fireEvent(new MouseEvent(MouseEvent.MOUSE_CLICKED,
+                                       0,       // double x,
+                                       0,       // double y,
+                                       0,       // double screenX,
+                                       0,       // double screenY,
+                                       MouseButton.PRIMARY,         // MouseButton button,
+                                       0,       // int clickCount,
+                                       false,   // boolean shiftDown,
+                                       false,   // boolean controlDown,
+                                       false,   // boolean altDown,
+                                       false,   // boolean metaDown,
+                                       true,    // boolean primaryButtonDown,
+                                       false,   // boolean middleButtonDown,
+                                       false,   // boolean secondaryButtonDown,
+                                       false,   // boolean synthesized,
+                                       false,   // boolean popupTrigger,
+                                       false,   // boolean stillSincePress,
+                                       null     // PickResult pickResult
+                                     )
+                      );
+
+        // mainStage.setScene(scene);
+        // mainStage.show();
+        Platform.exit();
+    }
+
+    // show engine invocations with script text and their Bindings
+    static void dumpEvalInformation() {
+        System.err.println("\nListing eval() invocation information (invocationList):");
+
+        Iterator<RgfPseudoScriptEngineCompilable> it = RgfPseudoScriptEngineCompilable.getEnginesUsed().iterator();
+        while (it.hasNext()) {
+            RgfPseudoScriptEngineCompilable rpse = it.next();
+            ArrayList invocationList = rpse.getInvocationList();
+            System.err.println("ScriptEngine: [" + rpse + "]");
+
+            Iterator<InvocationInfos> itEval = invocationList.iterator();
+            int count = 1;
+            while (itEval.hasNext()) {
+                System.err.println("\teval() invocation # " + count + ": ");
+                InvocationInfos entry = itEval.next();
+                System.err.println(entry.toDebugFormat("\t\t"));    // indentation
+                count++;
+                System.err.println();
+            }
+        }
+    }
+
+    static void assertCorrectInvocations() {
+            // test only creates one engine for a script controller
+        Util.assertTrue("exactly one pseudo script engine instance",
+                        RgfPseudoScriptEngineCompilable.getEnginesUsed().size() == 1);
+        RgfPseudoScriptEngineCompilable rpse = RgfPseudoScriptEngineCompilable.getEnginesUsed().get(0);
+
+        ArrayList invocationList = rpse.getInvocationList();
+        Util.assertTrue("exactly nine script engine invocations", invocationList.size() == 9);
+
+        final String FILENAME = "javax.script.filename";
+        final String ARGV = "javax.script.argv";
+        final String EVENT = "event";
+        final String IDBUTTON = "idButton";
+        final String IDROOT = "idRoot";
+        final String LOCATION = "location";    // always FXML File hosting script controller code
+        final String RESOURCES = "resources";   // always null in this test
+
+        for (Integer invocation = 1; invocation <= invocationList.size(); invocation++) {
+            InvocationInfos entry = (InvocationInfos) invocationList.get(invocation - 1);
+            String script = entry.script;
+            TreeMap<Integer,TreeMap> scopes = (TreeMap) entry.bindings;
+
+            TreeMap<String,Object> engineBindings = scopes.get(100);
+            TreeMap<String,Object> globalBindings = scopes.get(200);
+
+            Object obj = null;
+            Button btn = null;
+
+            // global Bindings
+            Util.assertExists(IDROOT + " in global scope Bindings", globalBindings.containsKey(IDROOT));
+            obj = globalBindings.get(IDROOT);
+            Util.assertType(IDROOT, AnchorPane.class, obj);
+
+            Util.assertExists(LOCATION + " in global scope Bindings", globalBindings.containsKey(LOCATION));
+            obj = globalBindings.get(LOCATION);
+            Util.assertType(LOCATION, URL.class, obj);
+
+            Util.assertExists(RESOURCES + " in global scope Bindings", globalBindings.containsKey(RESOURCES));
+            obj = globalBindings.get(RESOURCES);
+            Util.assertNull(RESOURCES,obj);
+
+            if (invocation == 1) {
+                Util.assertNotExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+            }
+            else {
+                Util.assertExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+                obj = globalBindings.get(IDBUTTON);
+                Util.assertType(IDBUTTON, Button.class, obj);
+                btn = (Button) obj;
+            }
+
+            // engine Bindings
+            Util.assertExists(FILENAME + " in engine scope Bindings", engineBindings.containsKey(FILENAME));
+            if (invocation < 7) {  // no event objects, no arguments
+                Util.assertNotExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Util.assertNotExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+            }
+            else {    // this has events on the Button
+                Util.assertExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Object[] argv = (Object[]) engineBindings.get(ARGV);
+
+                Util.assertExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+                obj = engineBindings.get(EVENT);
+
+                Util.assertSame("argv[0] == event", argv[0], obj);
+
+                if (invocation == 9) {
+                    Util.assertType(EVENT, MouseEvent.class, obj);
+                    MouseEvent ev = (MouseEvent) obj;
+                    Util.assertSame("MouseEvent.getSource() == btn", ev.getSource(), btn);
+                    Util.assertSame("MouseEvent.MOUSE_CLICKED", MouseEvent.MOUSE_CLICKED, ev.getEventType());
+                } else {
+                    Util.assertType(EVENT, ActionEvent.class, obj);
+                    ActionEvent ev = (ActionEvent) obj;
+                    Util.assertSame("ActionEvent.getSource() == btn", ev.getSource(), btn);
+                }
+            }
+
+            // check filename and script
+            String filename = (String) engineBindings.get(FILENAME);
+            boolean ok = false;
+            switch (invocation) {
+                case 1:
+                    Util.assertEndsWith  ("demo_02_topscript.sqtmc", filename);
+                    Util.assertStartsWith("demo_02_topscript.sqtmc file - pseudo script in external file, starts with the filename", script);
+                    break;
+
+                case 2:
+                    Util.assertEndsWith  ("demo_02_middlescript.sqtmc", filename);
+                    Util.assertStartsWith("demo_02_middlescript.sqtmc file - pseudo script in external file, starts with the filename", script);
+                    break;
+
+                case 3:
+                    Util.assertEndsWith("demo_02_off_on.fxml-script_starting_at_line_52", filename);
+                    Util.assertStartsWith("demo_02_off_on.fxml embedded script sqtmc - line # 52", script);
+                    break;
+
+                case 4:
+                    Util.assertEndsWith  ("demo_02_bottomscript.sqtmc", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_bottomscript.sqtmc file - pseudo script", script);
+                    break;
+
+                case 5:
+                    Util.assertEndsWith("demo_02_off_on.fxml-script_starting_at_line_56", filename);
+                    Util.assertStartsWith("something (line # 56)(PCDATA)", script);
+                    break;
+
+                case 6:
+                    Util.assertEndsWith("demo_02_off_on.fxml-script_starting_at_line_59", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_off_on.fxml (line # 59):", script);
+                    break;
+
+                case 7:     // same as case 8 (same button clicked)
+                    Util.assertEndsWith("demo_02_off_on.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_off_on.fxml embedded event - ActionEvent - line # 45 -", script);
+                    break;
+
+                case 8:     // same as case 7 (same button clicked)
+                    Util.assertEndsWith("demo_02_off_on.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_off_on.fxml embedded event - ActionEvent - line # 45 -", script);
+                    break;
+
+                case 9:
+                    Util.assertEndsWith("demo_02_off_on.fxml-onMouseClicked_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_off_on.fxml embedded event - MouseClicked - line # 44", script);
+                    break;
+            }
+        }
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_On.java b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_On.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_On.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myapp2;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+
+import static myapp2.Constants.*;
+import pseudoScriptEngineCompilable.InvocationInfos;
+import pseudoScriptEngineCompilable.RgfPseudoScriptEngineCompilable;
+
+/**
+ * Modular test application for testing FXML.
+ * This is launched by ModuleLauncherTest.
+ */
+public class FXMLScriptDeployment2Compile_On extends Application {
+
+    static boolean bDebug = false; // true; // display invocation list
+
+    /** Runs the application and invokes the tests.
+     *  @param args the command line arguments, if any given the RgfPseudoScriptEngine invocation logs get displayed
+     *              which are used in the asserCorrectInvocations() method
+     */
+    public static void main(String[] args) {
+        try {
+            // any argument will cause the bDebug flag to be set to true
+            if (args.length > 0) {
+               bDebug = true;
+            }
+            new FXMLScriptDeployment2Compile_On().launch();
+            // for debugging, allows to study invocation logs in detail
+            if (bDebug) { dumpEvalInformation(); }
+            assertCorrectInvocations();
+        } catch (AssertionError ex) {
+            System.err.println("ASSERTION ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_ASSERTION_FAILURE);
+        } catch (Error | Exception ex) {
+            System.err.println("ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+        System.exit(ERROR_NONE);    // not in stop() method as we need to run the assertions first
+    }
+
+    @Override
+    public void start(Stage mainStage) {
+        URL fxmlUrl = null;
+        Parent rootNode = null;
+        Scene scene = null;
+        Button btn = null;
+        try {
+             fxmlUrl = Util.getURL(FXMLScriptDeployment2Compile_On.class, "demo_02_on");
+             rootNode = FXMLLoader.load(fxmlUrl);
+             scene = new Scene(rootNode);
+             btn = (Button) scene.lookup("#idButton");
+        }
+        catch (Exception ioe) {
+            ioe.printStackTrace();
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+            // fire three events on the button
+        btn.fire();
+        btn.fireEvent(new ActionEvent());
+        btn.fireEvent(new MouseEvent(MouseEvent.MOUSE_CLICKED,
+                                       0,       // double x,
+                                       0,       // double y,
+                                       0,       // double screenX,
+                                       0,       // double screenY,
+                                       MouseButton.PRIMARY,         // MouseButton button,
+                                       0,       // int clickCount,
+                                       false,   // boolean shiftDown,
+                                       false,   // boolean controlDown,
+                                       false,   // boolean altDown,
+                                       false,   // boolean metaDown,
+                                       true,    // boolean primaryButtonDown,
+                                       false,   // boolean middleButtonDown,
+                                       false,   // boolean secondaryButtonDown,
+                                       false,   // boolean synthesized,
+                                       false,   // boolean popupTrigger,
+                                       false,   // boolean stillSincePress,
+                                       null     // PickResult pickResult
+                                     )
+                      );
+
+        // mainStage.setScene(scene);
+        // mainStage.show();
+        Platform.exit();
+    }
+
+    // show engine invocations with script text and their Bindings
+    static void dumpEvalInformation() {
+        System.err.println("\nListing eval() invocation information (invocationList):");
+
+        Iterator<RgfPseudoScriptEngineCompilable> it = RgfPseudoScriptEngineCompilable.getEnginesUsed().iterator();
+        while (it.hasNext()) {
+            RgfPseudoScriptEngineCompilable rpse = it.next();
+            ArrayList invocationList = rpse.getInvocationList();
+            System.err.println("ScriptEngine: [" + rpse + "]");
+
+            Iterator<InvocationInfos> itEval = invocationList.iterator();
+            int count = 1;
+            while (itEval.hasNext()) {
+                System.err.println("\teval() invocation # " + count + ": ");
+                InvocationInfos entry = itEval.next();
+                System.err.println(entry.toDebugFormat("\t\t"));    // indentation
+                count++;
+                System.err.println();
+            }
+        }
+    }
+
+    static void assertCorrectInvocations() {
+            // test only creates one engine for a script controller
+        Util.assertTrue("exactly one pseudo script engine instance",
+                        RgfPseudoScriptEngineCompilable.getEnginesUsed().size() == 1);
+        RgfPseudoScriptEngineCompilable rpse = RgfPseudoScriptEngineCompilable.getEnginesUsed().get(0);
+
+        ArrayList invocationList = rpse.getInvocationList();
+        Util.assertTrue("exactly nine script engine invocations", invocationList.size() == 9);
+
+        final String FILENAME = "javax.script.filename";
+        final String ARGV = "javax.script.argv";
+        final String EVENT = "event";
+        final String IDBUTTON = "idButton";
+        final String IDROOT = "idRoot";
+        final String LOCATION = "location";    // always FXML File hosting script controller code
+        final String RESOURCES = "resources";   // always null in this test
+
+        for (Integer invocation = 1; invocation <= invocationList.size(); invocation++) {
+            InvocationInfos entry = (InvocationInfos) invocationList.get(invocation - 1);
+            String script = entry.script;
+            TreeMap<Integer,TreeMap> scopes = (TreeMap) entry.bindings;
+
+            TreeMap<String,Object> engineBindings = scopes.get(100);
+            TreeMap<String,Object> globalBindings = scopes.get(200);
+
+            Object obj = null;
+            Button btn = null;
+
+            // global Bindings
+            Util.assertExists(IDROOT + " in global scope Bindings", globalBindings.containsKey(IDROOT));
+            obj = globalBindings.get(IDROOT);
+            Util.assertType(IDROOT, AnchorPane.class, obj);
+
+            Util.assertExists(LOCATION + " in global scope Bindings", globalBindings.containsKey(LOCATION));
+            obj = globalBindings.get(LOCATION);
+            Util.assertType(LOCATION, URL.class, obj);
+
+            Util.assertExists(RESOURCES + " in global scope Bindings", globalBindings.containsKey(RESOURCES));
+            obj = globalBindings.get(RESOURCES);
+            Util.assertNull(RESOURCES,obj);
+
+            if (invocation == 1) {
+                Util.assertNotExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+            }
+            else {
+                Util.assertExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+                obj = globalBindings.get(IDBUTTON);
+                Util.assertType(IDBUTTON, Button.class, obj);
+                btn = (Button) obj;
+            }
+
+            // engine Bindings
+            Util.assertExists(FILENAME + " in engine scope Bindings", engineBindings.containsKey(FILENAME));
+            if (invocation < 7) {  // no event objects, no arguments
+                Util.assertNotExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Util.assertNotExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+            }
+            else {    // this has events on the Button
+                Util.assertExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Object[] argv = (Object[]) engineBindings.get(ARGV);
+
+                Util.assertExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+                obj = engineBindings.get(EVENT);
+
+                Util.assertSame("argv[0] == event", argv[0], obj);
+
+                if (invocation == 9) {
+                    Util.assertType(EVENT, MouseEvent.class, obj);
+                    MouseEvent ev = (MouseEvent) obj;
+                    Util.assertSame("MouseEvent.getSource() == btn", ev.getSource(), btn);
+                    Util.assertSame("MouseEvent.MOUSE_CLICKED", MouseEvent.MOUSE_CLICKED, ev.getEventType());
+                } else {
+                    Util.assertType(EVENT, ActionEvent.class, obj);
+                    ActionEvent ev = (ActionEvent) obj;
+                    Util.assertSame("ActionEvent.getSource() == btn", ev.getSource(), btn);
+                }
+            }
+
+            // check filename and script
+            String filename = (String) engineBindings.get(FILENAME);
+            boolean ok = false;
+            switch (invocation) {
+                case 1:
+                    Util.assertEndsWith  ("demo_02_topscript.sqtmc", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_topscript.sqtmc file - pseudo script", script);
+                    break;
+
+                case 2:
+                    Util.assertEndsWith  ("demo_02_middlescript.sqtmc", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_middlescript.sqtmc file - pseudo script", script);
+                    break;
+
+                case 3:
+                    Util.assertEndsWith("demo_02_on.fxml-script_starting_at_line_52", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_on.fxml embedded script sqtmc - line # 52", script);
+                    break;
+
+                case 4:
+                    Util.assertEndsWith  ("demo_02_bottomscript.sqtmc", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_bottomscript.sqtmc file - pseudo script", script);
+                    break;
+
+                case 5:
+                    Util.assertEndsWith("demo_02_on.fxml-script_starting_at_line_56", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[something (line # 56)", script);
+                    break;
+
+                case 6:
+                    Util.assertEndsWith("demo_02_on.fxml-script_starting_at_line_59", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_on.fxml (line # 59):", script);
+                    break;
+
+                case 7:     // same as case 8 (same button clicked)
+                    Util.assertEndsWith("demo_02_on.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_on.fxml embedded event - ActionEvent - line # 45 -", script);
+                    break;
+
+                case 8:     // same as case 7 (same button clicked)
+                    Util.assertEndsWith("demo_02_on.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_on.fxml embedded event - ActionEvent - line # 45 -", script);
+                    break;
+
+                case 9:
+                    Util.assertEndsWith("demo_02_on.fxml-onMouseClicked_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_on.fxml embedded event - MouseClicked - line # 44", script);
+                    break;
+            }
+        }
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_On_Off.java b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_On_Off.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_On_Off.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myapp2;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+
+import static myapp2.Constants.*;
+import pseudoScriptEngineCompilable.InvocationInfos;
+import pseudoScriptEngineCompilable.RgfPseudoScriptEngineCompilable;
+
+/**
+ * Modular test application for testing FXML.
+ * This is launched by ModuleLauncherTest.
+ */
+public class FXMLScriptDeployment2Compile_On_Off extends Application {
+
+    static boolean bDebug = false; // true; // display invocation list
+
+    /** Runs the application and invokes the tests.
+     *  @param args the command line arguments, if any given the RgfPseudoScriptEngine invocation logs get displayed
+     *              which are used in the asserCorrectInvocations() method
+     */
+    public static void main(String[] args) {
+        try {
+            // any argument will cause the bDebug flag to be set to true
+            if (args.length > 0) {
+               bDebug = true;
+            }
+            new FXMLScriptDeployment2Compile_On_Off().launch();
+            // for debugging, allows to study invocation logs in detail
+            if (bDebug) { dumpEvalInformation(); }
+            assertCorrectInvocations();
+        } catch (AssertionError ex) {
+            System.err.println("ASSERTION ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_ASSERTION_FAILURE);
+        } catch (Error | Exception ex) {
+            System.err.println("ERROR: caught unexpected exception: " + ex);
+            ex.printStackTrace(System.err);
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+        System.exit(ERROR_NONE);    // not in stop() method as we need to run the assertions first
+    }
+
+    @Override
+    public void start(Stage mainStage) {
+        URL fxmlUrl = null;
+        Parent rootNode = null;
+        Scene scene = null;
+        Button btn = null;
+        try {
+             fxmlUrl = Util.getURL(FXMLScriptDeployment2Compile_On_Off.class, "demo_02_on_off");
+             rootNode = FXMLLoader.load(fxmlUrl);
+             scene = new Scene(rootNode);
+             btn = (Button) scene.lookup("#idButton");
+        }
+        catch (Exception ioe) {
+            ioe.printStackTrace();
+            System.exit(ERROR_UNEXPECTED_EXCEPTION);
+        }
+            // fire three events on the button
+        btn.fire();
+        btn.fireEvent(new ActionEvent());
+        btn.fireEvent(new MouseEvent(MouseEvent.MOUSE_CLICKED,
+                                       0,       // double x,
+                                       0,       // double y,
+                                       0,       // double screenX,
+                                       0,       // double screenY,
+                                       MouseButton.PRIMARY,         // MouseButton button,
+                                       0,       // int clickCount,
+                                       false,   // boolean shiftDown,
+                                       false,   // boolean controlDown,
+                                       false,   // boolean altDown,
+                                       false,   // boolean metaDown,
+                                       true,    // boolean primaryButtonDown,
+                                       false,   // boolean middleButtonDown,
+                                       false,   // boolean secondaryButtonDown,
+                                       false,   // boolean synthesized,
+                                       false,   // boolean popupTrigger,
+                                       false,   // boolean stillSincePress,
+                                       null     // PickResult pickResult
+                                     )
+                      );
+
+        // mainStage.setScene(scene);
+        // mainStage.show();
+        Platform.exit();
+    }
+
+    // show engine invocations with script text and their Bindings
+    static void dumpEvalInformation() {
+        System.err.println("\nListing eval() invocation information (invocationList):");
+
+        Iterator<RgfPseudoScriptEngineCompilable> it = RgfPseudoScriptEngineCompilable.getEnginesUsed().iterator();
+        while (it.hasNext()) {
+            RgfPseudoScriptEngineCompilable rpse = it.next();
+            ArrayList invocationList = rpse.getInvocationList();
+            System.err.println("ScriptEngine: [" + rpse + "]");
+
+            Iterator<InvocationInfos> itEval = invocationList.iterator();
+            int count = 1;
+            while (itEval.hasNext()) {
+                System.err.println("\teval() invocation # " + count + ": ");
+                InvocationInfos entry = itEval.next();
+                System.err.println(entry.toDebugFormat("\t\t"));    // indentation
+                count++;
+                System.err.println();
+            }
+        }
+    }
+
+    static void assertCorrectInvocations() {
+            // test only creates one engine for a script controller
+        Util.assertTrue("exactly one pseudo script engine instance",
+                        RgfPseudoScriptEngineCompilable.getEnginesUsed().size() == 1);
+        RgfPseudoScriptEngineCompilable rpse = RgfPseudoScriptEngineCompilable.getEnginesUsed().get(0);
+
+        ArrayList invocationList = rpse.getInvocationList();
+        Util.assertTrue("exactly nine script engine invocations", invocationList.size() == 9);
+
+        final String FILENAME = "javax.script.filename";
+        final String ARGV = "javax.script.argv";
+        final String EVENT = "event";
+        final String IDBUTTON = "idButton";
+        final String IDROOT = "idRoot";
+        final String LOCATION = "location";    // always FXML File hosting script controller code
+        final String RESOURCES = "resources";   // always null in this test
+
+        for (Integer invocation = 1; invocation <= invocationList.size(); invocation++) {
+            InvocationInfos entry = (InvocationInfos) invocationList.get(invocation - 1);
+            String script = entry.script;
+            TreeMap<Integer,TreeMap> scopes = (TreeMap) entry.bindings;
+
+            TreeMap<String,Object> engineBindings = scopes.get(100);
+            TreeMap<String,Object> globalBindings = scopes.get(200);
+
+            Object obj = null;
+            Button btn = null;
+
+            // global Bindings
+            Util.assertExists(IDROOT + " in global scope Bindings", globalBindings.containsKey(IDROOT));
+            obj = globalBindings.get(IDROOT);
+            Util.assertType(IDROOT, AnchorPane.class, obj);
+
+            Util.assertExists(LOCATION + " in global scope Bindings", globalBindings.containsKey(LOCATION));
+            obj = globalBindings.get(LOCATION);
+            Util.assertType(LOCATION, URL.class, obj);
+
+            Util.assertExists(RESOURCES + " in global scope Bindings", globalBindings.containsKey(RESOURCES));
+            obj = globalBindings.get(RESOURCES);
+            Util.assertNull(RESOURCES,obj);
+
+            if (invocation == 1) {
+                Util.assertNotExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+            }
+            else {
+                Util.assertExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON));
+                obj = globalBindings.get(IDBUTTON);
+                Util.assertType(IDBUTTON, Button.class, obj);
+                btn = (Button) obj;
+            }
+
+            // engine Bindings
+            Util.assertExists(FILENAME + " in engine scope Bindings", engineBindings.containsKey(FILENAME));
+            if (invocation < 7) {  // no event objects, no arguments
+                Util.assertNotExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Util.assertNotExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+            }
+            else {    // this has events on the Button
+                Util.assertExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV));
+                Object[] argv = (Object[]) engineBindings.get(ARGV);
+
+                Util.assertExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT));
+                obj = engineBindings.get(EVENT);
+
+                Util.assertSame("argv[0] == event", argv[0], obj);
+
+                if (invocation == 9) {
+                    Util.assertType(EVENT, MouseEvent.class, obj);
+                    MouseEvent ev = (MouseEvent) obj;
+                    Util.assertSame("MouseEvent.getSource() == btn", ev.getSource(), btn);
+                    Util.assertSame("MouseEvent.MOUSE_CLICKED", MouseEvent.MOUSE_CLICKED, ev.getEventType());
+                } else {
+                    Util.assertType(EVENT, ActionEvent.class, obj);
+                    ActionEvent ev = (ActionEvent) obj;
+                    Util.assertSame("ActionEvent.getSource() == btn", ev.getSource(), btn);
+                }
+            }
+
+            // check filename and script
+            String filename = (String) engineBindings.get(FILENAME);
+            boolean ok = false;
+            switch (invocation) {
+                case 1:
+                    Util.assertEndsWith  ("demo_02_topscript.sqtmc", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_topscript.sqtmc file - pseudo script", script);
+                    break;
+
+                case 2:
+                    Util.assertEndsWith  ("demo_02_middlescript.sqtmc", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_middlescript.sqtmc file - pseudo script", script);
+                    break;
+
+                case 3:
+                    Util.assertEndsWith("demo_02_on_off.fxml-script_starting_at_line_52", filename);
+                    Util.assertStartsWith("demo_02_on_off.fxml embedded script sqtmc - line # 52", script);
+                    break;
+
+                case 4:
+                    Util.assertEndsWith  ("demo_02_bottomscript.sqtmc", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_bottomscript.sqtmc file - pseudo script", script);
+                    break;
+
+                case 5:
+                    Util.assertEndsWith("demo_02_on_off.fxml-script_starting_at_line_56", filename);
+                    Util.assertStartsWith("something (line # 56)(PCDATA)", script);
+                    break;
+
+                case 6:
+                    Util.assertEndsWith("demo_02_on_off.fxml-script_starting_at_line_59", filename);
+                    Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_on_off.fxml (line # 59):", script);
+                    break;
+
+                case 7:     // same as case 8 (same button clicked)
+                    Util.assertEndsWith("demo_02_on_off.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_02_on_off.fxml embedded event - ActionEvent - line # 45 - LF entity (&#10;) forces linebreak", script);
+                    break;
+
+                case 8:     // same as case 7 (same button clicked)
+                    Util.assertEndsWith("demo_02_on_off.fxml-onAction_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_02_on_off.fxml embedded event - ActionEvent - line # 45 - LF entity (&#10;) forces linebreak", script);
+                    break;
+
+                case 9:
+                    Util.assertEndsWith("demo_02_on_off.fxml-onMouseClicked_attribute_in_element_ending_at_line_46", filename);
+                    Util.assertStartsWith("demo_02_on_off.fxml embedded event - MouseClicked - line # 44 (PCDATA)", script);
+                    break;
+            }
+        }
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/myapp2/Util.java b/tests/system/src/testscriptapp2/java/mymod/myapp2/Util.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/myapp2/Util.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myapp2;
+
+import java.net.URL;
+
+public class Util {
+
+    public static final URL getURL(Class clazz, String name) {
+        final String theName = name + ".fxml";
+        final URL fxmlFile = clazz.getResource(theName);
+        if (fxmlFile == null) {
+            throw new AssertionError("(getURL()) unable to open: " + theName);
+        }
+        return fxmlFile;
+    }
+
+    public static void assertNull(String message, Object o) {
+        if (o != null) {
+            throw new AssertionError("(assertNull) " + message + ", expected null object, but was non-null");
+        }
+    }
+
+    public static void assertNotNull(Object o) {
+        if (o == null) {
+            throw new AssertionError("(assertNotNull) expected non-null object, but was null");
+        }
+    }
+
+    public static void assertEndsWith(String expected, String observed) {
+        if ((expected == null && observed != null) || !observed.endsWith(expected)) {
+            throw new AssertionError("(assertEndsWith) " + "expected: <" + expected + "> but was: <" + observed + ">");
+        }
+    }
+
+    public static void assertStartsWith(String expected, String observed) {
+        if ((expected == null && observed != null) || !observed.startsWith(expected)) {
+            throw new AssertionError("(assertStartsWith) " + "expected: <" + expected + "> but was: <" + observed + ">");
+        }
+    }
+
+
+    public static void assertSame(String message, Object expected, Object observed) {
+        if (expected != observed) {
+            throw new AssertionError("(assertSame) "+ message + ", expected: <" + expected + "> but was: <" + observed + ">");
+        }
+    }
+
+    public static void assertTrue(String message, boolean cond) {
+        if (!cond) {
+            throw new AssertionError("(assertTrue): " + message);
+        }
+    }
+
+    public static void assertFalse(String message, boolean cond) {
+        if (cond) {
+            throw new AssertionError("(assertFalse): " + message);
+        }
+    }
+
+    public static void assertExists(String message, boolean cond) {
+        if (!cond) {
+            throw new AssertionError("(assertExists): " + message);
+        }
+    }
+
+    public static void assertNotExists(String message, boolean cond) {
+        if (cond) {
+            throw new AssertionError("(assertNotExists): " + message);
+        }
+    }
+
+    public static void assertType(String message, Class clz, Object obj) {
+        if (obj == null) {
+            throw new AssertionError("(assertType): " + message+": \"obj\" is null");
+        }
+        else if (clz == null) {
+            throw new AssertionError("(assertType): " + message+": \"clz\" is null");
+        }
+
+        if (! clz.isInstance(obj)) {
+            throw new AssertionError("(assertType): " + message
+                                      + ", object " + obj +
+                                      " is not an instance of class " +
+                                      clz + " -> " + clz.getName() + "]");
+        }
+    }
+
+    private Util() {
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/InvocationInfos.java b/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/InvocationInfos.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/InvocationInfos.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pseudoScriptEngineCompilable;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeMap;
+
+
+/** Stores PseudoScriptEngine related invocation information for asserting and debugging. */
+public class InvocationInfos {
+    public String script;
+    public TreeMap<Integer,TreeMap<String,Object>> bindings;
+    public Instant dateTime;
+
+    InvocationInfos(String script, ScriptContext context) {
+        this.dateTime = Instant.now();
+        this.script = script;
+        this.bindings = new TreeMap();
+        // get and save each Bindings
+        for (Integer scope : context.getScopes()) {
+            Bindings binding = context.getBindings(scope);
+            bindings.put(scope, binding == null ? new TreeMap<String,Object>() : new TreeMap<String,Object>(binding));
+        }
+    }
+
+    /**
+     * Creates and returns a string having all information formatted to ease debugging.
+     * @return string formatted to ease debugging
+     */
+    public String toDebugFormat(String indentation) {
+        StringBuilder sb = new StringBuilder();
+        String indent = (indentation == null ? "\t\t" : indentation);
+        sb.append(indent).append("at:     [").append(dateTime.toString()).append("]\n");
+        sb.append(indent).append("script: [").append(script)             .append("]\n");
+
+        for (Integer scope : (Set<Integer>) bindings.keySet()) {
+            sb.append(indent).append("Bindings for scope # ").append(scope);
+            if (scope == 100) sb.append(" (ENGINE_SCOPE):");
+            else if (scope == 200) sb.append(" (GLOBAL_SCOPE):");
+            else                 sb.append(':');
+            sb.append('\n');
+
+            TreeMap<String,Object> treeMap = bindings.get(scope);
+            for (String k : (Set<String>) treeMap.keySet()) {
+                sb.append(indent).append("\t[").append(k).append("]:\t[").append(treeMap.get(k)).append("]\n");
+            }
+        }
+        return sb.toString();
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoCompiledScript.java b/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoCompiledScript.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoCompiledScript.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pseudoScriptEngineCompilable;
+
+import javax.script.Bindings;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+public class RgfPseudoCompiledScript extends CompiledScript {
+    String code = null;
+    ScriptEngine scriptEngine = null;
+
+    RgfPseudoCompiledScript(String code, ScriptEngine scriptEngine) {
+        this.code = code;
+        this.scriptEngine = scriptEngine;
+    }
+
+    public Object eval(Bindings bindings) throws ScriptException {
+        return scriptEngine.eval("RgfPseudoCompiledScript.eval(Bindings bindings): " + code, bindings);
+    }
+
+    public Object eval(ScriptContext context) throws ScriptException {
+        return scriptEngine.eval("RgfPseudoCompiledScript.eval(ScriptContext context): " + code, context);
+    }
+
+    public Object eval() throws ScriptException {
+        return scriptEngine.eval("RgfPseudoCompiledScript.eval(): " + code );
+    }
+
+    public ScriptEngine getEngine() {
+        return scriptEngine;
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoScriptEngineCompilable.java b/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoScriptEngineCompilable.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoScriptEngineCompilable.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pseudoScriptEngineCompilable;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+
+import javax.script.AbstractScriptEngine;
+import javax.script.SimpleScriptContext;
+import javax.script.SimpleBindings;
+
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeMap;
+import java.io.Reader;
+import java.io.BufferedReader;
+import java.io.IOException;
+
+import java.time.Instant;
+
+public class RgfPseudoScriptEngineCompilable extends AbstractScriptEngine implements Compilable {
+    static final boolean bDebug = false; // true;
+
+    /** Allows to log and access the ScriptEngine instances with their evalDataList. */
+    static final ArrayList<RgfPseudoScriptEngineCompilable> enginesUsed = new ArrayList();
+    public static ArrayList<RgfPseudoScriptEngineCompilable> getEnginesUsed() {
+        return enginesUsed;
+    }
+
+    public RgfPseudoScriptEngineCompilable() {
+        enginesUsed.add(this);
+    }
+
+    public ScriptEngineFactory getFactory() {
+        return new RgfPseudoScriptEngineCompilableFactory();
+    }
+
+    /** ArrayList of eval() (invocation) information. */
+    final ArrayList<InvocationInfos> invocationList = new ArrayList();
+
+    /**
+     * Returns ArrayList of eval() (invocation) information.
+     * @return invocationList
+     */
+    public ArrayList<InvocationInfos> getInvocationList() {
+        return invocationList;
+    }
+
+    public Bindings createBindings() {
+        return new SimpleBindings();
+    }
+
+    public Object eval(Reader reader, ScriptContext context) {
+        if (bDebug) System.err.println("[debug: " + this + ".eval(Reader,ScriptContext), ScriptContext=" + context + "]");
+
+        return eval(readReader(reader), context);
+    }
+
+    public Object eval(String script, ScriptContext context) {
+        if (bDebug) System.err.print("[debug: " + this + ".eval(String,ScriptContext), ScriptContext=" + context + "]");
+
+        // create copies of the Bindings for later inspection as they may
+        // get reused and changed on each eval() invocation
+        TreeMap<Integer,TreeMap> bindings = new TreeMap();
+        for (Integer scope : context.getScopes()) {
+            Bindings binding = context.getBindings(scope);
+            bindings.put(scope, binding == null ? new TreeMap<String,Object>() : new TreeMap<String,Object>(binding));
+        }
+        invocationList.add(new InvocationInfos(script,context));
+        if (bDebug) System.err.println(" | invocationList.size()=" + invocationList.size());
+        return invocationList;
+    }
+
+    public CompiledScript compile(Reader script) throws ScriptException {
+        return compile (readReader(script));
+    }
+
+    public CompiledScript compile(String script) throws ScriptException {
+        if (script.indexOf("FAIL COMPILATION") != -1) {
+                throw new ScriptException("test script contains FAIL COMPILATION");
+        }
+
+        String code = "RgfPseudoCompiledScript=[" + script + "]";
+        RgfPseudoCompiledScript rpcs = new RgfPseudoCompiledScript(code, this);
+        return rpcs;
+    }
+
+    String readReader(Reader reader) {
+        if (reader == null) {
+            return "";
+        }
+
+        BufferedReader bufferedReader = new BufferedReader(reader);
+        StringBuilder sb = new StringBuilder();
+        // caters for possible IOException in read() and close()
+        try {
+            try {
+                char[] charBuffer = new char[1024];
+                int r = 0;
+
+                while ((r = bufferedReader.read(charBuffer)) != -1) {
+                    sb.append(charBuffer, 0, r);
+                }
+            } finally {
+                bufferedReader.close();
+            }
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe.getMessage(), ioe);
+        }
+        return sb.toString();
+    }
+}
diff a/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoScriptEngineCompilableFactory.java b/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoScriptEngineCompilableFactory.java
--- /dev/null
+++ b/tests/system/src/testscriptapp2/java/mymod/pseudoScriptEngineCompilable/RgfPseudoScriptEngineCompilableFactory.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pseudoScriptEngineCompilable;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+import java.lang.StringBuilder;
+import java.util.Arrays;
+import java.util.List;
+
+
+public class RgfPseudoScriptEngineCompilableFactory implements ScriptEngineFactory {
+    static final String       ENGINE_NAME       = "RgfPseudoScriptLanguageCompilable (SQTMC) 1.0.0";
+    static final String       SHORT_ENGINE_NAME = "sqtmc";
+    static final String       ENGINE_VERSION    = "100.20200228";
+    static final List<String> EXTENSIONS        = Arrays.asList("sqtmc", "SQTMC");
+    static final String       LANGUAGE_NAME     = "RgfPseudoScriptLanguageCompilable";
+    static final String       LANGUAGE_VERSION  = "1.0.0.100.20200228";
+    static final List<String> MIME_TYPES        = Arrays.asList("text/sqtmc", "application/x-sqtmc");
+    static final String       THREADING         = "MULTITHREADED";
+    static final List<String> ENGINE_NAMES      = Arrays.asList(SHORT_ENGINE_NAME, "RgfPseudoSLCompilable");
+
+    public String getEngineName() {
+        return ENGINE_NAME;
+    }
+
+    public String getEngineVersion() {
+        return ENGINE_VERSION;
+    }
+
+    public List<String> getExtensions() {
+        return EXTENSIONS;
+    }
+
+    public String getLanguageName() {
+        return LANGUAGE_NAME;
+    }
+
+    public String getLanguageVersion() {
+        return LANGUAGE_VERSION;
+    }
+
+    public String getName() {
+        return ENGINE_NAME;
+    }
+
+    public String getMethodCallSyntax(String obj, String m, String... args) {
+        return "obj~(m, ...) /* ooRexx style */ ";
+    }
+
+    public List<String> getMimeTypes() {
+        return MIME_TYPES;
+    }
+
+    public List<String> getNames() {
+        return ENGINE_NAMES;
+    }
+
+    public String getOutputStatement(String toDisplay) {
+        String tmpDisplay = toStringLiteral(toDisplay);
+        return "say " + tmpDisplay + " /* Rexx style (duplicate quotes within string) */ ";
+    }
+
+    String toStringLiteral(String toDisplay) {
+        if (toDisplay == null) {
+            return "\"\"";
+        }
+        return '"' + toDisplay.replace("\"","\"\"") + '"';
+    }
+
+    public Object getParameter(final String key) {
+        switch (key) {
+            case "THREADING":
+                return THREADING;
+
+            case ScriptEngine.NAME:
+                return SHORT_ENGINE_NAME;
+
+            case ScriptEngine.ENGINE:
+                return ENGINE_NAME;
+
+            case ScriptEngine.ENGINE_VERSION:
+                return ENGINE_VERSION;
+
+            case ScriptEngine.LANGUAGE:
+                return LANGUAGE_NAME;
+
+            case ScriptEngine.LANGUAGE_VERSION:
+                 return LANGUAGE_VERSION;
+
+            default:
+                return null;
+        }
+    }
+
+    public String getProgram(String... statements) {
+        if (statements == null) {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < statements.length; i++) {
+            if (statements[i] == null) {
+                sb.append("\tsay 'null'; /* Rexx style */ \n");
+            }
+            else {
+                sb.append("\t" + statements[i] + ";\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    public ScriptEngine getScriptEngine() {
+        return new RgfPseudoScriptEngineCompilable();
+    }
+}
diff a/tests/system/src/testscriptapp2/resources/mymod/META-INF/services/javax.script.ScriptEngineFactory b/tests/system/src/testscriptapp2/resources/mymod/META-INF/services/javax.script.ScriptEngineFactory
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/META-INF/services/javax.script.ScriptEngineFactory
@@ -0,0 +1,1 @@
+pseudoScriptEngineCompilable.RgfPseudoScriptEngineCompilableFactory
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_bottomscript.sqtmc b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_bottomscript.sqtmc
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_bottomscript.sqtmc
@@ -0,0 +1,1 @@
+demo_02_bottomscript.sqtmc file - pseudo script in external file, starts with the filename
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_middlescript.sqtmc b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_middlescript.sqtmc
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_middlescript.sqtmc
@@ -0,0 +1,1 @@
+demo_02_middlescript.sqtmc file - pseudo script in external file, starts with the filename
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_off.fxml b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_off.fxml
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_off.fxml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-->
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.layout.AnchorPane?>
+
+<!-- line # 33 --> <?language sqtmc?> <!-- do NOT compile scripts because compile PI turns it off: --> <?compile false?>
+
+<AnchorPane fx:id="idRoot" prefHeight="240.0" prefWidth="480.0"
+            xmlns:fx="http://javafx.com/fxml/1">
+
+<!-- line # 38 -->     <fx:script source="demo_02_topscript.sqtmc" />
+
+                       <children>
+
+<!-- line # 42 -->         <Button fx:id="idButton" text="Press me!"
+                                   layoutX="210.0" layoutY="137.0"
+                                   onMouseClicked="demo_02_off.fxml embedded event - MouseClicked - line # 44 (PCDATA)"
+                                   onAction="demo_02_off.fxml embedded event - ActionEvent - line # 45 - LF entity (&amp;#10;) forces linebreak in attribute value: &#10;
+(this is on a new line) these characters in attribute values need to be escaped: &lt;, &gt;, &amp;, these if used as delimiters: &quot;, &apos; (PCDATA)" />
+
+<!-- line # 48 -->         <fx:script source="demo_02_middlescript.sqtmc" />
+
+                       </children>
+
+<!-- line # 52 -->     <fx:script>demo_02_off.fxml embedded script sqtmc - line # 52</fx:script>
+
+<!-- line # 54 -->     <fx:script source="demo_02_bottomscript.sqtmc" />
+
+<!-- line # 56 --> <fx:script>something (line # 56)(PCDATA)
+        in   a=&amp;b  (line # 57)
+        the  b&gt;1   (line # 58)
+        news c&lt;2   (line # 59) </fx:script>   <fx:script><![CDATA[demo_02_off.fxml (line # 59):
+CDATA-section ("<![CDATA[") allows any characters including <, > and & !! (no need to escape (line # 60)
+these special characters; it is plain CDATA which does not get processed, just passed on     (line # 61)
+including LF etc.                                                                            (line # 62)
+        in   a=&b  (line # 63)
+        the  b>1   (line # 64)
+        news c<2   (line # 65)
+Watch out that in the code there is no string that exactly matches the end tag               (line # 66)
+for a CDATA-section (close-square-bracket+close-square-bracket+greater-character             (line # 67) ]]></fx:script>
+
+</AnchorPane>
+
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_off_on.fxml b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_off_on.fxml
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_off_on.fxml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-->
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.layout.AnchorPane?>
+
+<!-- line # 33 --> <?language sqtmc?> <!-- set compiling off and on before each script, start out with off: -->  <?compile false?>
+
+<AnchorPane fx:id="idRoot" prefHeight="240.0" prefWidth="480.0"
+            xmlns:fx="http://javafx.com/fxml/1">
+
+<!-- line # 38 -->     <fx:script source="demo_02_topscript.sqtmc" />
+
+                       <children>
+<?compile true?>
+<!-- line # 42 -->         <Button fx:id="idButton" text="Press me!"
+                                   layoutX="210.0" layoutY="137.0"
+                                   onMouseClicked="demo_02_off_on.fxml embedded event - MouseClicked - line # 44 (PCDATA)"
+                                   onAction="demo_02_off_on.fxml embedded event - ActionEvent - line # 45 - LF entity (&amp;#10;) forces linebreak in attribute value: &#10;
+(this is on a new line) these characters in attribute values need to be escaped: &lt;, &gt;, &amp;, these if used as delimiters: &quot;, &apos; (PCDATA)" />
+<?compile false?>
+<!-- line # 48 -->         <fx:script source="demo_02_middlescript.sqtmc" />
+
+                       </children>
+
+<!-- line # 52 -->     <fx:script>demo_02_off_on.fxml embedded script sqtmc - line # 52</fx:script>
+<?compile true?>
+<!-- line # 54 -->     <fx:script source="demo_02_bottomscript.sqtmc" />
+<?compile false?>
+<!-- line # 56 --> <fx:script>something (line # 56)(PCDATA)
+        in   a=&amp;b  (line # 57)
+        the  b&gt;1   (line # 58)
+        news c&lt;2   (line # 59) </fx:script> <?compile true?>  <fx:script><![CDATA[demo_02_off_on.fxml (line # 59):
+CDATA-section ("<![CDATA[") allows any characters including <, > and & !! (no need to escape (line # 60)
+these special characters; it is plain CDATA which does not get processed, just passed on     (line # 61)
+including LF etc.                                                                            (line # 62)
+        in   a=&b  (line # 63)
+        the  b>1   (line # 64)
+        news c<2   (line # 65)
+Watch out that in the code there is no string that exactly matches the end tag               (line # 66)
+for a CDATA-section (close-square-bracket+close-square-bracket+greater-character             (line # 67) ]]></fx:script>
+
+</AnchorPane>
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_on.fxml b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_on.fxml
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_on.fxml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-->
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.layout.AnchorPane?>
+
+<!-- line # 33 --> <?language sqtmc?> <!-- compile scripts by default, no need to supply the compile PI -->
+
+<AnchorPane fx:id="idRoot" prefHeight="240.0" prefWidth="480.0"
+            xmlns:fx="http://javafx.com/fxml/1">
+
+<!-- line # 38 -->     <fx:script source="demo_02_topscript.sqtmc" />
+
+                       <children>
+
+<!-- line # 42 -->         <Button fx:id="idButton" text="Press me!"
+                                   layoutX="210.0" layoutY="137.0"
+                                   onMouseClicked="demo_02_on.fxml embedded event - MouseClicked - line # 44 (PCDATA)"
+                                   onAction="demo_02_on.fxml embedded event - ActionEvent - line # 45 - LF entity (&amp;#10;) forces linebreak in attribute value: &#10;
+(this is on a new line) these characters in attribute values need to be escaped: &lt;, &gt;, &amp;, these if used as delimiters: &quot;, &apos; (PCDATA)" />
+
+<!-- line # 48 -->         <fx:script source="demo_02_middlescript.sqtmc" />
+
+                       </children>
+
+<!-- line # 52 -->     <fx:script>demo_02_on.fxml embedded script sqtmc - line # 52</fx:script>
+
+<!-- line # 54 -->     <fx:script source="demo_02_bottomscript.sqtmc" />
+
+<!-- line # 56 --> <fx:script>something (line # 56)(PCDATA)
+        in   a=&amp;b  (line # 57)
+        the  b&gt;1   (line # 58)
+        news c&lt;2   (line # 59) </fx:script>   <fx:script><![CDATA[demo_02_on.fxml (line # 59):
+CDATA-section ("<![CDATA[") allows any characters including <, > and & !! (no need to escape (line # 60)
+these special characters; it is plain CDATA which does not get processed, just passed on     (line # 61)
+including LF etc.                                                                            (line # 62)
+        in   a=&b  (line # 63)
+        the  b>1   (line # 64)
+        news c<2   (line # 65)
+Watch out that in the code there is no string that exactly matches the end tag               (line # 66)
+for a CDATA-section (close-square-bracket+close-square-bracket+greater-character             (line # 67) ]]></fx:script>
+
+</AnchorPane>
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_on_off.fxml b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_on_off.fxml
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_on_off.fxml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-->
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.layout.AnchorPane?>
+
+<!-- line # 33 --> <?language sqtmc?> <!-- set compiling on and off before each script, start out with on: -->  <?compile true?>
+
+<AnchorPane fx:id="idRoot" prefHeight="240.0" prefWidth="480.0"
+            xmlns:fx="http://javafx.com/fxml/1">
+
+<!-- line # 38 -->     <fx:script source="demo_02_topscript.sqtmc" />
+
+                       <children>
+<?compile false?>
+<!-- line # 42 -->         <Button fx:id="idButton" text="Press me!"
+                                   layoutX="210.0" layoutY="137.0"
+                                   onMouseClicked="demo_02_on_off.fxml embedded event - MouseClicked - line # 44 (PCDATA)"
+                                   onAction="demo_02_on_off.fxml embedded event - ActionEvent - line # 45 - LF entity (&amp;#10;) forces linebreak in attribute value: &#10;
+(this is on a new line) these characters in attribute values need to be escaped: &lt;, &gt;, &amp;, these if used as delimiters: &quot;, &apos; (PCDATA)" />
+<?compile true?>
+<!-- line # 48 -->         <fx:script source="demo_02_middlescript.sqtmc" />
+
+                       </children>
+<?compile false?>
+<!-- line # 52 -->     <fx:script>demo_02_on_off.fxml embedded script sqtmc - line # 52</fx:script>
+<?compile?>
+<!-- line # 54 -->     <fx:script source="demo_02_bottomscript.sqtmc" />
+<?compile false?>
+<!-- line # 56 --> <fx:script>something (line # 56)(PCDATA)
+        in   a=&amp;b  (line # 57)
+        the  b&gt;1   (line # 58)
+        news c&lt;2   (line # 59) </fx:script> <?compile true?>  <fx:script><![CDATA[demo_02_on_off.fxml (line # 59):
+CDATA-section ("<![CDATA[") allows any characters including <, > and & !! (no need to escape (line # 60)
+these special characters; it is plain CDATA which does not get processed, just passed on     (line # 61)
+including LF etc.                                                                            (line # 62)
+        in   a=&b  (line # 63)
+        the  b>1   (line # 64)
+        news c<2   (line # 65)
+Watch out that in the code there is no string that exactly matches the end tag               (line # 66)
+for a CDATA-section (close-square-bracket+close-square-bracket+greater-character             (line # 67) ]]></fx:script>
+
+</AnchorPane>
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_topscript.sqtmc b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_topscript.sqtmc
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_topscript.sqtmc
@@ -0,0 +1,1 @@
+demo_02_topscript.sqtmc file - pseudo script in external file, starts with the filename
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_bottomscript.sqtmc b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_bottomscript.sqtmc
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_bottomscript.sqtmc
@@ -0,0 +1,2 @@
+demo_03_bottomscript.sqtmc file - pseudo script in external file, starts with the filename
+FAIL COMPILATION
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_fail_compile.fxml b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_fail_compile.fxml
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_fail_compile.fxml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-->
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.layout.AnchorPane?>
+
+<!-- line # 33 --> <?language sqtmc?> <!-- make sure compiling is set to on: -->  <?compile true?>
+
+<AnchorPane fx:id="idRoot" prefHeight="240.0" prefWidth="480.0"
+            xmlns:fx="http://javafx.com/fxml/1">
+
+<!-- line # 38 -->     <fx:script source="demo_03_topscript.sqtmc" />
+
+                       <children>
+
+<!-- line # 42 -->         <Button fx:id="idButton" text="Press me!"
+                                   layoutX="210.0" layoutY="137.0"
+                                   onMouseClicked="demo_03_fail_compile.fxml embedded event - MouseClicked - line # 44 (PCDATA) FAIL COMPILATION"
+                                   onAction="demo_03_fail_compile.fxml embedded event - ActionEvent - line # 45 - LF entity (&amp;#10;) forces linebreak in attribute value: &#10;
+(this is on a new line) these characters in attribute values need to be escaped: &lt;, &gt;, &amp;, these if used as delimiters: &quot;, &apos; (PCDATA) FAIL COMPILATION" />
+
+<!-- line # 48 -->         <fx:script source="demo_03_middlescript.sqtmc" />
+
+                       </children>
+
+<!-- line # 52 -->     <fx:script>demo_03_fail_compile.fxml embedded script sqtmc - line # 52 - FAIL COMPILATION</fx:script>
+
+<!-- line # 54 -->     <fx:script source="demo_03_bottomscript.sqtmc" />
+
+<!-- line # 56 --> <fx:script>something (line # 56)(PCDATA)
+        in   a=&amp;b  (line # 57)
+        the  b&gt;1   (line # 58)
+        news c&lt;2   (line # 59) FAIL COMPILATION</fx:script>  <fx:script><![CDATA[demo_03_fail_compile.fxml (line # 59):
+CDATA-section ("<![CDATA[") allows any characters including <, > and & !! (no need to escape (line # 60) FAIL COMPILATION
+these special characters; it is plain CDATA which does not get processed, just passed on     (line # 61)
+including LF etc.                                                                            (line # 62)
+        in   a=&b  (line # 63)
+        the  b>1   (line # 64)
+        news c<2   (line # 65)
+Watch out that in the code there is no string that exactly matches the end tag               (line # 66)
+for a CDATA-section (close-square-bracket+close-square-bracket+greater-character             (line # 67) ]]></fx:script>
+
+</AnchorPane>
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_middlescript.sqtmc b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_middlescript.sqtmc
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_middlescript.sqtmc
@@ -0,0 +1,2 @@
+demo_03_middlescript.sqtmc file - pseudo script in external file, starts with the filename
+FAIL COMPILATION
diff a/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_topscript.sqtmc b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_topscript.sqtmc
--- /dev/null
+++ b/tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_topscript.sqtmc
@@ -0,0 +1,2 @@
+demo_03_topscript.sqtmc file - pseudo script in external file, starts with the filename
+FAIL COMPILATION
