changeset 5010:1f9bb8fd4c51 8.0-b107

Merge
author ngthomas
date Tue, 10 Sep 2013 14:12:43 -0700
parents 52f7abe54d41 7c4ead19a131
children 7007eeeaa0e8 80183062bb60 7bae615fd3e2
files build.gradle modules/fxml/src/main/java/com/sun/javafx/fxml/ObservableListChangeEvent.java modules/fxml/src/main/java/com/sun/javafx/fxml/ObservableMapChangeEvent.java modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java.jfx78 modules/graphics/src/main/native-prism-d3d/D3DWindow.cc modules/web/src/main/java/com/sun/javafx/webkit/PolicyClientImpl.java modules/web/src/main/native/Source/WebCore/storage/java/StorageAreaJava.cpp modules/web/src/main/native/Source/WebCore/storage/java/StorageAreaJava.h modules/web/src/main/native/Source/WebCore/storage/java/StorageNamespaceJava.cpp modules/web/src/main/native/Source/WebCore/storage/java/StorageNamespaceJava.h tests/app-lifecycle/LauncherTests/build.xml tests/app-lifecycle/LauncherTests/manifest.mf tests/app-lifecycle/LauncherTests/nbproject/build-impl.xml tests/app-lifecycle/LauncherTests/nbproject/genfiles.properties tests/app-lifecycle/LauncherTests/nbproject/project.properties tests/app-lifecycle/LauncherTests/nbproject/project.xml tests/app-lifecycle/LauncherTests/test/launchertest/Constants.java tests/app-lifecycle/LauncherTests/test/launchertest/MainLauncherTest.java tests/app-lifecycle/LauncherTests/test/launchertest/TestApp.java tests/app-lifecycle/LauncherTests/test/launchertest/TestAppNoMain.java tests/app-lifecycle/LauncherTests/test/launchertest/TestNotApplication.java tests/app-lifecycle/LifeCycleTests/build.xml tests/app-lifecycle/LifeCycleTests/manifest.mf tests/app-lifecycle/LifeCycleTests/nbproject/build-impl.xml tests/app-lifecycle/LifeCycleTests/nbproject/genfiles.properties tests/app-lifecycle/LifeCycleTests/nbproject/project.properties tests/app-lifecycle/LifeCycleTests/nbproject/project.xml tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/ListenerError1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/ListenerError2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/ListenerException1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/ListenerException2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/ListenerExitTest.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/ListenerIdle1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/ListenerIdle2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/ListenerTestCommon.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitCommon.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitExplicit1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitExplicit2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitExplicitError1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitExplicitError2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitExplicitException1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitExplicitException2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitImplicitErrorTest.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitImplicitExceptionTest.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleExitImplicitTest.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowExplicit1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowExplicit2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowExplicitError1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowExplicitError2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowExplicitException1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowExplicitException2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowImplicitErrorTest.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowImplicitExceptionTest.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SingleNoShowImplicitTest.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SwingExitCommon.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SwingExitExplicit1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SwingExitExplicit2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/SwingExitImplicitTest.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/TaskbarApp1Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/TaskbarApp2Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/TaskbarApp3Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/TaskbarApp4Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/TaskbarApp5Test.java tests/app-lifecycle/LifeCycleTests/test/com/sun/javafx/application/TaskbarAppCommon.java tests/app-lifecycle/LifeCycleTests/test/javafx/stage/ShowAndWaitTest.java tests/app-lifecycle/LifeCycleTests/test/util/Util.java tests/app-lifecycle/build.xml tests/base.properties tests/build-defs.xml tests/build.xml tests/common.properties tests/glass/ExceptionHandler/build.xml tests/glass/ExceptionHandler/test/com/sun/glass/ui/DefaultExceptionHandlerTest.java tests/glass/ExceptionHandler/test/com/sun/glass/ui/ExceptionHandlerTest.java tests/glass/build.xml tests/graphics/MaterialTests/build.xml tests/graphics/MaterialTests/manifest.mf tests/graphics/MaterialTests/nbproject/build-impl.xml tests/graphics/MaterialTests/nbproject/genfiles.properties tests/graphics/MaterialTests/nbproject/project.properties tests/graphics/MaterialTests/nbproject/project.xml tests/graphics/MaterialTests/test/com/sun/javafx/sg/prism/NGHelper.java tests/graphics/MaterialTests/test/com/sun/prism/es2/ES2Helper.java tests/graphics/MaterialTests/test/javafx/scene/PhongMaterialTest.java tests/graphics/SnapshotTests/build.xml tests/graphics/SnapshotTests/manifest.mf tests/graphics/SnapshotTests/nbproject/build-impl.xml tests/graphics/SnapshotTests/nbproject/genfiles.properties tests/graphics/SnapshotTests/nbproject/project.properties tests/graphics/SnapshotTests/nbproject/project.xml tests/graphics/SnapshotTests/test/javafx/scene/Snapshot1Test.java tests/graphics/SnapshotTests/test/javafx/scene/Snapshot2Test.java tests/graphics/SnapshotTests/test/javafx/scene/SnapshotCommon.java tests/graphics/SnapshotTests/test/util2/Util.java tests/graphics/SwingInterop/build.xml tests/graphics/SwingInterop/nbproject/build-impl.xml tests/graphics/SwingInterop/nbproject/genfiles.properties tests/graphics/SwingInterop/nbproject/project.properties tests/graphics/SwingInterop/nbproject/project.xml tests/graphics/SwingInterop/test/javafx/embed/swing/RT23603Test.java tests/graphics/SwingInterop/test/javafx/embed/swing/RT30650GUI.java tests/graphics/SwingInterop/test/javafx/embed/swing/RT30650Test.java tests/graphics/TextTests/build.xml tests/graphics/TextTests/manifest.mf tests/graphics/TextTests/nbproject/build-impl.xml tests/graphics/TextTests/nbproject/genfiles.properties tests/graphics/TextTests/nbproject/project.properties tests/graphics/TextTests/nbproject/project.xml tests/graphics/TextTests/test/javafx/scene/text/TextNodeTest.java tests/graphics/build.xml tests/quantum/CloseWindow/build.xml tests/quantum/CloseWindow/test/com/sun/javafx/tk/quantum/CloseWindowTest.java tests/quantum/WindowSceneInitDispose/build.xml tests/quantum/WindowSceneInitDispose/test/com/sun/javafx/tk/quantum/WindowSceneInitDisposeTest.java tests/quantum/build.xml
diffstat 335 files changed, 12587 insertions(+), 17388 deletions(-) [+]
line wrap: on
line diff
--- a/build.gradle	Fri Sep 06 13:22:16 2013 -0700
+++ b/build.gradle	Tue Sep 10 14:12:43 2013 -0700
@@ -309,6 +309,10 @@
 defineProperty("COMPILE_PANGO", "false")
 if (COMPILE_PANGO instanceof String) ext.COMPILE_PANGO = Boolean.parseBoolean(COMPILE_PANGO)
 
+// COMPILE_PARFAIT specifies whether to build parfait
+defineProperty("COMPILE_PARFAIT", "false")
+if (COMPILE_PARFAIT instanceof String) ext.COMPILE_PARFAIT = Boolean.parseBoolean(COMPILE_PARFAIT)
+
 
 // Define the SWT.jar that we are going to have to download during the build process based
 // on what platform we are compiling from (not based on our target).
@@ -325,6 +329,13 @@
 }
 ext.BUILD_JAVADOC = buildJavadoc;
 
+// Specifies whether to run full tests (true) or smoke tests (false)
+def isFullTest = false;
+if (hasProperty("FULL_TEST")) {
+    isFullTest = Boolean.parseBoolean(FULL_TEST);
+}
+ext.IS_FULL_TEST = isFullTest;
+
 // Specify the build configuration (Release or Debug)
 defineProperty("CONF", "Release")
 ext.IS_DEBUG = CONF == "Debug"
@@ -1411,6 +1422,20 @@
     }
 }
 
+// This project is for system tests that need to run with a full SDK.
+// Most of them display a stage or do other things that preclude running
+// them in a shared JVM or as part of the "smoke test" run (which must
+// not pop up any windows or use audio). As such, they are only enabled
+// when FULL_TEST is specified, and each test runs in its own JVM
+project(":systemTests") {
+    def sdkDir = "build/${defaultHostTarget}-sdk"
+    test {
+        enabled = IS_FULL_TEST
+        forkEvery = 1
+        classpath = files("$sdkDir/rt/lib/ext/jfxrt.jar") + classpath
+    }
+}
+
 project(":fxpackager") {
     tasks.all {
         if (!COMPILE_FXPACKAGER) it.enabled = false
@@ -1677,6 +1702,7 @@
     }
 }
 
+
 task javadoc(type: Javadoc) {
     enabled = BUILD_JAVADOC
     group = "Basic"
@@ -1714,7 +1740,10 @@
     dependsOn(projectsToDocument.collect { project -> project.getTasksByName("classes", true)});
 }
 
-task jfxrt()
+task jfxrt() {
+    def t = project(":systemTests").test
+    if (t.enabled) t.dependsOn(jfxrt)
+}
 
 task sdk() {
     dependsOn(checkJfxrtJar)
@@ -1729,16 +1758,6 @@
     dependsOn(copyAppsArtifacts)
 }
 
-task fullTest() {
-// TODO: WHY DOES THE FOLLOWING NOT WORK???
-//    dependsOn(test)
-
-    // TODO additional tests
-    doLast {
-        println "fullTest task is not implemented"
-    }
-}
-
 task findbugs() {
     dependsOn(sdk)
 
@@ -2137,8 +2156,9 @@
                 workingDir("$projectDir/src/main/native")
                 if (t.name == "win") {
                     String qtDir = cygpath(System.getenv().get("QTSDK_DIR"))
+                    String parfaitPath = COMPILE_PARFAIT ? System.getenv().get("PARFAIT_PATH") + ";" : "";
                     Map environmentSettings = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
-                    environmentSettings["PATH"] = "$WINDOWS_VS_PATH;$qtDir/bin;$qtDir/qt/bin"
+                    environmentSettings["PATH"] = parfaitPath + "$WINDOWS_VS_PATH;$qtDir/bin;$qtDir/qt/bin"
                     environmentSettings["QMAKESPEC"] = "win32-msvc2008"
                     environment(environmentSettings)
                     /* To build with ICU:
@@ -2187,6 +2207,19 @@
                     "JAVA_HOME"       : JAVA_HOME,
                     "WEBKITOUTPUTDIR" : webkitOutputDir,
                 ])
+
+                if (COMPILE_PARFAIT) {
+                    environment([
+                        "CC"        : "parfait-gcc",
+                        "QMAKE_CC"  : "parfait-gcc",
+                        "CXX"       : "parfait-g++",
+                        "QMAKE_CXX" : "parfait-g++",
+                        "CPP"       : "parfait-g++",
+                        "cc"        : "parfait-gcc",
+                        "LINK"      : "parfait-g++",
+                        "QMAKE_LINK": "parfait-g++",
+                    ])
+                }
                 commandLine("perl", "Tools/Scripts/build-webkit", "--java", "--imageio")
             }
 
--- a/buildSrc/genVSproperties.bat	Fri Sep 06 13:22:16 2013 -0700
+++ b/buildSrc/genVSproperties.bat	Tue Sep 10 14:12:43 2013 -0700
@@ -80,7 +80,7 @@
 echo windows.vs.INCLUDE=%INCLUDE%@@ENDOFLINE@@
 echo windows.vs.LIB=%LIB%@@ENDOFLINE@@
 echo windows.vs.LIBPATH=%LIBPATH%@@ENDOFLINE@@
-echo windows.vs.PATH=%PATH%@@ENDOFLINE@@
+echo windows.vs.PATH=%PARFAIT_PATH%;%PATH%@@ENDOFLINE@@
 echo windows.vs.VER=%VSVER%@@ENDOFLINE@@
 echo WINDOWS_SDK_DIR=%WindowsSdkDir%@@ENDOFLINE@@
 echo ############################################################
--- a/buildSrc/ios.gradle	Fri Sep 06 13:22:16 2013 -0700
+++ b/buildSrc/ios.gradle	Tue Sep 10 14:12:43 2013 -0700
@@ -27,7 +27,7 @@
 
 if (BUILD_CLOSED) {
     fetchExternalTools('IOS', 
-      ["ios-libs-06.tgz"], 
+      ["ios-libs-07.tgz"], 
       rootProject.CROSS_TOOLS_DIR, rootProject.IMPORT_CROSS_TOOLS)
 }
 
--- a/buildSrc/linux.gradle	Fri Sep 06 13:22:16 2013 -0700
+++ b/buildSrc/linux.gradle	Tue Sep 10 14:12:43 2013 -0700
@@ -128,9 +128,9 @@
     }
 )
 
-
-def compiler = "gcc"
-def linker = "g++"
+def compiler = COMPILE_PARFAIT ? "parfait-gcc" : "gcc";
+def cc_compiler = COMPILE_PARFAIT ? "parfait-cc" : "cc";
+def linker = COMPILE_PARFAIT ? "parfait-g++" : "g++";
 
 LINUX.glass = [:]
 LINUX.glass.javahInclude = [
@@ -155,7 +155,7 @@
 LINUX.prism = [:]
 LINUX.prism.javahInclude = ["com/sun/prism/impl/**/*", "com/sun/prism/PresentableState*"]
 LINUX.prism.nativeSource = file("modules/graphics/src/main/native-prism")
-LINUX.prism.compiler = "cc"
+LINUX.prism.compiler = cc_compiler
 LINUX.prism.ccFlags = [ccFlags, "-DINLINE=inline"].flatten()
 LINUX.prism.linker = linker
 LINUX.prism.linkFlags = [linkFlags].flatten()
@@ -164,7 +164,7 @@
 LINUX.prismSW = [:]
 LINUX.prismSW.javahInclude = ["com/sun/pisces/**/*"]
 LINUX.prismSW.nativeSource = file("modules/graphics/src/main/native-prism-sw")
-LINUX.prismSW.compiler = "cc"
+LINUX.prismSW.compiler = cc_compiler
 LINUX.prismSW.ccFlags = [ccFlags, "-DINLINE=inline"].flatten()
 LINUX.prismSW.linker = linker
 LINUX.prismSW.linkFlags = [linkFlags].flatten()
--- a/buildSrc/mac.gradle	Fri Sep 06 13:22:16 2013 -0700
+++ b/buildSrc/mac.gradle	Tue Sep 10 14:12:43 2013 -0700
@@ -91,8 +91,9 @@
         commonParams,
         IS_DEBUG ? "-DDEBUG" : ["-O3", "-DNDEBUG"]].flatten()
 
-def compiler = "gcc"
-def linker = "g++"
+def compiler = COMPILE_PARFAIT ? "parfait-gcc" : "gcc";
+def cc_compiler = COMPILE_PARFAIT ? "parfait-cc" : "cc";
+def linker = COMPILE_PARFAIT ? "parfait-g++" : "g++";
 
 MAC.glass = [:]
 MAC.glass.javahInclude = [
@@ -123,7 +124,7 @@
 MAC.prism = [:]
 MAC.prism.javahInclude = ["com/sun/prism/impl/**/*", "com/sun/prism/PresentableState*"]
 MAC.prism.nativeSource = file("modules/graphics/src/main/native-prism")
-MAC.prism.compiler = "cc"
+MAC.prism.compiler = cc_compiler
 MAC.prism.ccFlags = ["-O3", "-DINLINE=inline",
         "-I$JDK_HOME/include",
         "-I$JDK_HOME/include/darwin",
@@ -138,7 +139,7 @@
 MAC.prismSW = [:]
 MAC.prismSW.javahInclude = ["com/sun/pisces/**/*"]
 MAC.prismSW.nativeSource = file("modules/graphics/src/main/native-prism-sw")
-MAC.prismSW.compiler = "cc"
+MAC.prismSW.compiler = cc_compiler
 MAC.prismSW.ccFlags = [MAC.prism.ccFlags].flatten()
 MAC.prismSW.linker = linker
 MAC.prismSW.linkFlags = [MAC.prism.linkFlags].flatten()
--- a/buildSrc/src/main/groovy/com/sun/javafx/gradle/LinkTask.groovy	Fri Sep 06 13:22:16 2013 -0700
+++ b/buildSrc/src/main/groovy/com/sun/javafx/gradle/LinkTask.groovy	Tue Sep 10 14:12:43 2013 -0700
@@ -39,7 +39,8 @@
         lib.getParentFile().mkdirs();
         project.exec({
             commandLine(linker);
-            args(objectDir.listFiles());
+            // Exclude parfait files (.bc)
+            args(objectDir.listFiles().findAll{ !it.getAbsolutePath().endsWith(".bc") });
             if (project.IS_WINDOWS) {
                 args("/out:$lib");
             } else {
--- a/buildSrc/win.gradle	Fri Sep 06 13:22:16 2013 -0700
+++ b/buildSrc/win.gradle	Tue Sep 10 14:12:43 2013 -0700
@@ -103,7 +103,8 @@
         defineProperty("WINDOWS_VS_VER", properties, "70")
         defineProperty("WINDOWS_VS_LIB", properties, "$WINDOWS_VS_VCINSTALLDIR/LIB;" + "$WINDOWS_SDK_DIR/lib;")
         defineProperty("WINDOWS_VS_LIBPATH", properties, "$WINDOWS_VS_VCINSTALLDIR/LIB;")
-        defineProperty("WINDOWS_VS_PATH", properties, "$WINDOWS_VS_DEVENVDIR;" +
+        def parfaitPath = COMPILE_PARFAIT ? System.getenv().get("PARFAIT_PATH") + ";" : "";
+        defineProperty("WINDOWS_VS_PATH", properties, parfaitPath + "$WINDOWS_VS_DEVENVDIR;" +
                 "$WINDOWS_VS_VSINSTALLDIR/VC/BIN;" +
                 "$WINDOWS_VS_VSINSTALLDIR/Common7/Tools;" +
                 "$WINDOWS_VS_VCINSTALLDIR/VCPackages;" +
@@ -128,8 +129,8 @@
 String msvcBinDir = (IS_64
                   ? "$WINDOWS_VS_VSINSTALLDIR/VC/BIN/amd64"
                   : "$WINDOWS_VS_VSINSTALLDIR/VC/BIN")
-def compiler = cygpath("$msvcBinDir/cl.exe")
-def linker = cygpath("$msvcBinDir/link.exe")
+def compiler = COMPILE_PARFAIT ? "cl.exe" : cygpath("$msvcBinDir/cl.exe")
+def linker = COMPILE_PARFAIT ? "link.exe" : cygpath("$msvcBinDir/link.exe")
 ext.RC = cygpath("$WINDOWS_SDK_DIR/Bin/RC.Exe")
 ext.FXC = cygpath("$WINDOWS_DXSDK_DIR/utilities/bin/x86/fxc.exe")
 ext.MC = cygpath("$WINDOWS_SDK_DIR/Bin/mt.exe")
--- a/gradle.properties.template	Fri Sep 06 13:22:16 2013 -0700
+++ b/gradle.properties.template	Tue Sep 10 14:12:43 2013 -0700
@@ -46,6 +46,12 @@
 
 #BUILD_JAVADOC = true
 
+# Specifies whether to do a full test run or a "smoke test" run. By default we
+# do a smoke test run which excludes all tests that show a window or play media.
+# Certain long running tests might also be excluded when this is not set.
+
+#FULL_TEST = true
+
 # Specify the COMPILE_TARGETS when performing cross compiles. A Cross-Compile is
 # when you build for a platform other than the one you are building on. For example,
 # to build for Apple iOS, you would specify ios as one of the COMPILE_TARGETS.
--- a/modules/base/src/main/java/com/sun/javafx/binding/SelectBinding.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/base/src/main/java/com/sun/javafx/binding/SelectBinding.java	Tue Sep 10 14:12:43 2013 -0700
@@ -94,7 +94,7 @@
                 return null;
             }
             try {
-                return (T)helper.getObservableValue().getValue();
+                return (T)observable.getValue();
             } catch (ClassCastException ex) {
                 Logging.getLogger().warning("Value of select-binding has wrong type, returning null.", ex);
             }
--- a/modules/base/src/main/java/javafx/beans/property/ReadOnlySetProperty.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/base/src/main/java/javafx/beans/property/ReadOnlySetProperty.java	Tue Sep 10 14:12:43 2013 -0700
@@ -133,7 +133,7 @@
     @Override
     public int hashCode() {
         int h = 0;
-        for (E e : get()) {
+        for (E e : this) {
             if (e != null)
                 h += e.hashCode();
         }
--- a/modules/base/src/main/java/javafx/event/EventType.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/base/src/main/java/javafx/event/EventType.java	Tue Sep 10 14:12:43 2013 -0700
@@ -225,7 +225,7 @@
         
         private EventType findSubType(Set<EventType> subTypes, String name) {
             for (EventType t : subTypes) {
-                if (((t.name == null && name == null) || (t != null && t.name.equals(name)))) {
+                if (((t.name == null && name == null) || (t.name != null && t.name.equals(name)))) {
                     return t;
                 }
             }
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/AccordionSkin.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/AccordionSkin.java	Tue Sep 10 14:12:43 2013 -0700
@@ -238,6 +238,9 @@
                     expandedPane = getSkinnable().getExpandedPane();
                     getSkinnable().setExpandedPane(null);
                 }
+
+                // added to resolve RT-32787
+                previousHeight = 0;
             }
         };
     }
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Tue Sep 10 14:12:43 2013 -0700
@@ -476,12 +476,8 @@
         } else {
             // run item through StringConverter if it isn't null
             StringConverter<T> c = comboBox.getConverter();
-            
-            // prompt text used to be displayed in the display text of a 
-            // non-editable node, but was removed as per RT-29284
-            String s = item == null ? /*comboBox.getPromptText()*/"" : (c == null ? item.toString() : c.toString(item));
+            String s = item == null ? comboBox.getPromptText() : (c == null ? item.toString() : c.toString(item));
             cell.setText(s);
-            
             cell.setGraphic(null);
             return s == null || s.isEmpty();
         }
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ProgressIndicatorSkin.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ProgressIndicatorSkin.java	Tue Sep 10 14:12:43 2013 -0700
@@ -528,64 +528,66 @@
         static final private Duration UNCLIPPED_DELAY = new Duration(0);
 
         private void rebuildTimeline() {
-            final ObservableList<KeyFrame> keyFrames = FXCollections.<KeyFrame>observableArrayList();
-            keyFrames.add(
-              new KeyFrame(
-                Duration.millis(0), new EventHandler<ActionEvent>() {
-                  @Override public void handle(ActionEvent event) {
-                      /**
-                       * Stop the animation if the ProgressBar is removed
-                       * from a Scene, or is invisible.
-                       * Pause the animation if it's outside of a clipped
-                       * region (e.g. not visible in a ScrollPane)
-                       */
-                      if (indeterminateTimeline != null) {
-                          stopIfInvisibleOrDisconnected();
-                          if (!isVisibleInClip()) {
-                              Platform.runLater(new Runnable() {
-                                @Override public void run() {
-                                    if (indeterminateTimeline != null) {
-                                        if (indeterminateTimeline.getDelay().compareTo(CLIPPED_DELAY) != 0) {
-                                            indeterminateTimeline.setDelay(CLIPPED_DELAY);
-                                        }
-                                        indeterminateTimeline.stop();
-                                        indeterminateTimeline.jumpTo(Duration.ZERO);
-                                        indeterminateTimeline.play();
-                                    }
-                                }
-                              });
-                          }
-                          else {
-                              Platform.runLater(new Runnable() {
-                                @Override public void run() {
-                                    if (indeterminateTimeline != null) {
-                                        if (indeterminateTimeline.getDelay().compareTo(UNCLIPPED_DELAY) != 0) {
-                                            indeterminateTimeline.setDelay(UNCLIPPED_DELAY);
+            if (indeterminateTimeline != null) {
+                final ObservableList<KeyFrame> keyFrames = FXCollections.<KeyFrame>observableArrayList();
+                keyFrames.add(
+                  new KeyFrame(
+                    Duration.millis(0), new EventHandler<ActionEvent>() {
+                      @Override public void handle(ActionEvent event) {
+                          /**
+                           * Stop the animation if the ProgressBar is removed
+                           * from a Scene, or is invisible.
+                           * Pause the animation if it's outside of a clipped
+                           * region (e.g. not visible in a ScrollPane)
+                           */
+                          if (indeterminateTimeline != null) {
+                              stopIfInvisibleOrDisconnected();
+                              if (!isVisibleInClip()) {
+                                  Platform.runLater(new Runnable() {
+                                    @Override public void run() {
+                                        if (indeterminateTimeline != null) {
+                                            if (indeterminateTimeline.getDelay().compareTo(CLIPPED_DELAY) != 0) {
+                                                indeterminateTimeline.setDelay(CLIPPED_DELAY);
+                                            }
+                                            indeterminateTimeline.stop();
+                                            indeterminateTimeline.jumpTo(Duration.ZERO);
+                                            indeterminateTimeline.play();
                                         }
                                     }
-                                }
-                              });
+                                  });
+                              }
+                              else {
+                                  Platform.runLater(new Runnable() {
+                                    @Override public void run() {
+                                        if (indeterminateTimeline != null) {
+                                            if (indeterminateTimeline.getDelay().compareTo(UNCLIPPED_DELAY) != 0) {
+                                                indeterminateTimeline.setDelay(UNCLIPPED_DELAY);
+                                            }
+                                        }
+                                    }
+                                  });
+                              }
                           }
                       }
-                  }
-                }));
-            if(spinEnabled) {
-                keyFrames.add(new KeyFrame(Duration.millis(1), new KeyValue(pathsG.rotateProperty(), 360)));
-                keyFrames.add(new KeyFrame(Duration.millis(3900), new KeyValue(pathsG.rotateProperty(), 0)));
+                    }));
+                if(spinEnabled) {
+                    keyFrames.add(new KeyFrame(Duration.millis(1), new KeyValue(pathsG.rotateProperty(), 360)));
+                    keyFrames.add(new KeyFrame(Duration.millis(3900), new KeyValue(pathsG.rotateProperty(), 0)));
+                }
+
+                for (int i = 100; i <= 3900; i += 100) {
+                    keyFrames.add(
+                            new KeyFrame(
+                                    Duration.millis(i), new EventHandler<ActionEvent>() {
+                                @Override public void handle(ActionEvent event) {
+                                    shiftColors();
+                                }
+                            }));
+                }
+                indeterminateTimeline.stop();
+                indeterminateTimeline.getKeyFrames().setAll(keyFrames);
+                indeterminateTimeline.playFromStart();
             }
-
-            for (int i = 100; i <= 3900; i += 100) {
-                keyFrames.add(
-                        new KeyFrame(
-                                Duration.millis(i), new EventHandler<ActionEvent>() {
-                            @Override public void handle(ActionEvent event) {
-                                shiftColors();
-                            }
-                        }));
-            }
-            indeterminateTimeline.stop();
-            indeterminateTimeline.getKeyFrames().setAll(keyFrames);
-            indeterminateTimeline.playFromStart();
         }
 
         private void pauseIndicator(boolean pause) {
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ScrollBarSkin.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ScrollBarSkin.java	Tue Sep 10 14:12:43 2013 -0700
@@ -329,9 +329,11 @@
         super.handleControlPropertyChanged(p);
         if ("ORIENTATION".equals(p)) {
             getSkinnable().requestLayout();
-        } else if ("MIN".equals(p) || "MAX".equals(p) || "VALUE".equals(p) || "VISIBLE_AMOUNT".equals(p)) {
+        } else if ("MIN".equals(p) || "MAX".equals(p) || "VISIBLE_AMOUNT".equals(p)) {
             positionThumb();
             getSkinnable().requestLayout();
+        } else if ("VALUE".equals(p)) {
+            positionThumb();
         }
     }
 
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ScrollPaneSkin.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ScrollPaneSkin.java	Tue Sep 10 14:12:43 2013 -0700
@@ -150,9 +150,15 @@
                     (scrollNode.getLayoutBounds().getHeight() != 0.0 && nodeHeight != scrollNode.getLayoutBounds().getHeight())) {
                     getSkinnable().requestLayout();
                 } else {
-                    // otherwise just update scrollbars based on new scrollNode size
-                    updateVerticalSB();
-                    updateHorizontalSB();
+                    /**
+                     * we just need to update scrollbars based on new scrollNode size,
+                     * but we don't do this while dragging, there's no need,
+                     * and it jumps, as dragging updates the scrollbar too.
+                     */
+                    if (!dragDetected) {
+                        updateVerticalSB();
+                        updateHorizontalSB();
+                    }
                 }
             }
         }
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java	Tue Sep 10 14:12:43 2013 -0700
@@ -1586,7 +1586,7 @@
         }
 
         if (pile.size() > 0) {
-            accumCell = pile.get(0);
+            return pile.get(0);
         }
 
         // We need to use the accumCell and return that
--- a/modules/controls/src/main/java/javafx/scene/control/Button.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/Button.java	Tue Sep 10 14:12:43 2013 -0700
@@ -181,7 +181,9 @@
 
     /** {@inheritDoc} */
     @Override public void fire() {
-        fireEvent(new ActionEvent());
+        if (!isDisabled()) {
+            fireEvent(new ActionEvent());
+        }
     }
 
     /** {@inheritDoc} */
--- a/modules/controls/src/main/java/javafx/scene/control/CheckBox.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/CheckBox.java	Tue Sep 10 14:12:43 2013 -0700
@@ -218,20 +218,22 @@
      * false.
      */
     @Override public void fire() {
-        if (isAllowIndeterminate()) {
-            if (!isSelected() && !isIndeterminate()) {
-                setIndeterminate(true);
-            } else if (isSelected() && !isIndeterminate()) {
-                setSelected(false);
-            } else if (isIndeterminate()) {
-                setSelected(true);
+        if (!isDisabled()) {
+            if (isAllowIndeterminate()) {
+                if (!isSelected() && !isIndeterminate()) {
+                    setIndeterminate(true);
+                } else if (isSelected() && !isIndeterminate()) {
+                    setSelected(false);
+                } else if (isIndeterminate()) {
+                    setSelected(true);
+                    setIndeterminate(false);
+                }
+            } else {
+                setSelected(!isSelected());
                 setIndeterminate(false);
             }
-        } else {
-            setSelected(!isSelected());
-            setIndeterminate(false);
+            fireEvent(new ActionEvent());
         }
-        fireEvent(new ActionEvent());
     }
 
     /** {@inheritDoc} */
--- a/modules/controls/src/main/java/javafx/scene/control/Hyperlink.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/Hyperlink.java	Tue Sep 10 14:12:43 2013 -0700
@@ -139,11 +139,13 @@
      * function will also {@link #setVisited} to true.
      */
     @Override public void fire() {
-        // Avoid causing an exception in the case that visited was bound
-        if (visited == null || !visited.isBound()) {
-            setVisited(true);
+        if (!isDisabled()) {
+            // Avoid causing an exception in the case that visited was bound
+            if (visited == null || !visited.isBound()) {
+                setVisited(true);
+            }
+            fireEvent(new ActionEvent());
         }
-        fireEvent(new ActionEvent());
     }
 
     /** {@inheritDoc} */
--- a/modules/controls/src/main/java/javafx/scene/control/Labeled.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/Labeled.java	Tue Sep 10 14:12:43 2013 -0700
@@ -468,7 +468,9 @@
                         }
                         if (url != null) {
                             final Image img = StyleManager.getInstance().getCachedImage(url.toExternalForm());
-                            ((StyleableProperty)graphicProperty()).applyStyle(origin, new ImageView(img));
+                            if (img != null) {
+                                ((StyleableProperty)graphicProperty()).applyStyle(origin, new ImageView(img));
+                            }
                         }
                     }
                 }
--- a/modules/controls/src/main/java/javafx/scene/control/MenuButton.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/MenuButton.java	Tue Sep 10 14:12:43 2013 -0700
@@ -237,7 +237,9 @@
      */
     @Override
     public void fire() {
-        fireEvent(new ActionEvent());
+        if (!isDisabled()) {
+            fireEvent(new ActionEvent());
+        }
     }
 
     /** {@inheritDoc} */
--- a/modules/controls/src/main/java/javafx/scene/control/SplitMenuButton.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/SplitMenuButton.java	Tue Sep 10 14:12:43 2013 -0700
@@ -105,7 +105,9 @@
      * Call the action when button is pressed.
      */
     @Override public void fire() {
-        fireEvent(new ActionEvent());
+        if (!isDisabled()) {
+            fireEvent(new ActionEvent());
+        }
     }
 
     /***************************************************************************
--- a/modules/controls/src/main/java/javafx/scene/control/TableCell.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/TableCell.java	Tue Sep 10 14:12:43 2013 -0700
@@ -542,9 +542,11 @@
         final int index = getIndex();
         final boolean isEmpty = isEmpty();
         final T oldValue = getItem();
+
+        final boolean indexExceedsItemCount = index >= itemCount;
         
         // there is a whole heap of reasons why we should just punt...
-        if (index >= itemCount ||
+        if (indexExceedsItemCount ||
                 index < 0 || 
                 columnIndex < 0 ||
                 !isVisible() ||
@@ -557,7 +559,12 @@
             // refer to Ensemble8PopUpTree.png - in this case the arrows are being
             // shown as the new cells are instantiated with the arrows in the
             // children list, and are only hidden in updateItem.
-            if ((!isEmpty && oldValue != null) || isFirstRun) {
+            // RT-32621: There are circumstances where we need to updateItem,
+            // even when the index is greater than the itemCount. For example,
+            // RT-32621 identifies issues where a TreeTableView collapses a
+            // TreeItem but the custom cells remain visible. This is now
+            // resolved with the check for indexExceedsItemCount.
+            if ((!isEmpty && oldValue != null) || isFirstRun || indexExceedsItemCount) {
                 updateItem(null, true);
                 isFirstRun = false;
             }
--- a/modules/controls/src/main/java/javafx/scene/control/TableColumnBase.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/TableColumnBase.java	Tue Sep 10 14:12:43 2013 -0700
@@ -76,7 +76,7 @@
  *      right-clicks the column header area
  *    <li>Have the contents of the table be sorted (using 
  *      {@link #comparatorProperty() comparator}, {@link #sortable sortable} and
- *      {@link #sortTypeProperty() sortType})
+ *      sortType).
  * </ul>
  * </p>
  * 
@@ -222,9 +222,13 @@
     // --- Parent Column
     /**
      * This read-only property will always refer to the parent of this column,
-     * in the situation where nested columns are being used. To create a nested
-     * column is simply a matter of placing TableColumnBase instances inside the
-     * {@link #columns} ObservableList of a TableColumnBase.
+     * in the situation where nested columns are being used.
+     *
+     * <p>In the currently existing subclasses, to create a nested
+     * column is simply a matter of placing the relevant TableColumnBase instances
+     * inside the columns ObservableList (for example, see
+     * {@link javafx.scene.control.TableColumn#getColumns()} and
+     * {@link javafx.scene.control.TreeTableColumn#getColumns()}.
      */
     private ReadOnlyObjectWrapper<TableColumnBase<S,?>> parentColumn;
     void setParentColumn(TableColumnBase<S,?> value) { parentColumnPropertyImpl().set(value); }
@@ -265,7 +269,6 @@
      * The id of this TableColumnBase. This simple string identifier is useful 
      * for finding a specific TableColumnBase within a UI control that uses 
      * TableColumnBase instances. The default value is {@code null}.
-     * @since JavaFX 2.2
      */
     private StringProperty id;
     public final void setId(String value) { idProperty().set(value); }
@@ -288,7 +291,6 @@
      * <p>
      * Parsing this style might not be supported on some limited
      * platforms. It is recommended to use a standalone CSS file instead.
-     * @since JavaFX 2.2
      */
     private StringProperty style;
     public final void setStyle(String value) { styleProperty().set(value); }
@@ -310,7 +312,6 @@
      * each element of the list is a style class to which this Node belongs.
      *
      * @see <a href="http://www.w3.org/TR/css3-selectors/#class-html">CSS3 class selectors</a>
-     * @since JavaFX 2.2
      */
     @Override public ObservableList<String> getStyleClass() {
         return styleClass;
@@ -321,7 +322,6 @@
     /**
      * <p>The graphic to show in the table column to allow the user to
      * indicate graphically what is in the column. </p>
-     * @since JavaFX 2.2
      */
     private ObjectProperty<Node> graphic;
     public final void setGraphic(Node value) {
@@ -353,8 +353,6 @@
      * on screen to indicate whether the table column is part of the sort order, 
      * and if so, whether the sort is ascending or descending, and what position in 
      * the sort order it is in.
-     * 
-     * @since JavaFX 2.2
      */
     private ObjectProperty<Node> sortNode = new SimpleObjectProperty<Node>(this, "sortNode");
     public final void setSortNode(Node value) { sortNodeProperty().set(value); }
@@ -597,7 +595,6 @@
       *
       * @return an observable map of properties on this table column for use 
       * primarily by application developers
-     * @since JavaFX 2.2
      */
     public final ObservableMap<Object, Object> getProperties() {
         if (properties == null) {
@@ -609,7 +606,6 @@
     /**
      * Tests if this table column has properties.
      * @return true if node has properties.
-     * @since JavaFX 2.2
      */
     public boolean hasProperties() {
         return properties != null && ! properties.isEmpty();
@@ -625,7 +621,6 @@
      *
      * @param value The value to be stored - this can later be retrieved by calling
      *          {@link TableColumnBase#getUserData()}.
-     * @since JavaFX 2.2
      */
     public void setUserData(Object value) {
         getProperties().put(USER_DATA_KEY, value);
@@ -637,7 +632,6 @@
      *
      * @return The Object that was previously set, or null if no property
      *          has been set or if null was set.
-     * @since JavaFX 2.2
      */
     public Object getUserData() {
         return getProperties().get(USER_DATA_KEY);
--- a/modules/controls/src/main/java/javafx/scene/control/ToggleButton.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/ToggleButton.java	Tue Sep 10 14:12:43 2013 -0700
@@ -226,8 +226,10 @@
     /** {@inheritDoc} */
     @Override public void fire() {
         // TODO (aruiz): if (!isReadOnly(isSelected()) {
-        setSelected(!isSelected());
-        fireEvent(new ActionEvent());
+        if (!isDisabled()) {
+            setSelected(!isSelected());
+            fireEvent(new ActionEvent());
+        }
     }
 
     /** {@inheritDoc} */
--- a/modules/controls/src/main/java/javafx/scene/control/TreeTableCell.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/TreeTableCell.java	Tue Sep 10 14:12:43 2013 -0700
@@ -533,9 +533,11 @@
         final int index = getIndex();
         final boolean isEmpty = isEmpty();
         final T oldValue = getItem();
+
+        final boolean indexExceedsItemCount = index >= itemCount;
         
         // there is a whole heap of reasons why we should just punt...
-        if (index >= itemCount ||
+        if (indexExceedsItemCount ||
                 index < 0 || 
                 columnIndex < 0 ||
                 !isVisible() ||
@@ -549,7 +551,12 @@
             // refer to Ensemble8PopUpTree.png - in this case the arrows are being
             // shown as the new cells are instantiated with the arrows in the
             // children list, and are only hidden in updateItem.
-            if ((!isEmpty && oldValue != null) || isFirstRun) {
+            // RT-32621: There are circumstances where we need to updateItem,
+            // even when the index is greater than the itemCount. For example,
+            // RT-32621 identifies issues where a TreeTableView collapses a
+            // TreeItem but the custom cells remain visible. This is now
+            // resolved with the check for indexExceedsItemCount.
+            if ((!isEmpty && oldValue != null) || isFirstRun || indexExceedsItemCount) {
                 updateItem(null, true);
                 isFirstRun = false;
             }
--- a/modules/controls/src/main/java/javafx/scene/control/TreeTableView.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/TreeTableView.java	Tue Sep 10 14:12:43 2013 -0700
@@ -950,115 +950,6 @@
         return editingCell;
     }
 
-    
-    // --- On Edit Start
-    private ObjectProperty<EventHandler<TreeTableView.EditEvent<S>>> onEditStart;
-
-    /**
-     * Sets the {@link EventHandler} that will be called when the user begins
-     * an edit. 
-     */
-    public final void setOnEditStart(EventHandler<TreeTableView.EditEvent<S>> value) {
-        onEditStartProperty().set(value);
-    }
-
-    /**
-     * Returns the {@link EventHandler} that will be called when the user begins
-     * an edit.
-     */
-    public final EventHandler<TreeTableView.EditEvent<S>> getOnEditStart() {
-        return onEditStart == null ? null : onEditStart.get();
-    }
-
-    /**
-     * This event handler will be fired when the user successfully initiates
-     * editing.
-     */
-    public final ObjectProperty<EventHandler<TreeTableView.EditEvent<S>>> onEditStartProperty() {
-        if (onEditStart == null) {
-            onEditStart = new SimpleObjectProperty<EventHandler<TreeTableView.EditEvent<S>>>(this, "onEditStart") {
-                @Override protected void invalidated() {
-                    setEventHandler(TreeTableView.<S>editStartEvent(), get());
-                }
-            };
-        }
-        return onEditStart;
-    }
-
-
-    // --- On Edit Commit
-    private ObjectProperty<EventHandler<TreeTableView.EditEvent<S>>> onEditCommit;
-
-    /**
-     * Sets the {@link EventHandler} that will be called when the user commits
-     * an edit. 
-     */
-    public final void setOnEditCommit(EventHandler<TreeTableView.EditEvent<S>> value) {
-        onEditCommitProperty().set(value);
-    }
-
-    /**
-     * Returns the {@link EventHandler} that will be called when the user commits
-     * an edit.
-     */
-    public final EventHandler<TreeTableView.EditEvent<S>> getOnEditCommit() {
-        return onEditCommit == null ? null : onEditCommit.get();
-    }
-
-    /**
-     * <p>This property is used when the user performs an action that should
-     * result in their editing input being persisted.</p>
-     *
-     * <p>The EventHandler in this property should not be called directly - 
-     * instead call {@link TreeCell#commitEdit(java.lang.Object)} from within
-     * your custom TreeCell. This will handle firing this event, updating the 
-     * view, and switching out of the editing state.</p>
-     */
-    public final ObjectProperty<EventHandler<TreeTableView.EditEvent<S>>> onEditCommitProperty() {
-        if (onEditCommit == null) {
-            onEditCommit = new SimpleObjectProperty<EventHandler<TreeTableView.EditEvent<S>>>(this, "onEditCommit") {
-                @Override protected void invalidated() {
-                    setEventHandler(TreeTableView.<S>editCommitEvent(), get());
-                }
-            };
-        }
-        return onEditCommit;
-    }
-
-
-    // --- On Edit Cancel
-    private ObjectProperty<EventHandler<TreeTableView.EditEvent<S>>> onEditCancel;
-
-    /**
-     * Sets the {@link EventHandler} that will be called when the user cancels
-     * an edit.
-     */
-    public final void setOnEditCancel(EventHandler<TreeTableView.EditEvent<S>> value) {
-        onEditCancelProperty().set(value);
-    }
-
-    /**
-     * Returns the {@link EventHandler} that will be called when the user cancels
-     * an edit.
-     */
-    public final EventHandler<TreeTableView.EditEvent<S>> getOnEditCancel() {
-        return onEditCancel == null ? null : onEditCancel.get();
-    }
-
-    /**
-     * This event handler will be fired when the user cancels editing a cell.
-     */
-    public final ObjectProperty<EventHandler<TreeTableView.EditEvent<S>>> onEditCancelProperty() {
-        if (onEditCancel == null) {
-            onEditCancel = new SimpleObjectProperty<EventHandler<TreeTableView.EditEvent<S>>>(this, "onEditCancel") {
-                @Override protected void invalidated() {
-                    setEventHandler(TreeTableView.<S>editCancelEvent(), get());
-                }
-            };
-        }
-        return onEditCancel;
-    }
-    
 
     // --- Table menu button visible
     private BooleanProperty tableMenuButtonVisible;
--- a/modules/controls/src/main/java/javafx/scene/control/cell/ProgressBarTableCell.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/cell/ProgressBarTableCell.java	Tue Sep 10 14:12:43 2013 -0700
@@ -91,6 +91,7 @@
         this.getStyleClass().add("progress-bar-table-cell");
         
         this.progressBar = new ProgressBar();
+        this.progressBar.setMaxWidth(Double.MAX_VALUE);
     }
     
     
@@ -109,8 +110,10 @@
             setGraphic(null);
         } else {
             progressBar.progressProperty().unbind();
-            
-            observable = getTableColumn().getCellObservableValue(getIndex());
+
+            final TableColumn<S,Double> column = getTableColumn();
+            observable = column == null ? null : column.getCellObservableValue(getIndex());
+
             if (observable != null) {
                 progressBar.progressProperty().bind(observable);
             } else if (item != null) {
--- a/modules/controls/src/main/java/javafx/scene/control/cell/ProgressBarTreeTableCell.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/cell/ProgressBarTreeTableCell.java	Tue Sep 10 14:12:43 2013 -0700
@@ -27,6 +27,7 @@
 
 import javafx.beans.value.ObservableValue;
 import javafx.scene.control.ProgressBar;
+import javafx.scene.control.TableColumn;
 import javafx.scene.control.TreeTableCell;
 import javafx.scene.control.TreeTableColumn;
 import javafx.util.Callback;
@@ -91,6 +92,7 @@
         this.getStyleClass().add("progress-bar-tree-table-cell");
         
         this.progressBar = new ProgressBar();
+        this.progressBar.setMaxWidth(Double.MAX_VALUE);
     }
     
     
@@ -110,7 +112,9 @@
         } else {
             progressBar.progressProperty().unbind();
             
-            observable = getTableColumn().getCellObservableValue(getIndex());
+            final TreeTableColumn<S,Double> column = getTableColumn();
+            observable = column == null ? null : column.getCellObservableValue(getIndex());
+
             if (observable != null) {
                 progressBar.progressProperty().bind(observable);
             } else if (item != null) {
--- a/modules/controls/src/main/java/javafx/scene/control/cell/TextFieldTreeCell.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/cell/TextFieldTreeCell.java	Tue Sep 10 14:12:43 2013 -0700
@@ -216,8 +216,6 @@
     /** {@inheritDoc} */
     @Override public void updateItem(T item, boolean empty) {
         super.updateItem(item, empty);
-        
-        TreeItem<T> treeItem = getTreeItem();
         CellUtils.updateItem(this, getConverter(), hbox, getTreeItemGraphic(), textField);
     }
     
--- a/modules/controls/src/main/java/javafx/scene/control/cell/TextFieldTreeTableCell.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/cell/TextFieldTreeTableCell.java	Tue Sep 10 14:12:43 2013 -0700
@@ -56,7 +56,7 @@
     /**
      * Provides a {@link TextField} that allows editing of the cell content when
      * the cell is double-clicked, or when 
-     * {@link TableView#edit(int, javafx.scene.control.TreeTableColumn)} is called. 
+     * {@link javafx.scene.control.TreeTableView#edit(int, javafx.scene.control.TreeTableColumn)} is called.
      * This method will only  work on {@link TreeTableColumn} instances which are of
      * type String.
      * 
@@ -71,7 +71,7 @@
     /**
      * Provides a {@link TextField} that allows editing of the cell content when
      * the cell is double-clicked, or when 
-     * {@link TableView#edit(int, javafx.scene.control.TreeTableColumn) } is called. 
+     * {@link javafx.scene.control.TreeTableView#edit(int, javafx.scene.control.TreeTableColumn) } is called.
      * This method will work  on any {@link TreeTableColumn} instance, regardless of 
      * its generic type. However, to enable this, a {@link StringConverter} must 
      * be provided that will convert the given String (from what the user typed 
--- a/modules/controls/src/test/java/com/sun/javafx/scene/control/infrastructure/MouseEventFirer.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/com/sun/javafx/scene/control/infrastructure/MouseEventFirer.java	Tue Sep 10 14:12:43 2013 -0700
@@ -51,6 +51,11 @@
         fireMouseEvent(MouseEvent.MOUSE_PRESSED, modifiers);
         fireMouseEvent(MouseEvent.MOUSE_RELEASED, modifiers);
     }
+
+    public void fireMousePressAndRelease(int clickCount, KeyModifier... modifiers) {
+        fireMouseEvent(MouseEvent.MOUSE_PRESSED, MouseButton.PRIMARY, clickCount, 0, 0, modifiers);
+        fireMouseEvent(MouseEvent.MOUSE_RELEASED, MouseButton.PRIMARY, clickCount, 0, 0, modifiers);
+    }
     
     public void fireMouseClicked() {
         fireMouseEvent(MouseEvent.MOUSE_CLICKED);
@@ -83,6 +88,10 @@
     public void fireMousePressed(double deltaX, double deltaY, KeyModifier... modifiers) {
         fireMouseEvent(MouseEvent.MOUSE_PRESSED, deltaX, deltaY, modifiers);
     }
+
+    public void fireMousePressed(int clickCount, double deltaX, double deltaY, KeyModifier... modifiers) {
+        fireMouseEvent(MouseEvent.MOUSE_PRESSED, MouseButton.PRIMARY, clickCount, deltaX, deltaY, modifiers);
+    }
     
     public void fireMouseReleased() {
         fireMouseEvent(MouseEvent.MOUSE_RELEASED);
--- a/modules/controls/src/test/java/com/sun/javafx/scene/control/infrastructure/VirtualFlowTestUtils.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/com/sun/javafx/scene/control/infrastructure/VirtualFlowTestUtils.java	Tue Sep 10 14:12:43 2013 -0700
@@ -51,12 +51,20 @@
     }
 
     public static void clickOnRow(final Control control, int row, KeyModifier... modifiers) {
-        clickOnRow(control, row, false, modifiers);
+        clickOnRow(control, row, 1, false, modifiers);
+    }
+
+    public static void clickOnRow(final Control control, int row, int clickCount, KeyModifier... modifiers) {
+        clickOnRow(control, row, clickCount, false, modifiers);
+    }
+
+    public static void clickOnRow(final Control control, int row, boolean ignoreChildren, KeyModifier... modifiers) {
+        clickOnRow(control, row, 1, ignoreChildren, modifiers);
     }
 
     // ignore children allows clicking on the row, rather than a child in that row.
     // This is good for testing, for example, TableRowBehavior
-    public static void clickOnRow(final Control control, int row, boolean ignoreChildren, KeyModifier... modifiers) {
+    public static void clickOnRow(final Control control, int row, int clickCount, boolean ignoreChildren, KeyModifier... modifiers) {
         IndexedCell cell = VirtualFlowTestUtils.getCell(control, row);
 
         if (! ignoreChildren && ((cell instanceof TableRow) || (cell instanceof TreeTableRow))) {
@@ -65,7 +73,7 @@
                     continue;
                 }
                 IndexedCell<?> childCell = (IndexedCell<?>)n;
-                new MouseEventFirer(childCell).fireMousePressAndRelease(modifiers);
+                new MouseEventFirer(childCell).fireMousePressAndRelease(clickCount, modifiers);
                 break;
             }
         } else {
@@ -76,7 +84,7 @@
                 mef.fireMousePressed(cell.getWidth(), cell.getHeight() / 2.0, modifiers);
                 mef.fireMouseReleased(cell.getWidth(), cell.getHeight() / 2.0, modifiers);
             } else {
-                new MouseEventFirer(cell).fireMousePressAndRelease(modifiers);
+                new MouseEventFirer(cell).fireMousePressAndRelease(clickCount, modifiers);
             }
         }
     }
--- a/modules/controls/src/test/java/javafx/scene/control/ListViewKeyInputTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/ListViewKeyInputTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -1167,7 +1167,7 @@
         assertEquals(2, rt31577_count);
     }
 
-    @Ignore @Test public void test_rt32383_pageDown() {
+    @Test public void test_rt32383_pageDown() {
         // this test requires a lot of data
         listView.getItems().clear();
         for (int i = 0; i < 100; i++) {
@@ -1180,19 +1180,19 @@
 
         final String initialFocusOwner = fm.getFocusedItem();
 
-        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final String newFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, newFocusOwner);
 
-        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final String nextFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, nextFocusOwner);
         assertNotSame(newFocusOwner, nextFocusOwner);
     }
 
-    @Ignore @Test public void test_rt32383_pageUp() {
+    @Test public void test_rt32383_pageUp() {
         // this test requires a lot of data
         listView.getItems().clear();
         for (int i = 0; i < 100; i++) {
@@ -1214,12 +1214,12 @@
 
         final String initialFocusOwner = fm.getFocusedItem();
 
-        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final String newFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, newFocusOwner);
 
-        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final String nextFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, nextFocusOwner);
--- a/modules/controls/src/test/java/javafx/scene/control/TableViewKeyInputTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/TableViewKeyInputTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -1906,7 +1906,7 @@
         assertEquals(2, rt31577_count);
     }
 
-    @Ignore @Test public void test_rt32383_pageDown() {
+    @Test public void test_rt32383_pageDown() {
         // this test requires a lot of data
         tableView.getItems().clear();
         for (int i = 0; i < 100; i++) {
@@ -1919,19 +1919,19 @@
 
         final String initialFocusOwner = fm.getFocusedItem();
 
-        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final String newFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, newFocusOwner);
 
-        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final String nextFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, nextFocusOwner);
         assertNotSame(newFocusOwner, nextFocusOwner);
     }
 
-    @Ignore @Test public void test_rt32383_pageUp() {
+    @Test public void test_rt32383_pageUp() {
         // this test requires a lot of data
         tableView.getItems().clear();
         for (int i = 0; i < 100; i++) {
@@ -1950,12 +1950,12 @@
 
         final String initialFocusOwner = fm.getFocusedItem();
 
-        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final String newFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, newFocusOwner);
 
-        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final String nextFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, nextFocusOwner);
--- a/modules/controls/src/test/java/javafx/scene/control/TreeTableCellTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/TreeTableCellTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -277,20 +277,20 @@
         assertEquals(apples, tree.getEditingCell().getTreeItem());
     }
 
-    @Ignore // TODO file bug!
-    @Test public void editCellFiresEventOnTree() {
-        tree.setEditable(true);
-        cell.updateTreeTableView(tree);
-        cell.updateIndex(2);
-        final boolean[] called = new boolean[] { false };
-        tree.setOnEditStart(new EventHandler<TreeTableView.EditEvent<String>>() {
-            @Override public void handle(TreeTableView.EditEvent<String> event) {
-                called[0] = true;
-            }
-        });
-        cell.startEdit();
-        assertTrue(called[0]);
-    }
+//    @Ignore // TODO file bug!
+//    @Test public void editCellFiresEventOnTree() {
+//        tree.setEditable(true);
+//        cell.updateTreeTableView(tree);
+//        cell.updateIndex(2);
+//        final boolean[] called = new boolean[] { false };
+//        tree.setOnEditStart(new EventHandler<TreeTableView.EditEvent<String>>() {
+//            @Override public void handle(TreeTableView.EditEvent<String> event) {
+//                called[0] = true;
+//            }
+//        });
+//        cell.startEdit();
+//        assertTrue(called[0]);
+//    }
 
     // commitEdit()
     @Test public void commitWhenTreeIsNullIsOK() {
@@ -310,21 +310,21 @@
         assertEquals("Watermelon", tree.getRoot().getChildren().get(0).getValue());
     }
 
-    @Ignore // TODO file bug!
-    @Test public void commitSendsEventToTree() {
-        tree.setEditable(true);
-        cell.updateTreeTableView(tree);
-        cell.updateIndex(1);
-        cell.startEdit();
-        final boolean[] called = new boolean[] { false };
-        tree.setOnEditCommit(new EventHandler<TreeTableView.EditEvent<String>>() {
-            @Override public void handle(TreeTableView.EditEvent<String> event) {
-                called[0] = true;
-            }
-        });
-        cell.commitEdit("Watermelon");
-        assertTrue(called[0]);
-    }
+//    @Ignore // TODO file bug!
+//    @Test public void commitSendsEventToTree() {
+//        tree.setEditable(true);
+//        cell.updateTreeTableView(tree);
+//        cell.updateIndex(1);
+//        cell.startEdit();
+//        final boolean[] called = new boolean[] { false };
+//        tree.setOnEditCommit(new EventHandler<TreeTableView.EditEvent<String>>() {
+//            @Override public void handle(TreeTableView.EditEvent<String> event) {
+//                called[0] = true;
+//            }
+//        });
+//        cell.commitEdit("Watermelon");
+//        assertTrue(called[0]);
+//    }
 
     @Test public void afterCommitTreeTableViewEditingCellIsNull() {
         tree.setEditable(true);
@@ -344,21 +344,21 @@
         cell.cancelEdit();
     }
 
-    @Ignore // TODO file bug!
-    @Test public void cancelEditFiresChangeEvent() {
-        tree.setEditable(true);
-        cell.updateTreeTableView(tree);
-        cell.updateIndex(1);
-        cell.startEdit();
-        final boolean[] called = new boolean[] { false };
-        tree.setOnEditCancel(new EventHandler<TreeTableView.EditEvent<String>>() {
-            @Override public void handle(TreeTableView.EditEvent<String> event) {
-                called[0] = true;
-            }
-        });
-        cell.cancelEdit();
-        assertTrue(called[0]);
-    }
+//    @Ignore // TODO file bug!
+//    @Test public void cancelEditFiresChangeEvent() {
+//        tree.setEditable(true);
+//        cell.updateTreeTableView(tree);
+//        cell.updateIndex(1);
+//        cell.startEdit();
+//        final boolean[] called = new boolean[] { false };
+//        tree.setOnEditCancel(new EventHandler<TreeTableView.EditEvent<String>>() {
+//            @Override public void handle(TreeTableView.EditEvent<String> event) {
+//                called[0] = true;
+//            }
+//        });
+//        cell.cancelEdit();
+//        assertTrue(called[0]);
+//    }
 
     @Test public void cancelSetsTreeTableViewEditingIndexToNegativeOne() {
         tree.setEditable(true);
--- a/modules/controls/src/test/java/javafx/scene/control/TreeTableRowTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/TreeTableRowTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -590,19 +590,19 @@
         assertEquals(apples, tree.getEditingCell().getTreeItem());
     }
 
-    @Test public void editCellFiresEventOnTree() {
-        tree.setEditable(true);
-        cell.updateTreeTableView(tree);
-        cell.updateIndex(2);
-        final boolean[] called = new boolean[] { false };
-        tree.setOnEditStart(new EventHandler<TreeTableView.EditEvent<String>>() {
-            @Override public void handle(TreeTableView.EditEvent<String> event) {
-                called[0] = true;
-            }
-        });
-        cell.startEdit();
-        assertTrue(called[0]);
-    }
+//    @Test public void editCellFiresEventOnTree() {
+//        tree.setEditable(true);
+//        cell.updateTreeTableView(tree);
+//        cell.updateIndex(2);
+//        final boolean[] called = new boolean[] { false };
+//        tree.setOnEditStart(new EventHandler<TreeTableView.EditEvent<String>>() {
+//            @Override public void handle(TreeTableView.EditEvent<String> event) {
+//                called[0] = true;
+//            }
+//        });
+//        cell.startEdit();
+//        assertTrue(called[0]);
+//    }
 
     // commitEdit()
     @Test public void commitWhenTreeIsNullIsOK() {
@@ -620,20 +620,20 @@
         assertEquals("Watermelon", tree.getRoot().getChildren().get(0).getValue());
     }
 
-    @Test public void commitSendsEventToTree() {
-        tree.setEditable(true);
-        cell.updateTreeTableView(tree);
-        cell.updateIndex(1);
-        cell.startEdit();
-        final boolean[] called = new boolean[] { false };
-        tree.setOnEditCommit(new EventHandler<TreeTableView.EditEvent<String>>() {
-            @Override public void handle(TreeTableView.EditEvent<String> event) {
-                called[0] = true;
-            }
-        });
-        cell.commitEdit("Watermelon");
-        assertTrue(called[0]);
-    }
+//    @Test public void commitSendsEventToTree() {
+//        tree.setEditable(true);
+//        cell.updateTreeTableView(tree);
+//        cell.updateIndex(1);
+//        cell.startEdit();
+//        final boolean[] called = new boolean[] { false };
+//        tree.setOnEditCommit(new EventHandler<TreeTableView.EditEvent<String>>() {
+//            @Override public void handle(TreeTableView.EditEvent<String> event) {
+//                called[0] = true;
+//            }
+//        });
+//        cell.commitEdit("Watermelon");
+//        assertTrue(called[0]);
+//    }
 
     @Test public void afterCommitTreeTableViewEditingCellIsNull() {
         tree.setEditable(true);
@@ -652,20 +652,20 @@
         cell.cancelEdit();
     }
 
-    @Test public void cancelEditFiresChangeEvent() {
-        tree.setEditable(true);
-        cell.updateTreeTableView(tree);
-        cell.updateIndex(1);
-        cell.startEdit();
-        final boolean[] called = new boolean[] { false };
-        tree.setOnEditCancel(new EventHandler<TreeTableView.EditEvent<String>>() {
-            @Override public void handle(TreeTableView.EditEvent<String> event) {
-                called[0] = true;
-            }
-        });
-        cell.cancelEdit();
-        assertTrue(called[0]);
-    }
+//    @Test public void cancelEditFiresChangeEvent() {
+//        tree.setEditable(true);
+//        cell.updateTreeTableView(tree);
+//        cell.updateIndex(1);
+//        cell.startEdit();
+//        final boolean[] called = new boolean[] { false };
+//        tree.setOnEditCancel(new EventHandler<TreeTableView.EditEvent<String>>() {
+//            @Override public void handle(TreeTableView.EditEvent<String> event) {
+//                called[0] = true;
+//            }
+//        });
+//        cell.cancelEdit();
+//        assertTrue(called[0]);
+//    }
 
     @Test public void cancelSetsTreeTableViewEditingCellIsNull() {
         tree.setEditable(true);
--- a/modules/controls/src/test/java/javafx/scene/control/TreeTableViewKeyInputTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/TreeTableViewKeyInputTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -2422,7 +2422,7 @@
         assertEquals(2, rt31577_count);
     }
 
-    @Ignore @Test public void test_rt32383_pageDown() {
+    @Test public void test_rt32383_pageDown() {
         // this test requires a lot of data
         for (int i = 0; i < 100; i++) {
             root.getChildren().add(new TreeItem<String>("Row " + i));
@@ -2434,19 +2434,19 @@
 
         final TreeItem<String> initialFocusOwner = fm.getFocusedItem();
 
-        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final TreeItem<String> newFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, newFocusOwner);
 
-        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final TreeItem<String> nextFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, nextFocusOwner);
         assertNotSame(newFocusOwner, nextFocusOwner);
     }
 
-    @Ignore @Test public void test_rt32383_pageUp() {
+    @Test public void test_rt32383_pageUp() {
         // this test requires a lot of data
         for (int i = 0; i < 100; i++) {
             root.getChildren().add(new TreeItem<String>("Row " + i));
@@ -2464,12 +2464,12 @@
 
         final TreeItem<String> initialFocusOwner = fm.getFocusedItem();
 
-        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final TreeItem<String> newFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, newFocusOwner);
 
-        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final TreeItem<String> nextFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, nextFocusOwner);
--- a/modules/controls/src/test/java/javafx/scene/control/TreeViewKeyInputTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/TreeViewKeyInputTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -29,6 +29,7 @@
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
 import javafx.collections.FXCollections;
+import javafx.event.Event;
 import javafx.event.EventHandler;
 import javafx.scene.input.KeyCode;
 import java.util.List;
@@ -1370,7 +1371,7 @@
         assertEquals(2, rt31577_count);
     }
 
-    @Ignore @Test public void test_rt32383_pageDown() {
+    @Test public void test_rt32383_pageDown() {
         // this test requires a lot of data
         for (int i = 0; i < 100; i++) {
             root.getChildren().add(new TreeItem<String>("Row " + i));
@@ -1382,19 +1383,19 @@
 
         final TreeItem<String> initialFocusOwner = fm.getFocusedItem();
 
-        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final TreeItem<String> newFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, newFocusOwner);
 
-        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_DOWN, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final TreeItem<String> nextFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, nextFocusOwner);
         assertNotSame(newFocusOwner, nextFocusOwner);
     }
 
-    @Ignore @Test public void test_rt32383_pageUp() {
+    @Test public void test_rt32383_pageUp() {
         // this test requires a lot of data
         for (int i = 0; i < 100; i++) {
             root.getChildren().add(new TreeItem<String>("Row " + i));
@@ -1412,12 +1413,12 @@
 
         final TreeItem<String> initialFocusOwner = fm.getFocusedItem();
 
-        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final TreeItem<String> newFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, newFocusOwner);
 
-        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.CTRL);
+        keyboard.doKeyPress(KeyCode.PAGE_UP, KeyModifier.getShortcutKey());
         Toolkit.getToolkit().firePulse();
         final TreeItem<String> nextFocusOwner = fm.getFocusedItem();
         assertNotSame(initialFocusOwner, nextFocusOwner);
@@ -1491,4 +1492,71 @@
         assertNotSame(initialSelectionOwner, nextSelectionOwner);
         assertNotSame(newSelectionOwner, nextSelectionOwner);
     }
+
+    private int rt32783_count_start = 0;
+    private int rt32783_count_commit = 0;
+    private int rt32783_count_cancel = 0;
+    private int rt32783_count = 0;
+    @Test public void test_rt32683() {
+        // set up test
+        final int items = 8;
+        TreeItem<String> newRoot = new TreeItem<>("New root");
+        newRoot.setExpanded(false);
+        for (int i = 0; i < items; i++) {
+            newRoot.getChildren().add(new TreeItem<>("Row " + i));
+        }
+
+        treeView.setRoot(newRoot);
+        treeView.setEditable(true);
+        treeView.setOnEditStart(new EventHandler() {
+            @Override public void handle(Event t) {
+                rt32783_count_start++;
+            }
+        });
+
+        treeView.setOnEditCommit(new EventHandler() {
+            @Override public void handle(Event t) {
+                rt32783_count_commit++;
+            }
+        });
+
+        treeView.setOnEditCancel(new EventHandler() {
+            @Override public void handle(Event t) {
+                rt32783_count_cancel++;
+            }
+        });
+
+        treeView.editingItemProperty().addListener(new InvalidationListener() {
+            @Override
+            public void invalidated(Observable observable) {
+                assertNotNull(treeView.getEditingItem());
+                System.out.println("editing item: " + treeView.getEditingItem());
+                rt32783_count++;
+            }
+        });
+
+        // start test
+//        final int middleIndex = items / 2;
+
+        newRoot.setExpanded(true);
+        Toolkit.getToolkit().firePulse();
+        newRoot.setExpanded(false);
+        Toolkit.getToolkit().firePulse();
+
+        final MultipleSelectionModel sm = treeView.getSelectionModel();
+        sm.clearAndSelect(0);
+
+        // need to get the cell before the editing starts
+//        TreeCell cell = (TreeCell)VirtualFlowTestUtils.getCell(treeView, 0);
+
+        // this forces the selected cell to go into editing mode
+        keyboard.doKeyPress(KeyCode.F2);
+//        Toolkit.getToolkit().firePulse();
+
+        assertEquals(1, rt32783_count_start);
+        assertEquals(0, rt32783_count_commit);
+        assertEquals(0, rt32783_count_cancel);
+//        assertTrue(cell.isEditing());
+        assertEquals(newRoot, treeView.getEditingItem());
+    }
 }
--- a/modules/controls/src/test/java/javafx/scene/control/TreeViewTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/TreeViewTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -718,7 +718,6 @@
         VirtualFlowTestUtils.assertRowsEmpty(tree, 3, -1); // rows 3+ should be empty
     }
 
-    @Ignore("Test has started failing - I have reopened the jira issue")
     @Test public void test_rt28556() {
         List<Employee> employees = Arrays.<Employee>asList(
             new Employee("Ethan Williams", "Sales Department"),
--- a/modules/controls/src/test/java/javafx/scene/control/cell/ProgressBarTableCellTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/cell/ProgressBarTableCellTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -140,8 +140,21 @@
         assertNotNull(cell.getGraphic());
         assertTrue(cell.getGraphic() instanceof ProgressBar);
     }
-    
 
+
+
+    /**************************************************************************
+     *
+     * misc tests
+     *
+     **************************************************************************/
+
+    @Test public void test_graphicMaxWidthIsDoubleMaxValue() {
+        ProgressBarTableCell<Object> cell = new ProgressBarTableCell<>();
+        cell.updateItem(0.5, false);
+        assertNotNull(cell.getGraphic());
+        assertEquals(Double.MAX_VALUE, ((ProgressBar)cell.getGraphic()).getMaxWidth(), 0.0);
+    }
     
 //    /**************************************************************************
 //     * 
--- a/modules/controls/src/test/java/javafx/scene/control/cell/ProgressBarTreeTableCellTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/control/cell/ProgressBarTreeTableCellTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -141,9 +141,24 @@
         assertNotNull(cell.getGraphic());
         assertTrue(cell.getGraphic() instanceof ProgressBar);
     }
-    
 
-    
+
+
+    /**************************************************************************
+     *
+     * misc tests
+     *
+     **************************************************************************/
+
+    @Test public void test_graphicMaxWidthIsDoubleMaxValue() {
+        ProgressBarTreeTableCell<Object> cell = new ProgressBarTreeTableCell<>();
+        cell.updateItem(0.5, false);
+        assertNotNull(cell.getGraphic());
+        assertEquals(Double.MAX_VALUE, ((ProgressBar)cell.getGraphic()).getMaxWidth(), 0.0);
+    }
+
+
+
 //    /**************************************************************************
 //     * 
 //     * test checkbox selection state is bound
--- a/modules/fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html	Tue Sep 10 14:12:43 2013 -0700
@@ -617,6 +617,30 @@
 
 <p><assert id="handler_method_signature" group="event_handlers">In general, a handler method should conform to the signature of a standard event handler; that is, it should take a single argument of a type that extends <span class="code">javafx.event.Event</span> and should return void (similar to an event delegate in C#). The event argument often carries important and useful information about the nature of the event;</assert> <assert id="handler_method_opt_arg" group="event_handlers">however, it is optional and may be omitted if desired</assert>.</p>
 
+<p> One exception to this rule are collections. <span class="code">ObservableList</span>, <span class="code">ObservableMap</span> or <span class="code">ObservableSet</span>
+ uses a special <span class="code">onChange</span> attribute that points to a handler method with a <span class="code">ListChangeListner.Change</span>, <span class="code">MapChangeListener.Change</span> or <span class="code">SetChangeListener.Change</span> parameter respectively.
+
+<pre class="code">
+&lt;VBox fx:controller="com.foo.MyController"
+    xmlns:fx="http://javafx.com/fxml"&gt;
+    &lt;children onChange="#handleChildrenChange"/&gt;
+&lt;/VBox&gt;
+</pre>
+
+where the handler method looks like this:
+
+<pre class="code">
+package com.foo;
+
+import javafx.collections.ListChangeListener.Change;
+
+public class MyController {
+    public void handleChildrenChange(ListChangeListener.Change c) {
+        System.out.println("Children changed!");
+    }
+}
+</pre>
+
 <p>Controllers are discussed in more detail in a later section.</p>
 
 <h2><a name="scripting">Scripting</a></h2>
--- a/modules/fxml/src/main/java/com/sun/javafx/fxml/ObservableListChangeEvent.java	Fri Sep 06 13:22:16 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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 com.sun.javafx.fxml;
-
-import java.util.List;
-
-import javafx.collections.ObservableList;
-import javafx.event.Event;
-import javafx.event.EventType;
-
-/**
- * Observable list change event.
- */
-public class ObservableListChangeEvent<E> extends Event {
-    private static final long serialVersionUID = 0;
-
-    private EventType<ObservableListChangeEvent<?>> type;
-    private int from;
-    private int to;
-    private List<E> removed;
-
-    public static final EventType<ObservableListChangeEvent<?>> ADD =
-        new EventType<ObservableListChangeEvent<?>>(EventType.ROOT, ObservableListChangeEvent.class.getName() + "_ADD");
-    public static final EventType<ObservableListChangeEvent<?>> UPDATE =
-        new EventType<ObservableListChangeEvent<?>>(EventType.ROOT, ObservableListChangeEvent.class.getName() + "_UPDATE");
-    public static final EventType<ObservableListChangeEvent<?>> REMOVE =
-        new EventType<ObservableListChangeEvent<?>>(EventType.ROOT, ObservableListChangeEvent.class.getName() + "_REMOVE");
-
-    public ObservableListChangeEvent(ObservableList<E> source, EventType<ObservableListChangeEvent<?>> type,
-        int from, int to, List<E> removed) {
-        super(source, null, type);
-
-        this.from = from;
-        this.to = to;
-        this.removed = removed;
-    }
-
-    /**
-     * Returns the first index affected by the change.
-     */
-    public int getFrom() {
-        return from;
-    }
-
-    /**
-     * Returns the index immediately following the last index affected by the
-     * change.
-     */
-    public int getTo() {
-        return to;
-    }
-
-    /**
-     * Returns any elements that were removed as part of the change, or
-     * <tt>null</tt> if either this change did not cause any values to be
-     * removed or the removed values could not be determined.
-     */
-    public List<E> getRemoved() {
-        return removed;
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getName() + " " + type + ": [" + from + ".." + to + ") "
-            + ((removed == null) ? "" : removed);
-    }
-}
--- a/modules/fxml/src/main/java/com/sun/javafx/fxml/ObservableMapChangeEvent.java	Fri Sep 06 13:22:16 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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 com.sun.javafx.fxml;
-
-import javafx.collections.ObservableMap;
-import javafx.event.Event;
-import javafx.event.EventType;
-
-/**
- * Observable map change event.
- */
-public class ObservableMapChangeEvent<K, V> extends Event {
-    private static final long serialVersionUID = 0;
-
-    private EventType<ObservableMapChangeEvent<?, ?>> type;
-    private K key;
-    private V removed;
-
-    public static final EventType<ObservableMapChangeEvent<?, ?>> ADD =
-        new EventType<ObservableMapChangeEvent<?, ?>>(EventType.ROOT, ObservableMapChangeEvent.class.getName() + "_ADD");
-    public static final EventType<ObservableMapChangeEvent<?, ?>> UPDATE =
-        new EventType<ObservableMapChangeEvent<?, ?>>(EventType.ROOT, ObservableMapChangeEvent.class.getName() + "_UPDATE");
-    public static final EventType<ObservableMapChangeEvent<?, ?>> REMOVE =
-        new EventType<ObservableMapChangeEvent<?, ?>>(EventType.ROOT, ObservableMapChangeEvent.class.getName() + "_REMOVE");
-
-    public ObservableMapChangeEvent(ObservableMap<K, V> source, EventType<ObservableMapChangeEvent<?, ?>> type,
-        K key, V removed) {
-        super(source, null, type);
-
-        this.type = type;
-        this.key = key;
-        this.removed = removed;
-    }
-
-    /**
-     * The key associated with the change.
-     */
-    public K getKey() {
-        return key;
-    }
-
-    /**
-     * They value that was removed as part of the change, or <tt>null</tt> if
-     * this change did not cause a value to be removed.
-     */
-    public V getRemoved() {
-        return removed;
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getName() + " " + type + ": " + key + " "
-            + ((removed == null) ? "" : removed);
-    }
-}
--- a/modules/fxml/src/main/java/javafx/fxml/FXMLLoader.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/fxml/src/main/java/javafx/fxml/FXMLLoader.java	Tue Sep 10 14:12:43 2013 -0700
@@ -50,15 +50,12 @@
 import java.util.Set;
 import java.util.regex.Pattern;
 
+import com.sun.javafx.fxml.*;
 import javafx.beans.DefaultProperty;
 import javafx.beans.property.Property;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
-import javafx.collections.FXCollections;
-import javafx.collections.ListChangeListener;
-import javafx.collections.MapChangeListener;
-import javafx.collections.ObservableList;
-import javafx.collections.ObservableMap;
+import javafx.collections.*;
 import javafx.event.Event;
 import javafx.event.EventHandler;
 import javafx.event.EventType;
@@ -79,12 +76,6 @@
 import javax.xml.stream.util.StreamReaderDelegate;
 
 import com.sun.javafx.beans.IDProperty;
-import com.sun.javafx.fxml.BeanAdapter;
-import com.sun.javafx.fxml.LoadListener;
-import com.sun.javafx.fxml.ObservableListChangeEvent;
-import com.sun.javafx.fxml.ObservableMapChangeEvent;
-import com.sun.javafx.fxml.PropertyChangeEvent;
-import com.sun.javafx.fxml.PropertyNotFoundException;
 import com.sun.javafx.fxml.expression.Expression;
 import com.sun.javafx.fxml.expression.ExpressionValue;
 import com.sun.javafx.fxml.expression.KeyPath;
@@ -106,7 +97,6 @@
     // Abstract base class for elements
     private abstract class Element {
         public final Element parent;
-        public final int lineNumber;
 
         public Object value = null;
         private BeanAdapter valueAdapter = null;
@@ -118,7 +108,6 @@
 
         public Element() {
             parent = current;
-            lineNumber = getLineNumber();
         }
 
         public boolean isCollection() {
@@ -389,13 +378,19 @@
                     warnDeprecatedEscapeSequence(RELATIVE_PATH_PREFIX);
                     return aValue;
                 } else {
-                    try {
-                        return (aValue.charAt(0) == '/') ?
-                                classLoader.getResource(aValue.substring(1)).toString() :
-                                new URL(FXMLLoader.this.location, aValue).toString();
-                    } catch (MalformedURLException e) {
-                        System.err.println(FXMLLoader.this.location + "/" + aValue);
-                    }
+                        if (aValue.charAt(0) == '/') {
+                            final URL res = classLoader.getResource(aValue.substring(1));
+                            if (res == null) {
+                                throw new LoadException("Invalid resource: " + aValue + " not found on the classpath");
+                            }
+                            return res.toString();
+                        } else {
+                            try {
+                                return new URL(FXMLLoader.this.location, aValue).toString();
+                            } catch (MalformedURLException e) {
+                                System.err.println(FXMLLoader.this.location + "/" + aValue);
+                            }
+                        }
                 }
             } else if (aValue.startsWith(RESOURCE_KEY_PREFIX)) {
                 aValue = aValue.substring(RESOURCE_KEY_PREFIX.length());
@@ -506,59 +501,82 @@
             }
         }
 
+        private <T> T getExpressionObjectOfType(String handlerName, Class<T> type) throws LoadException{
+            if (handlerName.startsWith(EXPRESSION_PREFIX)) {
+                handlerName = handlerName.substring(EXPRESSION_PREFIX.length());
+
+                if (handlerName.length() == 0) {
+                    throw new LoadException("Missing expression reference.");
+                }
+
+                Object expression = Expression.get(namespace, KeyPath.parse(handlerName));
+                if (type.isInstance(expression)) {
+                    return (T) expression;
+                }
+            }
+            return null;
+        }
+
+        private <T> MethodHandler<T> getControllerMethodHandle(String handlerName, Class<T> type) throws LoadException{
+            if (handlerName.startsWith(CONTROLLER_METHOD_PREFIX)) {
+                handlerName = handlerName.substring(CONTROLLER_METHOD_PREFIX.length());
+
+                if (!handlerName.startsWith(CONTROLLER_METHOD_PREFIX)) {
+                    if (handlerName.length() == 0) {
+                        throw new LoadException("Missing controller method.");
+                    }
+
+                    if (controller == null) {
+                        throw new LoadException("No controller specified.");
+                    }
+
+                    Method method = getControllerMethods().get(type).get(handlerName);
+                    if (method == null) {
+                        method = getControllerMethods().get(null).get(handlerName);
+                    }
+
+                    if (method == null) {
+                        return null;
+                    }
+
+                    return new MethodHandler<>(controller, method);
+                }
+
+            }
+            return null;
+        }
+
         public void processEventHandlerAttributes() throws LoadException {
             if (eventHandlerAttributes.size() > 0 && !staticLoad) {
                 for (Attribute attribute : eventHandlerAttributes) {
-                    EventHandler<? extends Event> eventHandler = null;
-
-                    String attrValue = attribute.value;
-
-                    if (attrValue.startsWith(CONTROLLER_METHOD_PREFIX)) {
-                        attrValue = attrValue.substring(CONTROLLER_METHOD_PREFIX.length());
-
-                        if (!attrValue.startsWith(CONTROLLER_METHOD_PREFIX)) {
-                            if (attrValue.length() == 0) {
-                                throw new LoadException("Missing controller method.");
+                    String handlerName = attribute.value;
+                    if (value instanceof ObservableList && attribute.name.equals(COLLECTION_HANDLER_NAME)) {
+                        processObservableListHandler(handlerName);
+                    } else if (value instanceof ObservableMap && attribute.name.equals(COLLECTION_HANDLER_NAME)) {
+                        processObservableMapHandler(handlerName);
+                    } else if (value instanceof ObservableSet && attribute.name.equals(COLLECTION_HANDLER_NAME)) {
+                        processObservableSetHandler(handlerName);
+                    } else {
+                        EventHandler<? extends Event> eventHandler = null;
+                        MethodHandler handler = getControllerMethodHandle(handlerName, Event.class);
+                        if (handler != null) {
+                            eventHandler = new ControllerMethodEventHandler<>(handler);
+                        }
+
+                        if (eventHandler == null) {
+                            eventHandler = getExpressionObjectOfType(handlerName, EventHandler.class);
+                        }
+
+                        if (eventHandler == null) {
+                            if (handlerName.length() == 0 || scriptEngine == null) {
+                                throw new LoadException("Error resolving " + attribute.name + "='" + attribute.value
+                                        + "', either the event handler is not in the Namespace or there is an error in the script.");
                             }
 
-                            if (controller == null) {
-                                throw new LoadException("No controller specified.");
-                            }
-
-                            Method method = getControllerMethods().get(attrValue);
-
-                            if (method == null) {
-                                throw new LoadException("Controller method \"" + attrValue + "\" not found.");
-                            }
-
-                            eventHandler = new ControllerMethodEventHandler(controller, method);
+                            eventHandler = new ScriptEventHandler(handlerName, scriptEngine);
                         }
 
-                    } else if (attrValue.startsWith(EXPRESSION_PREFIX)) {
-                        attrValue = attrValue.substring(EXPRESSION_PREFIX.length());
-
-                        if (attrValue.length() == 0) {
-                            throw new LoadException("Missing expression reference.");
-                        }
-
-                        Object expression = Expression.get(namespace, KeyPath.parse(attrValue));
-                        if (expression instanceof EventHandler) {
-                            eventHandler = (EventHandler<? extends Event>) expression;
-                        }
-
-                    }
-
-                    if (eventHandler == null) {
-                        if (attrValue.length() == 0 || scriptEngine == null) {
-                            throw new LoadException("Error resolving "  + attribute.name + "='" + attribute.value
-                                + "', either the event handler is not in the Namespace or there is an error in the script.");
-                        }
-
-                        eventHandler = new ScriptEventHandler(attrValue, scriptEngine);
-                    }
-
-                    // Add the handler
-                    if (eventHandler != null){
+                        // Add the handler
                         addEventHandler(attribute, eventHandler);
                     }
                 }
@@ -572,19 +590,7 @@
                 int i = EVENT_HANDLER_PREFIX.length();
                 int j = attribute.name.length() - CHANGE_EVENT_HANDLER_SUFFIX.length();
 
-                if (i == j) {
-                    if (value instanceof ObservableList<?>) {
-                        ObservableList<Object> list = (ObservableList<Object>)value;
-                        list.addListener(new ObservableListChangeAdapter(list,
-                            (EventHandler<ObservableListChangeEvent<?>>)eventHandler));
-                    } else if (value instanceof ObservableMap<?, ?>) {
-                        ObservableMap<Object, Object> map = (ObservableMap<Object, Object>)value;
-                        map.addListener(new ObservableMapChangeAdapter(map,
-                            (EventHandler<ObservableMapChangeEvent<?, ?>>)eventHandler));
-                    } else {
-                        throw new LoadException("Invalid event source.");
-                    }
-                } else {
+                if (i != j) {
                     String key = Character.toLowerCase(attribute.name.charAt(i))
                         + attribute.name.substring(i + 1, j);
 
@@ -601,6 +607,57 @@
                 getValueAdapter().put(attribute.name, eventHandler);
             }
         }
+
+        private void processObservableListHandler(String handlerName) throws LoadException {
+            ObservableList list = (ObservableList)value;
+            if (handlerName.startsWith(CONTROLLER_METHOD_PREFIX)) {
+                MethodHandler handler = getControllerMethodHandle(handlerName, ListChangeListener.Change.class);
+                if (handler != null) {
+                    list.addListener(new ObservableListChangeAdapter(list, handler));
+                } else {
+                    throw new LoadException("Controller method \"" + handlerName + "\" not found.");
+                }
+            } else if (handlerName.startsWith(EXPRESSION_PREFIX)) {
+                ListChangeListener listener = getExpressionObjectOfType(handlerName, ListChangeListener.class);
+                if (listener != null) {
+                    list.addListener(listener);
+                }
+            }
+        }
+
+        private void processObservableMapHandler(String handlerName) throws LoadException {
+            ObservableMap map = (ObservableMap)value;
+            if (handlerName.startsWith(CONTROLLER_METHOD_PREFIX)) {
+                MethodHandler handler = getControllerMethodHandle(handlerName, MapChangeListener.Change.class);
+                if (handler != null) {
+                    map.addListener(new ObservableMapChangeAdapter(map, handler));
+                } else {
+                    throw new LoadException("Controller method \"" + handlerName + "\" not found.");
+                }
+            } else if (handlerName.startsWith(EXPRESSION_PREFIX)) {
+                MapChangeListener listener = getExpressionObjectOfType(handlerName, MapChangeListener.class);
+                if (listener != null) {
+                    map.addListener(listener);
+                }
+            }
+        }
+
+        private void processObservableSetHandler(String handlerName) throws LoadException {
+            ObservableSet set = (ObservableSet)value;
+            if (handlerName.startsWith(CONTROLLER_METHOD_PREFIX)) {
+                MethodHandler handler = getControllerMethodHandle(handlerName, SetChangeListener.Change.class);
+                if (handler != null) {
+                    set.addListener(new ObservableSetChangeAdapter(set, handler));
+                } else {
+                    throw new LoadException("Controller method \"" + handlerName + "\" not found.");
+                }
+            } else if (handlerName.startsWith(EXPRESSION_PREFIX)) {
+                SetChangeListener listener = getExpressionObjectOfType(handlerName, SetChangeListener.class);
+                if (listener != null) {
+                    set.addListener(listener);
+                }
+            }
+        }
     }
 
     // Element representing a value
@@ -1482,19 +1539,144 @@
     }
 
     // Event handler that delegates to a method defined by the controller object
-    private static class ControllerMethodEventHandler implements EventHandler<Event> {
-        public final Object controller;
-        public final Method method;
-        public final boolean typed;
-
-        public ControllerMethodEventHandler(Object controller, Method method) {
+    private static class ControllerMethodEventHandler<T extends Event> implements EventHandler<T> {
+        private final MethodHandler<T> handler;
+
+        public ControllerMethodEventHandler(MethodHandler<T> handler) {
+            this.handler = handler;
+        }
+
+        @Override
+        public void handle(T event) {
+            handler.invoke(event);
+        }
+    }
+
+    // Event handler implemented in script code
+    private static class ScriptEventHandler implements EventHandler<Event> {
+        public final String script;
+        public final ScriptEngine scriptEngine;
+
+        public ScriptEventHandler(String script, ScriptEngine scriptEngine) {
+            this.script = script;
+            this.scriptEngine = scriptEngine;
+        }
+
+        @Override
+        public void handle(Event event) {
+            // Don't pollute the page namespace with values defined in the script
+            Bindings engineBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
+            Bindings localBindings = scriptEngine.createBindings();
+            localBindings.put(EVENT_KEY, event);
+            localBindings.putAll(engineBindings);
+            scriptEngine.setBindings(localBindings, ScriptContext.ENGINE_SCOPE);
+
+            // Execute the script
+            try {
+                scriptEngine.eval(script);
+            } catch (ScriptException exception){
+                throw new RuntimeException(exception);
+            }
+
+            // Restore the original bindings
+            scriptEngine.setBindings(engineBindings, ScriptContext.ENGINE_SCOPE);
+        }
+    }
+
+    // Observable list change listener
+    private static class ObservableListChangeAdapter implements ListChangeListener {
+        private final ObservableList source;
+        private final MethodHandler<Change> handler;
+
+        public ObservableListChangeAdapter(ObservableList source,
+                                           MethodHandler<Change> handler) {
+            this.source = source;
+            this.handler = handler;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void onChanged(Change change) {
+            if (handler != null) {
+                handler.invoke(change);
+            }
+        }
+    }
+
+    // Observable map change listener
+    private static class ObservableMapChangeAdapter implements MapChangeListener {
+        public final ObservableMap source;
+        public final MethodHandler<Change> handler;
+
+        public ObservableMapChangeAdapter(ObservableMap source,
+                                          MethodHandler<Change> handler) {
+            this.source = source;
+            this.handler = handler;
+        }
+
+        @Override
+        public void onChanged(Change change) {
+            if (handler != null) {
+                handler.invoke(change);
+            }
+        }
+    }
+
+    // Observable set change listener
+    private static class ObservableSetChangeAdapter implements SetChangeListener {
+        public final ObservableSet source;
+        public final MethodHandler<Change> handler;
+
+        public ObservableSetChangeAdapter(ObservableSet source,
+                                          MethodHandler<Change> handler) {
+            this.source = source;
+            this.handler = handler;
+        }
+
+        @Override
+        public void onChanged(Change change) {
+            if (handler != null) {
+                handler.invoke(change);
+            }
+        }
+    }
+
+    // Property model change listener
+    private static class PropertyChangeAdapter implements ChangeListener<Object> {
+        public final Object source;
+        public final EventHandler<PropertyChangeEvent<?>> handler;
+
+        public PropertyChangeAdapter(Object source, EventHandler<PropertyChangeEvent<?>> handler) {
+            if (source == null) {
+                throw new NullPointerException();
+            }
+
+            if (handler == null) {
+                throw new NullPointerException();
+            }
+
+            this.source = source;
+            this.handler = handler;
+        }
+
+        @Override
+        public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
+            handler.handle(new PropertyChangeEvent<Object>(source, oldValue));
+        }
+    }
+
+    private static class MethodHandler<E> {
+        private final Object controller;
+        private final Method method;
+        private final boolean typed;
+
+        private MethodHandler(Object controller, Method method) {
+            this.method = method;
             this.controller = controller;
-            this.method = method;
             this.typed = (method.getParameterTypes().length == 1);
         }
 
-        @Override
-        public void handle(Event event) {
+        public void invoke(E event) {
             try {
                 if (typed) {
                     MethodUtil.invoke(method, controller, new Object[] { event });
@@ -1509,128 +1691,6 @@
         }
     }
 
-    // Event handler implemented in script code
-    private static class ScriptEventHandler implements EventHandler<Event> {
-        public final String script;
-        public final ScriptEngine scriptEngine;
-
-        public ScriptEventHandler(String script, ScriptEngine scriptEngine) {
-            this.script = script;
-            this.scriptEngine = scriptEngine;
-        }
-
-        @Override
-        public void handle(Event event) {
-            // Don't pollute the page namespace with values defined in the script
-            Bindings engineBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
-            Bindings localBindings = scriptEngine.createBindings();
-            localBindings.put(EVENT_KEY, event);
-            localBindings.putAll(engineBindings);
-            scriptEngine.setBindings(localBindings, ScriptContext.ENGINE_SCOPE);
-
-            // Execute the script
-            try {
-                scriptEngine.eval(script);
-            } catch (ScriptException exception){
-                throw new RuntimeException(exception);
-            }
-
-            // Restore the original bindings
-            scriptEngine.setBindings(engineBindings, ScriptContext.ENGINE_SCOPE);
-        }
-    }
-
-    // Observable list change listener
-    private static class ObservableListChangeAdapter implements ListChangeListener<Object> {
-        public final ObservableList<Object> source;
-        public final EventHandler<ObservableListChangeEvent<?>> handler;
-
-        public ObservableListChangeAdapter(ObservableList<Object> source,
-            EventHandler<ObservableListChangeEvent<?>> handler) {
-            this.source = source;
-            this.handler = handler;
-        }
-
-        @Override
-        @SuppressWarnings("unchecked")
-        public void onChanged(Change<? extends Object> change) {
-            while (change.next()) {
-                EventType<ObservableListChangeEvent<?>> eventType;
-                List<Object> removed = (List<Object>)change.getRemoved();
-
-                if (change.wasPermutated()) {
-                    eventType = ObservableListChangeEvent.UPDATE;
-                    removed = null;
-                } else if (change.wasAdded() && change.wasRemoved()) {
-                    eventType = ObservableListChangeEvent.UPDATE;
-                } else if (change.wasAdded()) {
-                    eventType = ObservableListChangeEvent.ADD;
-                } else if (change.wasRemoved()) {
-                    eventType = ObservableListChangeEvent.REMOVE;
-                } else {
-                    throw new UnsupportedOperationException();
-                }
-
-                handler.handle(new ObservableListChangeEvent<Object>(source,
-                    eventType, change.getFrom(), change.getTo(),
-                    removed));
-            }
-        }
-    }
-
-    // Observable map change listener
-    private static class ObservableMapChangeAdapter implements MapChangeListener<Object, Object> {
-        public final ObservableMap<Object, Object> source;
-        public final EventHandler<ObservableMapChangeEvent<?, ?>> handler;
-
-        public ObservableMapChangeAdapter(ObservableMap<Object, Object> source,
-            EventHandler<ObservableMapChangeEvent<?, ?>> handler) {
-            this.source = source;
-            this.handler = handler;
-        }
-
-        @Override
-        public void onChanged(Change<? extends Object, ? extends Object> change) {
-            EventType<ObservableMapChangeEvent<?, ?>> eventType;
-            if (change.wasAdded() && change.wasRemoved()) {
-                eventType = ObservableMapChangeEvent.UPDATE;
-            } else if (change.wasAdded()) {
-                eventType = ObservableMapChangeEvent.ADD;
-            } else if (change.wasRemoved()) {
-                eventType = ObservableMapChangeEvent.REMOVE;
-            } else {
-                throw new UnsupportedOperationException();
-            }
-
-            handler.handle(new ObservableMapChangeEvent<Object, Object>(source,
-                eventType, change.getKey(), change.getValueRemoved()));
-        }
-    }
-
-    // Property model change listener
-    private static class PropertyChangeAdapter implements ChangeListener<Object> {
-        public final Object source;
-        public final EventHandler<PropertyChangeEvent<?>> handler;
-
-        public PropertyChangeAdapter(Object source, EventHandler<PropertyChangeEvent<?>> handler) {
-            if (source == null) {
-                throw new NullPointerException();
-            }
-
-            if (handler == null) {
-                throw new NullPointerException();
-            }
-
-            this.source = source;
-            this.handler = handler;
-        }
-
-        @Override
-        public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue) {
-            handler.handle(new PropertyChangeEvent<Object>(source, oldValue));
-        }
-    }
-
     /**
      * @since JavaFX 8.0
      */
@@ -1674,7 +1734,7 @@
     private HashMap<String, Class<?>> classes = new HashMap<String, Class<?>>();
 
     private HashMap<String, Field> controllerFields = null;
-    private HashMap<String, Method> controllerMethods = null;
+    private HashMap<Class, Map<String, Method>> controllerMethods = null;
 
     private ScriptEngineManager scriptEngineManager = null;
 
@@ -1726,6 +1786,7 @@
     public static final String EVENT_HANDLER_PREFIX = "on";
     public static final String EVENT_KEY = "event";
     public static final String CHANGE_EVENT_HANDLER_SUFFIX = "Change";
+    private static final String COLLECTION_HANDLER_NAME = EVENT_HANDLER_PREFIX + CHANGE_EVENT_HANDLER_SUFFIX;
 
     public static final String NULL_KEYWORD = "null";
 
@@ -2343,7 +2404,7 @@
                 }
 
                 // Initialize the controller
-                Method initializeMethod = getControllerMethods().get(INITIALIZE_METHOD_NAME);
+                Method initializeMethod = getControllerMethods().get(null).get(INITIALIZE_METHOD_NAME);
 
                 if (initializeMethod != null) {
                     try {
@@ -2386,7 +2447,7 @@
 
             if (loader.current != null) {
                 messageBuilder.append(":");
-                messageBuilder.append(loader.current.lineNumber);
+                messageBuilder.append(loader.getLineNumber());
             }
 
             messageBuilder.append("\n");
@@ -2428,7 +2489,7 @@
         int i = 0;
         for (FXMLLoader loader : loaders) {
             parseTrace[i++] = new ParseTraceElement(loader.location, (loader.current != null) ?
-                loader.current.lineNumber : -1);
+                loader.getLineNumber() : -1);
         }
 
         return parseTrace;
@@ -2736,9 +2797,26 @@
         return controllerFields;
     }
 
-    private HashMap<String, Method> getControllerMethods() throws LoadException {
+    private static final Class[] SUPPORTED_TYPES = { Event.class, ListChangeListener.Change.class,
+        MapChangeListener.Change.class, SetChangeListener.Change.class
+    };
+
+    private Class<?> toSupportedEventType(Class<?> type) {
+        for (Class c : SUPPORTED_TYPES) {
+            if (c.isAssignableFrom(type)) {
+                return c;
+            }
+        }
+        return null;
+    }
+
+    private HashMap<Class, Map<String, Method>> getControllerMethods() throws LoadException {
         if (controllerMethods == null) {
-            controllerMethods = new HashMap<String, Method>();
+            controllerMethods = new HashMap<>();
+            controllerMethods.put(null, new HashMap<String,Method>());
+            for (Class c: SUPPORTED_TYPES) {
+                controllerMethods.put(c, new HashMap<String,Method>());
+            }
 
             Class<?> controllerType = controller.getClass();
             Class<?> type = controllerType;
@@ -2771,14 +2849,17 @@
                         //    name has not already been defined
                         String methodName = method.getName();
                         Class<?>[] parameterTypes = method.getParameterTypes();
+                        Class convertedType;
 
                         if (methodName.equals(INITIALIZE_METHOD_NAME)) {
                             if (parameterTypes.length == 0) {
-                                controllerMethods.put(method.getName(), method);
+                                controllerMethods.get(null).put(method.getName(), method);
                             }
-                        } else if ((parameterTypes.length == 1 && Event.class.isAssignableFrom(parameterTypes[0]))
-                            || (parameterTypes.length == 0 && !controllerMethods.containsKey(methodName))) {
-                            controllerMethods.put(method.getName(), method);
+                        } else if (parameterTypes.length == 1 &&
+                                (convertedType = toSupportedEventType(parameterTypes[0])) != null) {
+                            controllerMethods.get(convertedType).put(methodName, method);
+                        } else if (parameterTypes.length == 0) {
+                            controllerMethods.get(null).put(methodName, method);
                         }
                     }
                 }
--- a/modules/fxml/src/test/java/javafx/fxml/RT_17714Controller.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/fxml/src/test/java/javafx/fxml/RT_17714Controller.java	Tue Sep 10 14:12:43 2013 -0700
@@ -25,69 +25,57 @@
 
 package javafx.fxml;
 
-import com.sun.javafx.fxml.ObservableListChangeEvent;
-import com.sun.javafx.fxml.ObservableMapChangeEvent;
 import java.net.URL;
 import java.util.*;
-import javafx.collections.ObservableList;
-import javafx.collections.ObservableMap;
+
+import javafx.collections.*;
 
 public class RT_17714Controller implements Initializable {
     @FXML private Widget root;
 
-    private ArrayList<Widget> children = new ArrayList<Widget>();
-    private HashMap<String, Object> properties = new HashMap<String, Object>();
+    boolean listWithParamCalled = false;
+    boolean listNoParamCalled = false;
+    boolean setWithParamCalled = false;
+    boolean setNoParamCalled = false;
+    boolean mapWithParamCalled = false;
+    boolean mapNoParamCalled = false;
+
 
     @Override
     public void initialize(URL location, ResourceBundle resources) {
-        children.addAll(root.getChildren());
-        properties.putAll(root.getProperties());
-    }
-
-    public List<Widget> getChildren() {
-        return children;
-    }
-
-    public Map<String, Object> getProperties() {
-        return properties;
     }
 
     @FXML
     @SuppressWarnings("unchecked")
-    protected void handleChildListChange(ObservableListChangeEvent<Widget> event) {
-        ObservableList<Widget> list = (ObservableList<Widget>)event.getSource();
-        int from = event.getFrom();
-        int to = event.getTo();
-        List<Widget> removed = event.getRemoved();
-
-        if (event.getEventType() == ObservableListChangeEvent.ADD) {
-            children.addAll(list.subList(from, to));
-        } else if (event.getEventType() == ObservableListChangeEvent.UPDATE) {
-            if (removed != null) {
-                for (int i = from, n = from + removed.size(); i < n; i++) {
-                    children.set(i, list.get(i));
-                }
-            }
-        } else if (event.getEventType() == ObservableListChangeEvent.REMOVE) {
-            children.subList(from, from + removed.size()).clear();
-        } else {
-            throw new UnsupportedOperationException();
-        }
+    protected void handleChildListChange(ListChangeListener.Change<Widget> event) {
+        listWithParamCalled = true;
+    }
+    @FXML
+    @SuppressWarnings("unchecked")
+    protected void handleChildListChange() {
+        listNoParamCalled = true;
     }
 
     @FXML
     @SuppressWarnings("unchecked")
-    protected void handlePropertiesChange(ObservableMapChangeEvent<String, Object> event) {
-        ObservableMap<String, Object> map = (ObservableMap<String, Object>)event.getSource();
-        String key = event.getKey();
+    protected void handlePropertiesChange(MapChangeListener.Change<String, Object> event) {
+        mapWithParamCalled = true;
+    }
 
-        if (event.getEventType() == ObservableMapChangeEvent.ADD
-            || event.getEventType() == ObservableMapChangeEvent.UPDATE) {
-            properties.put(key, map.get(key));
-        } else if (event.getEventType() == ObservableMapChangeEvent.REMOVE) {
-            properties.remove(key);
-        } else {
-            throw new UnsupportedOperationException();
-        }
+    @FXML
+    @SuppressWarnings("unchecked")
+    protected void handlePropertiesChange() {
+        mapNoParamCalled = true;
+    }
+
+    @FXML
+    @SuppressWarnings("unchecked")
+    protected void handleSetChange(SetChangeListener.Change<String> event) {
+        setWithParamCalled = true;
+    }
+    @FXML
+    @SuppressWarnings("unchecked")
+    protected void handleSetChange() {
+        setNoParamCalled = true;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxml/src/test/java/javafx/fxml/RT_17714Controller2.java	Tue Sep 10 14:12:43 2013 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010, 2013, 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 javafx.fxml;
+
+import javafx.collections.ListChangeListener;
+import javafx.collections.MapChangeListener;
+import javafx.collections.SetChangeListener;
+
+import java.net.URL;
+import java.util.ResourceBundle;
+
+public class RT_17714Controller2 implements Initializable {
+    @FXML private Widget root;
+
+    boolean listNoParamCalled = false;
+    boolean setNoParamCalled = false;
+    boolean mapNoParamCalled = false;
+
+
+    @Override
+    public void initialize(URL location, ResourceBundle resources) {
+    }
+
+    @FXML
+    @SuppressWarnings("unchecked")
+    protected void handleChildListChange() {
+        listNoParamCalled = true;
+    }
+
+    @FXML
+    @SuppressWarnings("unchecked")
+    protected void handlePropertiesChange() {
+        mapNoParamCalled = true;
+    }
+
+    @FXML
+    @SuppressWarnings("unchecked")
+    protected void handleSetChange() {
+        setNoParamCalled = true;
+    }
+}
\ No newline at end of file
--- a/modules/fxml/src/test/java/javafx/fxml/RT_17714Test.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/fxml/src/test/java/javafx/fxml/RT_17714Test.java	Tue Sep 10 14:12:43 2013 -0700
@@ -25,6 +25,7 @@
 
 package javafx.fxml;
 
+import javafx.util.Callback;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
@@ -36,24 +37,12 @@
         Widget widget = (Widget)fxmlLoader.load();
         RT_17714Controller controller = (RT_17714Controller)fxmlLoader.getController();
 
-        assertEquals(widget.getChildren(), controller.getChildren());
-
-        // Test add
+        assertFalse(controller.listWithParamCalled);
+        assertFalse(controller.listNoParamCalled);
+        // Test
         widget.getChildren().add(new Widget("Widget 4"));
-        widget.getChildren().add(new Widget("Widget 5"));
-
-        assertEquals(widget.getChildren(), controller.getChildren());
-
-        // Test update
-        widget.getChildren().set(0, new Widget("Widget 1a"));
-        widget.getChildren().set(2, new Widget("Widget 3a"));
-
-        assertEquals(widget.getChildren(), controller.getChildren());
-
-        // Test remove
-        widget.getChildren().remove(1);
-
-        assertEquals(widget.getChildren(), controller.getChildren());
+        assertTrue(controller.listWithParamCalled);
+        assertFalse(controller.listNoParamCalled);
     }
 
     @Test
@@ -62,23 +51,80 @@
         Widget widget = (Widget)fxmlLoader.load();
         RT_17714Controller controller = (RT_17714Controller)fxmlLoader.getController();
 
-        assertEquals(widget.getProperties(), controller.getProperties());
+        assertFalse(controller.mapWithParamCalled);
+        assertFalse(controller.mapNoParamCalled);
+        // Test
+        widget.getProperties().put("d", 1000);
 
-        // Test add
+        assertTrue(controller.mapWithParamCalled);
+        assertFalse(controller.mapNoParamCalled);
+    }
+
+    @Test
+    public void testSetEvents() throws Exception {
+        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("rt_17714.fxml"));
+        Widget widget = (Widget)fxmlLoader.load();
+        RT_17714Controller controller = (RT_17714Controller)fxmlLoader.getController();
+
+        assertFalse(controller.setWithParamCalled);
+        assertFalse(controller.setNoParamCalled);
+        // Test
+        widget.getSet().add("x");
+
+        assertTrue(controller.setWithParamCalled);
+        assertFalse(controller.setNoParamCalled);
+    }
+
+    @Test
+    public void testListEvents_NoParam() throws Exception {
+        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("rt_17714.fxml"), null, null, new Callback<Class<?>, Object>() {
+            @Override
+            public Object call(Class<?> param) {
+                return new RT_17714Controller2();
+            }
+        });
+        Widget widget = (Widget)fxmlLoader.load();
+        RT_17714Controller2 controller = (RT_17714Controller2)fxmlLoader.getController();
+
+        assertFalse(controller.listNoParamCalled);
+        // Test
+        widget.getChildren().add(new Widget("Widget 4"));
+        assertTrue(controller.listNoParamCalled);
+    }
+
+    @Test
+    public void testMapEvents_NoParam() throws Exception {
+        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("rt_17714.fxml"), null, null, new Callback<Class<?>, Object>() {
+            @Override
+            public Object call(Class<?> param) {
+                return new RT_17714Controller2();
+            }
+        });
+        Widget widget = (Widget)fxmlLoader.load();
+        RT_17714Controller2 controller = (RT_17714Controller2)fxmlLoader.getController();
+
+        assertFalse(controller.mapNoParamCalled);
+        // Test
         widget.getProperties().put("d", 1000);
-        widget.getProperties().put("e", 10000);
 
-        assertEquals(widget.getProperties(), controller.getProperties());
+        assertTrue(controller.mapNoParamCalled);
+    }
 
-        // Test update
-        widget.getProperties().put("a", 2);
-        widget.getProperties().put("c", 200);
+    @Test
+    public void testSetEvents_NoParam() throws Exception {
+        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("rt_17714.fxml"), null, null, new Callback<Class<?>, Object>() {
+            @Override
+            public Object call(Class<?> param) {
+                return new RT_17714Controller2();
+            }
+        });
+        Widget widget = (Widget)fxmlLoader.load();
+        RT_17714Controller2 controller = (RT_17714Controller2)fxmlLoader.getController();
 
-        assertEquals(widget.getProperties(), controller.getProperties());
+        assertFalse(controller.setNoParamCalled);
+        // Test
+        widget.getSet().add("x");
 
-        // Test remove
-        widget.getProperties().remove("b");
-
-        assertEquals(widget.getProperties(), controller.getProperties());
+        assertTrue(controller.setNoParamCalled);
     }
 }
--- a/modules/fxml/src/test/java/javafx/fxml/Widget.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/fxml/src/test/java/javafx/fxml/Widget.java	Tue Sep 10 14:12:43 2013 -0700
@@ -39,6 +39,7 @@
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 import javafx.collections.ObservableMap;
+import javafx.collections.ObservableSet;
 
 @IDProperty("id")
 @DefaultProperty("children")
@@ -47,6 +48,7 @@
     private StringProperty name = new SimpleStringProperty();
     private IntegerProperty number = new SimpleIntegerProperty();
     private ObservableList<Widget> children = FXCollections.observableArrayList();
+    private ObservableSet<String> set = FXCollections.observableSet();
     private ObservableMap<String, Object> properties = FXCollections.observableHashMap();
     private BooleanProperty enabledProperty = new SimpleBooleanProperty(true);
     private ArrayList<String> styles = new ArrayList<String>();
@@ -154,6 +156,10 @@
         this.names = Arrays.copyOf(names, names.length);
     }
 
+    public ObservableSet<String> getSet() {
+        return set;
+    }
+
 
     public static Alignment getAlignment(Widget widget) {
         return (Alignment)widget.getProperties().get(ALIGNMENT_KEY);
--- a/modules/fxml/src/test/resources/javafx/fxml/rt_17714.fxml	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/fxml/src/test/resources/javafx/fxml/rt_17714.fxml	Tue Sep 10 14:12:43 2013 -0700
@@ -35,4 +35,5 @@
     </children>
     
     <properties a="1" b="10" c="100" onChange="#handlePropertiesChange"/>
+    <set onChange="#handleSetChange"/>
 </Widget>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/DalvikLauncher.java	Tue Sep 10 14:12:43 2013 -0700
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013 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 com.oracle.dalvik;
+
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Log;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+public class DalvikLauncher implements Launcher {
+
+    private static final String TAG                                     = "DalvikLauncher";
+    private static final String JAVAFX_APPLICATION_APPLICATION          = "javafx.application.Application";
+	private static final String COM_SUN_JAVAFX_APPLICATION_LAUNCHERIMPL = "com.sun.javafx.application.LauncherImpl";
+	private static final String LAUNCH_APPLICATION_METHOD               = "launchApplication";
+	private static final String MAIN_METHOD                             = "main";
+    private static final String META_DATA_MAIN_CLASS                    = "main.class";
+	private static final String META_DATA_PRELOADER_CLASS               = "preloader.class";    
+    private static final String ANDROID_PROPERTY_PREFIX                 = "android.";
+    
+    private static final Class[] LAUNCH_APPLICATION_ARGS = new Class[] {
+			Class.class, Class.class, (new String[0]).getClass() };
+
+	private static final Class[] MAIN_METHOD_ARGS = new Class[] { 
+			(new String[0]).getClass() };
+    
+    private static boolean fxApplicationLaunched = false;
+	private static boolean fxApplicationLaunching = false;
+    
+    private Activity    activity;
+    private Bundle      metadata;
+    
+    public void launchApp(Activity a, Bundle metadata) {
+        this.activity = a;
+        this.metadata = metadata;
+        Properties userProperties = new Properties();
+		try {
+			userProperties.load(DalvikLauncher.class.getResourceAsStream("/javafx.platform.properties"));
+			String key = null;
+            for(Entry<Object, Object> e:userProperties.entrySet()) {
+                key = (String)e.getKey();
+                System.setProperty(key.startsWith(ANDROID_PROPERTY_PREFIX) ?
+                    key.substring(ANDROID_PROPERTY_PREFIX.length()) : key,
+                    (String)e.getValue());
+			}
+			System.getProperties().list(System.out);
+			
+		} catch (IOException e) {
+			throw new RuntimeException("Can't load properties", e);
+		}
+        
+        Log.v(TAG, "Launch JavaFX application on dalvik vm.");
+        try {            
+			final Class applicationClass = resolveApplicationClass();
+			final Class preloaderClass = resolvePreloaderClass();
+			final Class javafxApplicationClass = Class.forName(JAVAFX_APPLICATION_APPLICATION);
+			final Class javafxLauncherClass = Class.forName(COM_SUN_JAVAFX_APPLICATION_LAUNCHERIMPL);
+	
+			final Method launchMethod = javafxLauncherClass.getMethod(
+					LAUNCH_APPLICATION_METHOD, LAUNCH_APPLICATION_ARGS);
+					
+            Log.v(TAG, String.format("application class: [%s]\n"
+                    + "preloader class: [%s]\n"
+                    + "javafx application class: [%s]\n"
+                    + "javafx launcher class: [%s]\n"
+                    + "launch application method: [%s]",
+                    applicationClass, 
+                    preloaderClass, 
+                    javafxApplicationClass, 
+                    javafxLauncherClass,
+                    launchMethod));
+			
+			new Thread(new Runnable() {
+				public void run() {
+					fxApplicationLaunching = true;					
+					try {
+						if (javafxApplicationClass.isAssignableFrom(applicationClass)) {
+							launchMethod.invoke(null, new Object[] {
+									applicationClass, preloaderClass,
+									new String[] {} });
+						} else {
+							Method mainMethod = applicationClass.getMethod(
+									MAIN_METHOD, MAIN_METHOD_ARGS);
+							mainMethod.invoke(null,
+									new Object[] { new String[] {} });
+						}
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+					fxApplicationLaunched = true;
+					fxApplicationLaunching = false;
+				}
+			}, "Prelauncher Thread").start();
+	
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+    }
+    
+    private Class resolveApplicationClass()
+			throws PackageManager.NameNotFoundException, ClassNotFoundException {
+
+		Class clazz = null;
+        String applicationClassName = metadata.getString(META_DATA_MAIN_CLASS);
+		if (applicationClassName != null && applicationClassName.length() > 0) {
+			clazz = Class.forName(applicationClassName);
+		}
+		return clazz;
+	}
+    
+    private Class resolvePreloaderClass()
+			throws PackageManager.NameNotFoundException, ClassNotFoundException {
+
+		Class clazz = null;
+        String className = metadata.getString(META_DATA_PRELOADER_CLASS);
+		if (className != null && className.length() > 0) {
+			clazz = Class.forName(className);
+		}
+		return clazz;
+	}
+    
+}
--- a/modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java	Tue Sep 10 14:12:43 2013 -0700
@@ -24,10 +24,6 @@
  */
 package com.oracle.dalvik;
 
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.List;
 
 import android.app.Activity;
 import android.content.Context;
@@ -35,7 +31,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.graphics.PixelFormat;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -53,28 +48,18 @@
         SurfaceHolder.Callback2 {
 	
     private static final String TAG     = "FXActivity";
-    private static final String TAG_JVM = "JVM";
-    private static final String JAR     = ".jar";
     
-    private static final String META_DATA_MAIN_CLASS = "main.class";
-    private static final String META_DATA_JVM_ARGS   = "jvm.args";
-    private static final String META_DATA_APP_ARGS   = "app.args";
-    private static final String META_DATA_DEBUG_PORT = "debug.port";
-    private static final String ANDROID_WEBVIEW = "android_webview";
-    private static final String GLASS_LENS_ANDROID = "glass_lens_android";
+    private static final String GLASS_LENS_ANDROID_LIB      = "glass_lens_android";
+    private static final String META_DATA_LAUNCHER_CLASS    = "launcher.class";
+    private static final String DEFAULT_LAUNCHER_CLASS      = "com.oracle.dalvik.JavaSELauncher";
+    
+    private static FXActivity   instance;
+    private static Launcher     launcher;
+    private static FrameLayout  mViewGroup;
+    private static SurfaceView  mView;
 
-    static {        
-        System.loadLibrary("vmlauncher");
-    }
-    private static FXActivity instance;
-    private static FrameLayout mViewGroup;
-    private static SurfaceView mView;
-
-    private String            appDataDir;
-    private String            storageDir;    
-    private NativePipeReader  reader;
-    private InputMethodManager imm;   
-    private String ldPath;
+    private String              appDataDir;
+    private InputMethodManager  imm;   
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -93,51 +78,71 @@
         mViewGroup = new FrameLayout(this);
         mViewGroup.addView(mView);
         setContentView(mViewGroup);
-        instance = this;
-        reader = NativePipeReader.getDefaultReader(textListener);
-        reader.start();
-        initDirInfo();
-        installJVMIfNeeded();
-        System.loadLibrary(GLASS_LENS_ANDROID);
-        System.loadLibrary(ANDROID_WEBVIEW);
+        instance = this;     
+        Log.v(TAG, "Loading glass native library.");
+        System.loadLibrary(GLASS_LENS_ANDROID_LIB);        
+    }
+    
+    private Bundle getMetadata() {
+        try {
+            ActivityInfo ai = FXActivity.this.getPackageManager().getActivityInfo(
+                    getIntent().getComponent(), PackageManager.GET_META_DATA);
+            return ai.metaData;
+
+        } catch(NameNotFoundException e) {
+            throw new RuntimeException("Error getting activity info", e);
+        }
     }
 
+    private void getLauncherAndLaunchApplication() {
+        Bundle metaData = getMetadata();
+        String launcherClass = metaData.getString(
+                META_DATA_LAUNCHER_CLASS,
+                DEFAULT_LAUNCHER_CLASS);
+        try {
+            Class clazz = Class.forName(launcherClass);
+            launcher = (Launcher)clazz.newInstance();
+            launcher.launchApp(this, metaData);
+            
+        } catch (Exception ex) {
+            throw new RuntimeException("Did not created correct launcher.", ex);
+        }
+    }
+    
     @Override
     protected void onDestroy() {
         android.os.Process.killProcess(android.os.Process.myPid());
         super.onDestroy();
     }
     
-    
-
     public static FXActivity getInstance() {
         return instance;
     }
 
-    public String getLDPath() {
+    public String getDataDir() {
         if (appDataDir == null) {
             appDataDir = this.getApplicationInfo().dataDir;
-        }
-        if (ldPath == null) {
-            ldPath = appDataDir + "/lib";
-        }
-        return ldPath;
+        }        
+        return appDataDir;
     }
-
+    
     public static ViewGroup getViewGroup() {
         return mViewGroup;
     }    
 	
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
-            _surfaceChanged(holder.getSurface());
+        Log.v(TAG, "Surface created.");
+        _surfaceChanged(holder.getSurface());
+        if (launcher == null) {
+            getLauncherAndLaunchApplication();
+        }
     }
 
     @Override
     public void surfaceChanged(SurfaceHolder holder, int format, int width,
                     int height) {
             _surfaceChanged(holder.getSurface(), format, width, height);
-
     }
 
     @Override
@@ -170,162 +175,6 @@
         Log.e(TAG, "VM SHUTDOWN");
         finish();
     }
-
-    private void installJVMIfNeeded() {
-        new InstallerTask().execute();
-    }
-	
-    private void runJVM() {
-        Log.i(TAG, "Launch JVM + application");
-        JvmArgs args = new JvmArgs(appDataDir);
-        VMLauncher.initialize(args.getJavaHome());
-        VMLauncher.runOnDebugPort(args.getDebugPort(),
-                                  args.getArgArray());
-    }
-	
-    private class InstallerTask extends AsyncTask<Void, Void, Void> {
-        protected Void doInBackground(Void... args) {
-           Log.i(TAG, "Installing JVM");
-            AppDataInstaller installer = 
-                new AppDataInstaller(storageDir,
-                    FXActivity.this.getApplicationContext().getAssets());
-            installer.install();
-            return null;
-        }
-    protected void onPostExecute(Void result) {
-            runJVM();
-        }
-    }
-	
-    private NativePipeReader.OnTextReceivedListener textListener = 
-            new NativePipeReader.OnTextReceivedListener() {
-                public void onTextReceived(String text) {
-                    Log.v(TAG_JVM, text);
-                }
-            };
-
-    private void initDirInfo() {
-        if (appDataDir == null) {
-            appDataDir = this.getApplicationInfo().dataDir;
-        }
-        storageDir = appDataDir + "/storage";
-    }
-	
-    private class JvmArgs {
-        private List<String> argList = new ArrayList<String>();
-        private String javaHome;
-
-        public JvmArgs(String appDir) {
-            String jvmRunCommand =
-                   "-Djava.library.path="
-                     + appDir + "/lib|"
-                     + "-Djava.home="
-                     + appDir + "/storage/jvm|"
-                     + "-Dsun.boot.library.path="
-                     + appDir + "/storage/jvm/lib|"
-                     + "-cp|"
-                     + getClasspath(appDir)
-                     + "|"                                         
-                     + "-Djavafx.platform=android|"
-                     + "-Djavafx.runtime.path="
-                     + appDir +"/storage/lib|"
-                     + getCustomJVMArgs()
-                     + "|"
-                     + getMainClass()
-                     + "|"
-                     + getApplicationArgs();
-
-            createArgList(jvmRunCommand);
-        }
-
-        private String[] listFiles(String dir, final String suffix) {
-            File dirf = new File(dir);
-            if (!dirf.exists()) {
-                return new String[]{};
-            }
-            String[] files = dirf.list(new FilenameFilter() {           
-                @Override
-                public boolean accept(File dir, String filename) {      
-                    return filename.endsWith(suffix);
-                }
-            });
-            return files;
-        }
-
-        private String getClasspath(String appDir) {
-            final String libDir = appDir + "/storage/lib/";
-            String[] libfiles = listFiles(libDir, JAR);
-            if (libfiles.length == 0) {
-                return "";
-            }
-            StringBuilder sb = new StringBuilder();
-            for(String file: libfiles) {
-                sb.append(libDir);
-                sb.append(file);
-                sb.append(File.pathSeparatorChar);
-            }
-            int len = sb.length();
-            return sb.substring(0, len - 1);
-        }
-
-        private String getMainClass() {
-             return getMetadata().getString(META_DATA_MAIN_CLASS);
-        }
-
-        private String getCustomJVMArgs() {
-             return getMetadata().getString(META_DATA_JVM_ARGS);
-        }
-
-        private String getApplicationArgs() {
-             return getMetadata().getString(META_DATA_APP_ARGS);
-        }
-
-        private int getDebugPort() {            
-             return getMetadata().getInt(META_DATA_DEBUG_PORT, 0);
-        }
-
-        private Bundle getMetadata() {
-            try {
-                ActivityInfo ai = FXActivity.this.getPackageManager().getActivityInfo(
-                        getIntent().getComponent(), PackageManager.GET_META_DATA);
-                return ai.metaData;
-
-            } catch(NameNotFoundException e) {
-                throw new RuntimeException("Error getting activity info", e);
-            }
-        }
-
-        public void createArgList(String args) {
-            if (args != null) {
-                String sep = (args.contains("|")) ? "\\|" : " ";
-                for (String arg : args.split(sep)) {
-                    arg = arg.trim();
-                    if (arg.length() > 0) {
-                        this.argList.add(arg);
-                        if (javaHome == null) {
-                            String[] pair = arg.split("\\=");
-                            Log.v(TAG, "arg = " + arg);
-                            Log.v(TAG, "pair.length = " + pair.length);
-                            if (pair.length == 2) {
-                                if ("-Djava.home".equals(pair[0])) {
-                                    Log.v(TAG, "Setting javaHome to " + pair[1]);
-                                    javaHome = pair[1];
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        
-        public String[] getArgArray() {
-            return argList.toArray(new String[0]);
-        }
-
-        public String getJavaHome() {
-           return javaHome;
-        }
-    }
 	
     class InternalSurfaceView extends SurfaceView {
 
--- a/modules/graphics/src/android/java/com/oracle/dalvik/FXActivity.java.jfx78	Fri Sep 06 13:22:16 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-package com.oracle.dalvik;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.Map.Entry;
-import java.util.Properties;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Configuration;
-import android.graphics.PixelFormat;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.FrameLayout;
-
-public class FXActivity extends Activity implements SurfaceHolder.Callback, SurfaceHolder.Callback2 {
-
-	private static final String TAG = "FXActivity";
-	
-	private static final String JAVAFX_APPLICATION_APPLICATION = "javafx.application.Application";
-
-	private static final String COM_SUN_JAVAFX_APPLICATION_LAUNCHERIMPL = "com.sun.javafx.application.LauncherImpl";
-
-	private static final String LAUNCH_APPLICATION_METHOD = "launchApplication";
-
-	private static final String MAIN_METHOD = "main";
-
-	private static final Class[] LAUNCH_APPLICATION_ARGS = new Class[] {
-			Class.class, Class.class, (new String[0]).getClass() };
-
-	private static final Class[] MAIN_METHOD_ARGS = new Class[] { 
-			(new String[0]).getClass() };
-
-//	private static final String JFX_APPLICATION_ATTRIBUTE = "JavaFX-Application-Class";
-    private static final String META_DATA_MAIN_CLASS = "main.class";
-	private static final String JFX_PRELOADER_ATTRIBUTE = "preloader.class";
-//	private static final String JFX_MAIN_ATTRIBUTE = "main.class";
-    private static final String GLASS_LENS_ANDROID = "glass_lens_android";
-	
-
-	private static int orientation;		
-//	private static FXActivity instance;
-	private static boolean fxApplicationLaunched = false;
-	private static boolean fxApplicationLaunching = false;
-	
-    private static FXActivity instance;
-    private static FrameLayout mViewGroup;
-    private static SurfaceView mView;
-
-    private String            appDataDir;
-    private String            storageDir;    
-    private NativePipeReader  reader;
-    private InputMethodManager imm;   
-    private String ldPath;
-    
-	public FXActivity() {
-		super();
-		
-		Properties userProperties = new Properties();
-//		try {
-//			userProperties.load(FXActivity.class.getResourceAsStream("/javafx.platform.properties"));
-//			for(Entry<Object, Object> e:userProperties.entrySet()) {
-//				System.setProperty((String)e.getKey(), (String)e.getValue());
-//			}
-//			System.getProperties().list(System.out);
-//			
-//		} catch (IOException e) {
-//			e.printStackTrace();
-//		}
-	}
-	
-//	public static FXActivity getInstance() {
-//		if (instance == null) {
-//			System.err.println("Activity not initialized.");
-//		}
-//		return instance;
-//	}
-	
-	@Override
-	public void onCreate(final Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		
-		//DEBUGGING
-		//Debug.waitForDebugger();										
-		//DEBUGGING
-		
-//        FXActivity.instance = this;    
-        
-        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
-        getWindow().setSoftInputMode(
-                WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
-                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
-        getWindow().setFormat(PixelFormat.RGBA_8888);
-
-        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-
-        mView = new FXActivity.InternalSurfaceView(this);
-        mView.getHolder().addCallback(this);        
-        mViewGroup = new FrameLayout(this);
-        mViewGroup.addView(mView);
-        setContentView(mViewGroup);
-        instance = this;        
-        System.loadLibrary(GLASS_LENS_ANDROID);
-//        System.loadLibrary(ANDROID_WEBVIEW);
-        
-        //AndroidViewGroup is FrameLayout and holds GLSurfaceView. 
-//        setContentView(AndroidViewGroup.getInstance());
-    	
-        //launch main class
-    	launchFXApplication();
-	}
-	
-    public static FXActivity getInstance() {
-        return instance;
-    }
-
-    public String getLDPath() {
-        if (appDataDir == null) {
-            appDataDir = this.getApplicationInfo().dataDir;
-        }
-        if (ldPath == null) {
-            ldPath = appDataDir + "/lib";
-        }
-        return ldPath;
-    }
-
-    public static ViewGroup getViewGroup() {
-        return mViewGroup;
-    }    
-	
-    @Override
-    public void surfaceCreated(SurfaceHolder holder) {
-            _surfaceChanged(holder.getSurface());
-    }
-
-    @Override
-    public void surfaceChanged(SurfaceHolder holder, int format, int width,
-                    int height) {
-            _surfaceChanged(holder.getSurface(), format, width, height);
-
-    }
-
-    @Override
-    public void surfaceDestroyed(SurfaceHolder holder) {
-            _surfaceChanged(null);
-    }
-
-    @Override
-    public void surfaceRedrawNeeded(SurfaceHolder holder) {
-            _surfaceRedrawNeeded(holder.getSurface());		
-    }
-
-    private native void _surfaceChanged(Surface surface);
-
-    private native void _surfaceChanged(Surface surface, int format, int width, int height);
-
-    private native void _surfaceRedrawNeeded(Surface surface);
-
-    private void showIME() {
-        mView.requestFocus();
-        imm.showSoftInput(mView, 0);
-    }
-
-    private void hideIME() {
-        mView.requestFocus();
-        imm.hideSoftInputFromWindow(mView.getWindowToken(), 0);
-    }
-    
-	@Override
-	public void onConfigurationChanged(Configuration newConfig) {
-		super.onConfigurationChanged(newConfig);
-//		if (newConfig.orientation != FXActivity.orientation) {
-//			Log.d(TAG, "orientation has changed");
-//			AndroidApplication.getInstance().notifyScreenSettingsChanged();
-//		}
-	}
-	
-	@Override
-	protected void onStart() {
-		super.onStart();
-		Log.d("onStart", "Activity started");
-//		Configuration startingConfiguration = getResources().getConfiguration();
-//		orientation = startingConfiguration.orientation;
-	}
-	
-	@Override
-	protected void onPause() {		
-		super.onPause();
-		Log.d("onPause", "Activity paused");
-	}
-	
-	@Override
-	protected void onResume() {
-		super.onResume();
-		Log.d("onResume", "Activity resumed");
-	}
-	
-	@Override
-	protected void onStop() {
-		super.onStop();
-		Log.d("onStop", "Activity stoped");
-	}
-	
-	@Override
-	protected void onRestart() {
-		super.onRestart();
-		Log.d("onRestart", "Activity re-started");
-	}
-	
-	public void launchFXApplication() {
-	    try {
-			final Class applicationClass = resolveApplicationClass();
-			final Class preloaderClass = resolvePreloaderClass();
-			final Class javafxApplicationClass = Class.forName(JAVAFX_APPLICATION_APPLICATION);
-			final Class javafxLauncherClass = Class.forName(COM_SUN_JAVAFX_APPLICATION_LAUNCHERIMPL);
-	
-			final Method launchMethod = javafxLauncherClass.getMethod(
-					LAUNCH_APPLICATION_METHOD, LAUNCH_APPLICATION_ARGS);
-						
-			
-			new Thread(new Runnable() {
-				public void run() {
-					fxApplicationLaunching = true;					
-					try {
-						if (javafxApplicationClass.isAssignableFrom(applicationClass)) {
-							launchMethod.invoke(null, new Object[] {
-									applicationClass, preloaderClass,
-									new String[] {} });
-						} else {
-							Method mainMethod = applicationClass.getMethod(
-									MAIN_METHOD, MAIN_METHOD_ARGS);
-							mainMethod.invoke(null,
-									new Object[] { new String[] {} });
-						}
-					} catch (Exception e) {
-						e.printStackTrace();
-					}
-					fxApplicationLaunched = true;
-					fxApplicationLaunching = false;
-				}
-			}, "Prelauncher Thread").start();
-	
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-    }
-    
-    private Bundle getMetadata() {
-        try {
-            ActivityInfo ai = FXActivity.this.getPackageManager().getActivityInfo(
-                    getIntent().getComponent(), PackageManager.GET_META_DATA);
-            return ai.metaData;
-
-        } catch(NameNotFoundException e) {
-            throw new RuntimeException("Error getting activity info", e);
-        }
-    }
-    
-    private Class resolveApplicationClass()
-			throws NameNotFoundException, ClassNotFoundException {
-
-		Class clazz = null;
-//		String applicationClassName = getPackageManager().getActivityInfo(
-//				new ComponentName(this, getClass()),
-//				PackageManager.GET_META_DATA).metaData
-//				.getString(JFX_APPLICATION_ATTRIBUTE);
-        String applicationClassName = getMetadata().getString(META_DATA_MAIN_CLASS);
-
-//		if (applicationClassName == null) {
-//			applicationClassName = getPackageManager().getActivityInfo(
-//					new ComponentName(this, getClass()),
-//					PackageManager.GET_META_DATA).metaData
-//					.getString(JFX_MAIN_ATTRIBUTE);
-//		}
-		if (applicationClassName != null && applicationClassName.length() > 0) {
-			clazz = Class.forName(applicationClassName);
-		}
-		return clazz;
-	}
-
-	private Class resolvePreloaderClass()
-			throws NameNotFoundException, ClassNotFoundException {
-
-		Class clazz = null;
-//		String className = getPackageManager().getActivityInfo(
-//				new ComponentName(this, getClass()),
-//				PackageManager.GET_META_DATA).metaData
-//				.getString(JFX_PRELOADER_ATTRIBUTE);
-
-        String className = getMetadata().getString(JFX_PRELOADER_ATTRIBUTE);
-		if (className != null && className.length() > 0) {
-			clazz = Class.forName(className);
-		}
-		return clazz;
-	}
-    
-    class InternalSurfaceView extends SurfaceView {
-
-        public InternalSurfaceView(Context context) {
-            super(context);
-            setFocusableInTouchMode(true);
-        }
-
-        @Override
-        public boolean dispatchTouchEvent(MotionEvent event) {
-            onTouchEventNative(event.getAction(), (int) event.getX(), (int) event.getY());
-            return true;
-        }
-
-        @Override
-        public boolean dispatchKeyEvent(KeyEvent event) {
-            onKeyEventNative(event.getAction(), event.getKeyCode(), event.getCharacters());
-            return true;
-        }
-
-        private native void onTouchEventNative(int action, int absx, int absy);
-
-        private native void onKeyEventNative(int action, int keycode, String characters);
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/JavaSELauncher.java	Tue Sep 10 14:12:43 2013 -0700
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2013 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 com.oracle.dalvik;
+
+import android.app.Activity;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JavaSELauncher implements Launcher, NativePipeReader.OnTextReceivedListener {
+
+    private static final String TAG                     = "JavaSELauncher";
+    private static final String TAG_JVM                 = "JavaSE";
+    
+    private static final String VMLAUNCHER_LIB          = "vmlauncher";
+    private static final String ANDROID_WEBVIEW_LIB     = "android_webview";
+    
+    private static final String META_DATA_MAIN_CLASS    = "main.class";
+    private static final String META_DATA_JVM_ARGS      = "jvm.args";
+    private static final String META_DATA_APP_ARGS      = "app.args";
+    private static final String META_DATA_DEBUG_PORT    = "debug.port";
+    private static final String JAR_EXT                 = ".jar";
+    
+    private Bundle              metaData;
+    private Activity            activity;
+    private NativePipeReader    reader;
+    private String              appDataDir;
+    private String              storageDir;
+    
+    public JavaSELauncher() {
+        System.loadLibrary(VMLAUNCHER_LIB);
+    }
+    
+    public void launchApp(Activity a, Bundle metadata) {
+        this.activity = a;
+        this.metaData = metadata;
+        reader = NativePipeReader.getDefaultReader(this);
+        reader.start();
+        appDataDir = activity.getApplicationInfo().dataDir;
+        storageDir = appDataDir + "/storage";
+        installJVMIfNeeded();
+        System.loadLibrary(ANDROID_WEBVIEW_LIB);
+    }
+
+    public void onTextReceived(String text) {
+        Log.v(TAG_JVM, text);
+    }
+    
+    private void installJVMIfNeeded() {
+        new InstallerTask().execute();
+    }
+    
+    private class InstallerTask extends AsyncTask<Void, Void, Void> {
+        protected Void doInBackground(Void... args) {
+           Log.i(TAG, "Installing JVM");
+            AppDataInstaller installer = 
+                new AppDataInstaller(storageDir,
+                    activity.getApplicationContext().getAssets());
+            installer.install();
+            return null;
+        }
+        
+        protected void onPostExecute(Void result) {
+            runJVM();
+        }
+    }
+    
+    private void runJVM() {
+        Log.i(TAG, "Launch JVM + application");
+        JvmArgs args = new JvmArgs(appDataDir);
+        VMLauncher.initialize(args.getJavaHome());
+        VMLauncher.runOnDebugPort(args.getDebugPort(),
+                                  args.getArgArray());
+    }
+    
+    private class JvmArgs {
+        private List<String> argList = new ArrayList<String>();
+        private String javaHome;
+
+        public JvmArgs(String appDir) {
+            String jvmRunCommand =
+                   "-Djava.library.path="
+                     + appDir + "/lib|"
+                     + "-Djava.home="
+                     + appDir + "/storage/jvm|"
+                     + "-Dsun.boot.library.path="
+                     + appDir + "/storage/jvm/lib|"
+                     + "-cp|"
+                     + getClasspath(appDir)
+                     + "|"                                         
+                     + "-Djavafx.platform=android|"
+                     + "-Djavafx.runtime.path="
+                     + appDir +"/storage/lib|"
+                     + getCustomJVMArgs()
+                     + "|"
+                     + getMainClass()
+                     + "|"
+                     + getApplicationArgs();
+
+            createArgList(jvmRunCommand);
+        }
+
+        private String[] listFiles(String dir, final String suffix) {
+            File dirf = new File(dir);
+            if (!dirf.exists()) {
+                return new String[]{};
+            }
+            String[] files = dirf.list(new FilenameFilter() {           
+                @Override
+                public boolean accept(File dir, String filename) {      
+                    return filename.endsWith(suffix);
+                }
+            });
+            return files;
+        }
+
+        private String getClasspath(String appDir) {
+            final String libDir = appDir + "/storage/lib/";
+            String[] libfiles = listFiles(libDir, JAR_EXT);
+            if (libfiles.length == 0) {
+                return "";
+            }
+            StringBuilder sb = new StringBuilder();
+            for(String file: libfiles) {
+                sb.append(libDir);
+                sb.append(file);
+                sb.append(File.pathSeparatorChar);
+            }
+            int len = sb.length();
+            return sb.substring(0, len - 1);
+        }
+
+        private String getMainClass() {
+             return metaData.getString(META_DATA_MAIN_CLASS);
+        }
+
+        private String getCustomJVMArgs() {
+             return metaData.getString(META_DATA_JVM_ARGS);
+        }
+
+        private String getApplicationArgs() {
+             return metaData.getString(META_DATA_APP_ARGS);
+        }
+
+        private int getDebugPort() {            
+             return metaData.getInt(META_DATA_DEBUG_PORT, 0);
+        }
+
+        public void createArgList(String args) {
+            if (args != null) {
+                String sep = (args.contains("|")) ? "\\|" : " ";
+                for (String arg : args.split(sep)) {
+                    arg = arg.trim();
+                    if (arg.length() > 0) {
+                        this.argList.add(arg);
+                        if (javaHome == null) {
+                            String[] pair = arg.split("\\=");
+                            Log.v(TAG, "arg = " + arg);
+                            Log.v(TAG, "pair.length = " + pair.length);
+                            if (pair.length == 2) {
+                                if ("-Djava.home".equals(pair[0])) {
+                                    Log.v(TAG, "Setting javaHome to " + pair[1]);
+                                    javaHome = pair[1];
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+        public String[] getArgArray() {
+            return argList.toArray(new String[0]);
+        }
+
+        public String getJavaHome() {
+           return javaHome;
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/Launcher.java	Tue Sep 10 14:12:43 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013 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 com.oracle.dalvik;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public interface Launcher {
+    public void launchApp(Activity a, Bundle metadata);
+}
--- a/modules/graphics/src/main/docs/javafx/scene/doc-files/cssref.html	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/docs/javafx/scene/doc-files/cssref.html	Tue Sep 10 14:12:43 2013 -0700
@@ -963,7 +963,7 @@
       <a href="#typesize" class="typelink">&lt;size&gt;</a>[,
       <a href="#typeboolean" class="typelink">&lt;boolean&gt;</a>]?]?)</p>
     <p>The parameters, in order, are:<br>
-    <p style="margin-left: 40px;">  
+    <p style="margin-left: 40px;">
     <span class="grammar"><a href="#typestring" class="typelink">&lt;string&gt;</a></span>
       The URL of the image.<br>
       <span class="grammar"><a href="#typesize" class="typelink">&lt;size&gt;</a></span>
@@ -977,8 +977,8 @@
       <span class="grammar"><a href="#typeboolean" class="typelink">&lt;boolean&gt;</a></span>
       The proportional flag which indicates whether start and end locations are proportional or absolute<br>
     </p>
-    <p>For a full explanation of the parameters, refer to the 
-        <a href="../paint/ImagePattern.html" class="typelink">ImagePattern</a> javadoc.</p>    
+    <p>For a full explanation of the parameters, refer to the
+        <a href="../paint/ImagePattern.html" class="typelink">ImagePattern</a> javadoc.</p>
     <p>Following are examples of the use of image-pattern:</p>
     <p class="example">image-pattern("images/Duke.png")</p>
     <p class="example">image-pattern("images/Duke.png", 20%, 20%, 80%, 80%)</p>
@@ -2674,7 +2674,7 @@
           <td class="propertyname">-fx-min-height, -fx-pref-height, -fx-max-height</td>
           <td class="value"><a href="#typenumber" class="typelink">&lt;number&gt;</a></td>
           <td class="default">-1</td>
-          <td>Percentage values are not useful since the actual value would be 
+          <td>Percentage values are not useful since the actual value would be
               computed from the width and/or height of the Regions's parent before
               the parent is laid out.</td>
         </tr>
@@ -2682,7 +2682,7 @@
           <td class="propertyname">-fx-min-width, -fx-pref-width, -fx-max-width</td>
           <td class="value"><a href="#typenumber" class="typelink">&lt;number&gt;</a></td>
           <td class="default">-1</td>
-          <td>Percentage values are not useful since the actual value would be 
+          <td>Percentage values are not useful since the actual value would be
               computed from the width and/or height of the Region's parent before
               the parent is laid out.</td>
         </tr>
@@ -4298,6 +4298,18 @@
           <td>&nbsp;</td>
         </tr>
         <tr>
+            <td class="propertyname">-fx-open-tab-animation</td>
+            <td class="value">[ grow | none ]</td>
+            <td>grow</td>
+            <td>&#39;none&#39; disables Tab opening animation</td>
+        </tr>
+        <tr>
+            <td class="propertyname">-fx-close-tab-animation</td>
+            <td class="value">[ grow | none ]</td>
+            <td>grow</td>
+            <td>&#39;none&#39; disables Tab closing animation</td>
+        </tr>
+        <tr>
           <td colspan="4" class="parents">Also has all properties of <a href="#control">Control</a></td>
         </tr>
       </tbody>
--- a/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensApplication.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensApplication.java	Tue Sep 10 14:12:43 2013 -0700
@@ -33,6 +33,7 @@
 import java.util.List;
 import com.sun.glass.events.KeyEvent;
 import com.sun.glass.events.MouseEvent;
+import com.sun.glass.events.TouchEvent;
 import com.sun.glass.events.ViewEvent;
 import com.sun.glass.events.WindowEvent;
 import com.sun.glass.ui.Application;
@@ -489,7 +490,8 @@
         @Override
         void dispatch() {
             LensTouchInputSupport.postTouchEvent(view, state, id, x, y, absX, absY);
-
+            view._notifyMouse(MouseEvent.DRAG, MouseEvent.BUTTON_NONE,
+                    x, y, absX, absY, 0, false, true);
         }
 
         @Override
@@ -530,6 +532,8 @@
         void dispatch() {
             LensTouchInputSupport.postMultiTouchEvent(
                     view, states, ids, xs, ys, dx, dy);
+            view._notifyMouse(MouseEvent.DRAG, MouseEvent.BUTTON_NONE,
+                    xs[0] + dx, ys[0] + dy, xs[0], ys[0], 0, false, true);
 
         }
 
@@ -1388,7 +1392,26 @@
                                             + x + "," + y
                                             + " on " + view);
             }
-
+            synchronized (eventList) {
+                if (!eventList.isEmpty()
+                        && state == TouchEvent.TOUCH_MOVED) {
+                    Event lastEvent = eventList.getLast();
+                    if (lastEvent instanceof LensTouchEvent) {
+                        LensTouchEvent e = (LensTouchEvent) lastEvent;
+                        if (e.view == view
+                                && e.state == state
+                                && e.id == id) {
+                            // rewrite the coordinates of the scheduled event
+                            // with the coordinates of this event.
+                            e.x = x;
+                            e.y = y;
+                            e.absX = absX;
+                            e.absY = absY;
+                            return;
+                        }
+                    }
+                }
+            }
             postEvent(new LensTouchEvent(view, state, id,
                                          x, y, absX, absY));
 
@@ -1417,9 +1440,41 @@
                                             + states.length + " points "
                                             + " on " + view);
             }
-
-            postEvent(new LensMultiTouchEvent(view, states, ids,
-                                              xs, ys, dx, dy));
+            synchronized (eventList) {
+                // Try to match this multitouch event against a pending event
+                boolean match = false;
+                if (!eventList.isEmpty()) {
+                    Event lastEvent = eventList.getLast();
+                    if (lastEvent instanceof LensMultiTouchEvent) {
+                        LensMultiTouchEvent e = (LensMultiTouchEvent) lastEvent;
+                        if (e.view == view
+                                && e.states.length == states.length
+                                && e.dx == dx && e.dy == dy) {
+                            assert(states.length == ids.length);
+                            assert(e.states.length == e.ids.length);
+                            match = true;
+                            for (int i = 0; i < states.length && match; i++) {
+                                if (e.states[i] != states[i]) {
+                                    match = false;
+                                }
+                                if (e.ids[i] != ids[i]) {
+                                    match = false;
+                                }
+                            }
+                            if (match) {
+                                // rewrite the coordinates of the scheduled event
+                                // with the coordinates of this event.
+                                e.xs = xs;
+                                e.ys = ys;
+                            }
+                        }
+                    }
+                }
+                if (!match) {
+                    postEvent(new LensMultiTouchEvent(view, states, ids,
+                                                      xs, ys, dx, dy));
+                }
+            }
 
         } catch (Exception e) {
             reportException(e);
--- a/modules/graphics/src/main/java/com/sun/javafx/css/StyleManager.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/css/StyleManager.java	Tue Sep 10 14:12:43 2013 -0700
@@ -25,6 +25,8 @@
 
 package com.sun.javafx.css;
 
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
 import javafx.css.Styleable;
 import java.io.FileNotFoundException;
 import java.io.FilePermission;
@@ -672,26 +674,42 @@
 
     public Image getCachedImage(String url) {
 
-        Image image = imageCache.get(url);
-        if (image == null) {
+        Image image = null;
+        if (imageCache.containsKey(url)) {
+
+            image = imageCache.get(url);
+
+        } else {
 
             try {
 
                 image = new Image(url);
+
+                // RT-31865
+                if (image.isError()) {
+
+                    final PlatformLogger logger = getLogger();
+                    if (logger != null && logger.isLoggable(Level.WARNING)) {
+                        logger.warning("Error loading image: " + url);
+                    }
+
+                    image = null;
+                }
+
                 imageCache.put(url, image);
 
             } catch (IllegalArgumentException iae) {
                 // url was empty!
                 final PlatformLogger logger = getLogger();
                 if (logger != null && logger.isLoggable(Level.WARNING)) {
-                        LOGGER.warning(iae.getLocalizedMessage());
+                    logger.warning(iae.getLocalizedMessage());
                 }
 
             } catch (NullPointerException npe) {
                 // url was null!
                 final PlatformLogger logger = getLogger();
                 if (logger != null && logger.isLoggable(Level.WARNING)) {
-                        LOGGER.warning(npe.getLocalizedMessage());
+                    logger.warning(npe.getLocalizedMessage());
                 }
             }
         }
--- a/modules/graphics/src/main/java/com/sun/javafx/css/converters/CursorConverter.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/css/converters/CursorConverter.java	Tue Sep 10 14:12:43 2013 -0700
@@ -48,12 +48,24 @@
 
     @Override
     public Cursor convert(ParsedValue<String, Cursor> value, Font not_used) {
+
         // the parser doesn't covert cusor, so convert it from the raw value
         String string = value.getValue();
-        if (string.startsWith("Cursor.")) {
-            string = string.substring("Cursor.".length());
+
+        if (string != null) {
+
+            int index = string.indexOf("Cursor.");
+            if (index > -1) {
+                string = string.substring(index+"Cursor.".length());
+            }
+            string = string.replace('-','_').toUpperCase();
         }
-        return Cursor.cursor(string);
+
+        try {
+            return Cursor.cursor(string);
+        } catch (IllegalArgumentException | NullPointerException exception) {
+            return Cursor.DEFAULT;
+        }
     }
 
     @Override
--- a/modules/graphics/src/main/java/com/sun/javafx/css/parser/CSSParser.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/css/parser/CSSParser.java	Tue Sep 10 14:12:43 2013 -0700
@@ -135,11 +135,6 @@
     private Styleable  sourceOfInlineStyle;
 
     // source is a file
-//    private void setInputSource(String url) {
-//        setInputSource(url, null);
-//    }
-
-    // source is a file
     private void setInputSource(String url, String str) {
         stylesheetAsText = str;
         sourceOfStylesheet = url;
@@ -244,7 +239,7 @@
         final String path = url != null ? url.toExternalForm() : null;
         final Stylesheet stylesheet = new Stylesheet(path);
         if (url != null) {
-            setInputSource(path);
+            setInputSource(path, null);
             Reader reader = new BufferedReader(new InputStreamReader(url.openStream()));
             parse(stylesheet, reader);
         }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontFile.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontFile.java	Tue Sep 10 14:12:43 2013 -0700
@@ -111,6 +111,7 @@
 
     Path2D getGlyphOutline(int gc, float size) {
         if (fontFace == null) return null;
+        if (size == 0) return new Path2D();
         return fontFace.GetGlyphRunOutline(size, (short)gc, false);
     }
 
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/transform/Affine2D.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/transform/Affine2D.java	Tue Sep 10 14:12:43 2013 -0700
@@ -1323,6 +1323,48 @@
     }
 
     @Override
+    public BaseTransform deriveWithTranslation(double mxt, double myt, double mzt) {
+        if (mzt == 0.0) {
+            translate(mxt, myt);
+            return this;
+        }
+        Affine3D a = new Affine3D(this);
+        a.translate(mxt, myt, mzt);
+        return a;
+    }
+
+    @Override
+    public BaseTransform deriveWithScale(double mxx, double myy, double mzz) {
+        if (mzz == 1.0) {
+            scale(mxx, myy);
+            return this;
+        }
+        Affine3D a = new Affine3D(this);
+        a.scale(mxx, myy, mzz);
+        return a;
+
+    }
+
+    @Override
+    public BaseTransform deriveWithRotation(double theta,
+            double axisX, double axisY, double axisZ) {
+        if (theta == 0.0) {
+            return this;
+        }
+        if (almostZero(axisX) && almostZero(axisY)) {
+            if (axisZ > 0) {
+                rotate(theta);
+            } else if (axisZ < 0) {
+                rotate(-theta);
+            } // else rotating about zero vector - NOP
+            return this;
+        }
+        Affine3D a = new Affine3D(this);
+        a.rotate(theta, axisX, axisY, axisZ);
+        return a;
+    }
+
+    @Override
     public BaseTransform deriveWithPreTranslation(double mxt, double myt) {
         this.mxt += mxt;
         this.myt += myt;
@@ -1354,6 +1396,27 @@
     }
 
     @Override
+    public BaseTransform deriveWithConcatenation(
+            double mxx,   double mxy,   double mxz,   double mxt,
+            double myx,   double myy,   double myz,   double myt,
+            double mzx,   double mzy,   double mzz,   double mzt) {
+        if (                                   mxz == 0.0
+                                            && myz == 0.0
+                && mzx == 0.0 && mzy == 0.0 && mzz == 1.0 && mzt == 0.0) {
+            concatenate(mxx, mxy,
+                        mxt, myx,
+                        myy, myt);
+            return this;
+        }
+
+        Affine3D t3d = new Affine3D(this);
+        t3d.concatenate(mxx, mxy, mxz, mxt,
+                        myx, myy, myz, myt,
+                        mzx, mzy, mzz, mzt);
+        return t3d;
+    }
+
+    @Override
     public BaseTransform deriveWithConcatenation(BaseTransform tx) {
         if (tx.is2D()) {
             concatenate(tx);
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/transform/Affine3D.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/transform/Affine3D.java	Tue Sep 10 14:12:43 2013 -0700
@@ -647,6 +647,25 @@
         return this;
     }
 
+    @Override
+    public BaseTransform deriveWithTranslation(double mxt, double myt, double mzt) {
+        translate(mxt, myt, mzt);
+        return this;
+    }
+
+    @Override
+    public BaseTransform deriveWithScale(double mxx, double myy, double mzz) {
+        scale(mxx, myy, mzz);
+        return this;
+    }
+
+    @Override
+    public BaseTransform deriveWithRotation(double theta,
+            double axisX, double axisY, double axisZ) {
+        rotate(theta, axisX, axisY, axisZ);
+        return this;
+    }
+
     public void preTranslate(double mxt, double myt, double mzt) {
         this.mxt += mxt;
         this.myt += myt;
@@ -940,6 +959,17 @@
         return this;
     }
 
+    @Override
+    public BaseTransform deriveWithConcatenation(
+            double mxx, double mxy, double mxz, double mxt,
+            double myx, double myy, double myz, double myt,
+            double mzx, double mzy, double mzz, double mzt) {
+        concatenate(mxx, mxy, mxz, mxt,
+                    myx, myy, myz, myt,
+                    mzx, mzy, mzz, mzt);
+        return this;
+    }
+
     public void preConcatenate(BaseTransform transform) {
         switch (transform.getDegree()) {
             case IDENTITY:
@@ -1091,12 +1121,6 @@
         return this;
     }
 
-    private static final double EPSILON_ABSOLUTE = 1.0e-5;
-
-    public static boolean almostZero(double a) {
-        return ((a < EPSILON_ABSOLUTE) && (a > -EPSILON_ABSOLUTE));
-    }
-
     static boolean almostOne(double a) {
         return ((a < 1+EPSILON_ABSOLUTE) && (a > 1-EPSILON_ABSOLUTE));
     }
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/transform/AffineBase.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/transform/AffineBase.java	Tue Sep 10 14:12:43 2013 -0700
@@ -2841,6 +2841,28 @@
     }
 
     /**
+     * Similar to {@link #concatenate(com.sun.javafx.geom.transform.BaseTransform)},
+     * passing the individual elements of the transformation.
+     */
+    public void concatenate(double Txx, double Txy, double Txt,
+                            double Tyx, double Tyy, double Tyt)
+    {
+        double rxx = (mxx * Txx + mxy * Tyx /* + mxt * 0.0 */);
+        double rxy = (mxx * Txy + mxy * Tyy /* + mxt * 0.0 */);
+        double rxt = (mxx * Txt + mxy * Tyt + mxt /* * 1.0 */);
+        double ryx = (myx * Txx + myy * Tyx /* + myt * 0.0 */);
+        double ryy = (myx * Txy + myy * Tyy /* + myt * 0.0 */);
+        double ryt = (myx * Txt + myy * Tyt + myt /* * 1.0 */);
+        this.mxx = rxx;
+        this.mxy = rxy;
+        this.mxt = rxt;
+        this.myx = ryx;
+        this.myy = ryy;
+        this.myt = ryt;
+        updateState();
+    }
+
+    /**
      * Sets this transform to the inverse of itself.
      * The inverse transform Tx' of this transform Tx
      * maps coordinates transformed by Tx back
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/transform/BaseTransform.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/transform/BaseTransform.java	Tue Sep 10 14:12:43 2013 -0700
@@ -437,10 +437,17 @@
                                           double mzx, double mzy, double mzz, double mzt);
 
     public abstract BaseTransform deriveWithTranslation(double mxt, double myt);
+    public abstract BaseTransform deriveWithTranslation(double mxt, double myt, double mzt);
+    public abstract BaseTransform deriveWithScale(double mxx, double myy, double mzz);
+    public abstract BaseTransform deriveWithRotation(double theta, double axisX, double axisY, double axisZ);
     public abstract BaseTransform deriveWithPreTranslation(double mxt, double myt);
     public abstract BaseTransform deriveWithConcatenation(double mxx, double myx,
                                                           double mxy, double myy,
                                                           double mxt, double myt);
+    public abstract BaseTransform deriveWithConcatenation(
+            double mxx, double mxy, double mxz, double mxt,
+            double myx, double myy, double myz, double myt,
+            double mzx, double mzy, double mzz, double mzt);
     public abstract BaseTransform deriveWithPreConcatenation(BaseTransform transform);
     public abstract BaseTransform deriveWithConcatenation(BaseTransform tx);
     public abstract BaseTransform deriveWithNewTransform(BaseTransform tx);
@@ -517,6 +524,12 @@
         return dst;
     }
 
+    static final double EPSILON_ABSOLUTE = 1.0e-5;
+
+    public static boolean almostZero(double a) {
+        return ((a < EPSILON_ABSOLUTE) && (a > -EPSILON_ABSOLUTE));
+    }
+
     /**
      * Returns the matrix elements and degree of this transform as a string.
      * @return  the matrix elements and degree of this transform
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/transform/Identity.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/transform/Identity.java	Tue Sep 10 14:12:43 2013 -0700
@@ -281,6 +281,58 @@
     }
 
     @Override
+    public BaseTransform deriveWithTranslation(double mxt, double myt, double mzt) {
+        if (mzt == 0.0) {
+            if (mxt == 0.0 && myt == 0.0) {
+                return this;
+            }
+            return new Translate2D(mxt, myt);
+        }
+        Affine3D a = new Affine3D();
+        a.translate(mxt, myt, mzt);
+        return a;
+    }
+
+    @Override
+    public BaseTransform deriveWithScale(double mxx, double myy, double mzz) {
+        if (mzz == 1.0) {
+            if (mxx == 1.0 && myy == 1.0) {
+                return this;
+            }
+            Affine2D a = new Affine2D();
+            a.scale(mxx, myy);
+            return a;
+        }
+        Affine3D a = new Affine3D();
+        a.scale(mxx, myy, mzz);
+        return a;
+
+    }
+
+    @Override
+    public BaseTransform deriveWithRotation(double theta,
+            double axisX, double axisY, double axisZ) {
+        if (theta == 0.0) {
+            return this;
+        }
+        if (almostZero(axisX) && almostZero(axisY)) {
+            if (axisZ == 0.0) {
+                return this;
+            }
+            Affine2D a = new Affine2D();
+            if (axisZ > 0) {
+                a.rotate(theta);
+            } else if (axisZ < 0) {
+                a.rotate(-theta);
+            }
+            return a;
+        }
+        Affine3D a = new Affine3D();
+        a.rotate(theta, axisX, axisY, axisZ);
+        return a;
+    }
+
+    @Override
     public BaseTransform deriveWithConcatenation(double mxx, double myx,
                                                  double mxy, double myy,
                                                  double mxt, double myt)
@@ -291,6 +343,16 @@
     }
 
     @Override
+    public BaseTransform deriveWithConcatenation(
+            double mxx, double mxy, double mxz, double mxt,
+            double myx, double myy, double myz, double myt,
+            double mzx, double mzy, double mzz, double mzt) {
+        return getInstance(mxx, mxy, mxz, mxt,
+                           myx, myy, myz, myt,
+                           mzx, mzy, mzz, mzt);
+    }
+
+    @Override
     public BaseTransform deriveWithConcatenation(BaseTransform tx) {
         return getInstance(tx);
     }
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/transform/Translate2D.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/transform/Translate2D.java	Tue Sep 10 14:12:43 2013 -0700
@@ -451,6 +451,61 @@
     }
 
     @Override
+    public BaseTransform deriveWithTranslation(double mxt, double myt, double mzt) {
+        if (mzt == 0.0) {
+            this.mxt += mxt;
+            this.myt += myt;
+            return this;
+        }
+        Affine3D a = new Affine3D();
+        a.translate(this.mxt + mxt, this.myt + myt, mzt);
+        return a;
+    }
+
+    @Override
+    public BaseTransform deriveWithScale(double mxx, double myy, double mzz) {
+        if (mzz == 1.0) {
+            if (mxx == 1.0 && myy == 1.0) {
+                return this;
+            }
+            Affine2D a = new Affine2D();
+            a.translate(this.mxt, this.myt);
+            a.scale(mxx, myy);
+            return a;
+        }
+        Affine3D a = new Affine3D();
+        a.translate(this.mxt, this.myt);
+        a.scale(mxx, myy, mzz);
+        return a;
+
+    }
+
+    @Override
+    public BaseTransform deriveWithRotation(double theta,
+            double axisX, double axisY, double axisZ) {
+        if (theta == 0.0) {
+            return this;
+        }
+        if (almostZero(axisX) && almostZero(axisY)) {
+            if (axisZ == 0.0) {
+                return this;
+            }
+            Affine2D a = new Affine2D();
+            a.translate(this.mxt, this.myt);
+            if (axisZ > 0) {
+                a.rotate(theta);
+            } else if (axisZ < 0) {
+                a.rotate(-theta);
+            }
+            return a;
+        }
+        Affine3D a = new Affine3D();
+        a.translate(this.mxt, this.myt);
+        a.rotate(theta, axisX, axisY, axisZ);
+        return a;
+    }
+
+    @Override
     public BaseTransform deriveWithPreTranslation(double mxt, double myt) {
         this.mxt += mxt;
         this.myt += myt;
@@ -474,6 +529,24 @@
     }
 
     @Override
+    public BaseTransform deriveWithConcatenation(
+            double mxx,   double mxy,   double mxz,   double mxt,
+            double myx,   double myy,   double myz,   double myt,
+            double mzx,   double mzy,   double mzz,   double mzt) {
+        if (                                   mxz == 0.0
+                                            && myz == 0.0
+                && mzx == 0.0 && mzy == 0.0 && mzz == 1.0 && mzt == 0.0) {
+            return deriveWithConcatenation(mxx, myx,
+                                           mxy, myy,
+                                           mxt, myt);
+        }
+
+        return new Affine3D(mxx, mxy, mxz, mxt + this.mxt,
+                            myx, myy, myz, myt + this.myt,
+                            mzx, mzy, mzz, mzt);
+    }
+
+    @Override
     public BaseTransform deriveWithConcatenation(BaseTransform tx) {
         if (tx.isTranslateOrIdentity()) {
             this.mxt += tx.getMxt();
--- a/modules/graphics/src/main/java/com/sun/javafx/scene/transform/TransformUtils.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/scene/transform/TransformUtils.java	Tue Sep 10 14:12:43 2013 -0700
@@ -25,7 +25,9 @@
 
 package com.sun.javafx.scene.transform;
 
+import com.sun.javafx.geom.transform.Affine2D;
 import com.sun.javafx.geom.transform.Affine3D;
+import com.sun.javafx.geom.transform.BaseTransform;
 import javafx.geometry.Point2D;
 import javafx.geometry.Point3D;
 import javafx.scene.transform.NonInvertibleTransformException;
@@ -841,6 +843,18 @@
         }
 
         /**
+         * @treatAsPrivate implementation detail
+         * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+         */
+        @Deprecated
+        @Override
+        public BaseTransform impl_derive(final BaseTransform trans) {
+            return trans.deriveWithConcatenation(xx, xy, xz, xt,
+                                                 yx, yy, yz, yt,
+                                                 zx, zy, zz, zt);
+        }
+
+        /**
          * Used only by tests to check the 2d matrix state
          */
         int getState2d() {
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGRegion.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGRegion.java	Tue Sep 10 14:12:43 2013 -0700
@@ -1171,6 +1171,7 @@
     private void renderBackgroundShape(Graphics g) {
         if (PulseLogger.PULSE_LOGGING_ENABLED) {
             PulseLogger.PULSE_LOGGER.renderIncrementCounter("NGRegion renderBackgroundShape slow path");
+            PulseLogger.PULSE_LOGGER.renderMessage("Slow shape path for " + getName());
         }
         // We first need to draw each background fill. We don't pay any attention
         // to the radii of the BackgroundFill, but we do honor the insets and
@@ -1220,9 +1221,6 @@
     }
 
     private void renderBackgrounds(Graphics g, float width, float height) {
-        if (PulseLogger.PULSE_LOGGING_ENABLED) {
-            PulseLogger.PULSE_LOGGER.renderIncrementCounter("NGRegion renderBackgrounds slow path");
-        }
         final List<BackgroundFill> fills = background.getFills();
         for (int i = 0, max = fills.size(); i < max; i++) {
             final BackgroundFill fill = fills.get(i);
@@ -1269,6 +1267,10 @@
                         g.fillRoundRect(l, t, w, h, arcWidth, arcHeight);
                     }
                 } else {
+                    if (PulseLogger.PULSE_LOGGING_ENABLED) {
+                        PulseLogger.PULSE_LOGGER.renderIncrementCounter("NGRegion renderBackgrounds slow path");
+                        PulseLogger.PULSE_LOGGER.renderMessage("Slow background path for " + getName());
+                    }
                     // The edges are not uniform, so we have to render each edge independently
                     // TODO document the issue number which will give us a fast path for rendering
                     // non-uniform corners, and that we want to implement that instead of createPath2
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/RegionImageCache.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/RegionImageCache.java	Tue Sep 10 14:12:43 2013 -0700
@@ -60,6 +60,7 @@
         backingStore = factory.createRTTexture(WIDTH + WIDTH, HEIGHT, WrapMode.CLAMP_NOT_NEEDED);
         backingStore.contentsUseful();
         backingStore.makePermanent();
+        factory.setRegionTexture(backingStore);
         // Subdivide the texture in two halves where on half is used to store
         // horizontal regions and the other vertical regions. Otherwise, mixing
         // horizontal and vertical regions on the same area, would result in
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PerformanceTrackerHelper.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PerformanceTrackerHelper.java	Tue Sep 10 14:12:43 2013 -0700
@@ -26,6 +26,8 @@
 package com.sun.javafx.tk.quantum;
 
 import com.sun.javafx.tk.Toolkit;
+import com.sun.prism.impl.PrismSettings;
+
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.security.AccessController;
@@ -52,12 +54,11 @@
                     @Override
                     public PerformanceTrackerHelper run() {
                         try {
-                            if (System.getProperty("sun.perflog") != null) {
+                            if (PrismSettings.perfLog) {
                                 final PerformanceTrackerHelper trackerImpl =
                                         new PerformanceTrackerDefaultImpl();
 
-                                if (System.getProperty(
-                                        "sun.perflog.fx.exitflush") != null) {
+                                if (PrismSettings.perfLogExitFlush) {
                                     Runtime.getRuntime().addShutdownHook(
                                             new Thread() {
 
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java	Tue Sep 10 14:12:43 2013 -0700
@@ -25,6 +25,7 @@
 
 package com.sun.javafx.tk.quantum;
 
+import com.sun.javafx.logging.PulseLogger;
 import com.sun.prism.Graphics;
 import com.sun.prism.GraphicsPipeline;
 import com.sun.prism.impl.Disposer;
@@ -86,19 +87,27 @@
                 if (g != null) {
                     paintImpl(g);
                 }
-                
+
+                long start = PulseLogger.PULSE_LOGGING_ENABLED ? System.currentTimeMillis() : 0;
                 if (!presentable.prepare(null)) {
                     disposePresentable();
                     sceneState.getScene().entireSceneNeedsRepaint();
+                    if (PulseLogger.PULSE_LOGGING_ENABLED) {
+                        PulseLogger.PULSE_LOGGER.renderMessage(start, System.currentTimeMillis(), "Presentable.prepare");
+                    }
                     return;
                 }
                 
                 /* present for vsync buffer swap */
+                start = PulseLogger.PULSE_LOGGING_ENABLED ? System.currentTimeMillis() : 0;
                 if (vs.getDoPresent()) {
                     if (!presentable.present()) {
                         disposePresentable();
                         sceneState.getScene().entireSceneNeedsRepaint();
                     }
+                    if (PulseLogger.PULSE_LOGGING_ENABLED) {
+                        PulseLogger.PULSE_LOGGER.renderMessage(start, System.currentTimeMillis(), "Presentable.present");
+                    }
                 }
             }
         } catch (Throwable th) {
@@ -119,6 +128,9 @@
                 ManagedResource.printSummary();
             }
             renderLock.unlock();
+            if (PulseLogger.PULSE_LOGGING_ENABLED) {
+                PulseLogger.PULSE_LOGGER.renderMessage(System.currentTimeMillis(), System.currentTimeMillis(), "Finished Presenting Painter");
+            }
         }
     }
 }
--- a/modules/graphics/src/main/java/com/sun/prism/ResourceFactory.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/ResourceFactory.java	Tue Sep 10 14:12:43 2013 -0700
@@ -167,6 +167,12 @@
     public void addFactoryListener(ResourceFactoryListener l);
     public void removeFactoryListener(ResourceFactoryListener l);
 
+    public void setRegionTexture(Texture texture);
+    public Texture getRegionTexture();
+    public void setGlyphTexture(Texture texture);
+    public Texture getGlyphTexture();
+    public boolean isSuperShaderAllowed();
+
     public void dispose();
 
     /*
--- a/modules/graphics/src/main/java/com/sun/prism/d3d/D3DContext.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/d3d/D3DContext.java	Tue Sep 10 14:12:43 2013 -0700
@@ -89,8 +89,10 @@
 
     private final D3DResourceFactory factory;
 
+    public static final int NUM_QUADS = PrismSettings.superShader ? 4096 : 256;
+
     static VertexBuffer createVertexBuffer(long contextHandle) {
-        return new D3DVertexBuffer(contextHandle, 256);
+        return new D3DVertexBuffer(contextHandle, NUM_QUADS);
     }
 
     D3DContext(long pContext, Screen screen, D3DResourceFactory factory) {
--- a/modules/graphics/src/main/java/com/sun/prism/d3d/D3DMeshView.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/d3d/D3DMeshView.java	Tue Sep 10 14:12:43 2013 -0700
@@ -82,7 +82,10 @@
 
     @Override
     public void setPointLight(int index, float x, float y, float z, float r, float g, float b, float w) {
-        context.setPointLight(nativeHandle, index, x, y, z, r, g, b, w);
+        // NOTE: We only support up to 3 point lights at the present
+        if (index >= 0 && index <= 2) {
+            context.setPointLight(nativeHandle, index, x, y, z, r, g, b, w);
+        }
     }
 
     @Override
--- a/modules/graphics/src/main/java/com/sun/prism/es2/ES2Context.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/es2/ES2Context.java	Tue Sep 10 14:12:43 2013 -0700
@@ -69,7 +69,7 @@
     private int indexBuffer = 0;
     private int shaderProgram;
 
-    public static final int NUM_QUADS = 256;
+    public static final int NUM_QUADS = PrismSettings.superShader ? 4096 : 256;
 
     private static ES2VertexBuffer createVertexBuffer() {
         return new ES2VertexBuffer(NUM_QUADS);
--- a/modules/graphics/src/main/java/com/sun/prism/es2/ES2Graphics.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/es2/ES2Graphics.java	Tue Sep 10 14:12:43 2013 -0700
@@ -25,7 +25,10 @@
 
 package com.sun.prism.es2;
 
+import com.sun.javafx.geom.transform.BaseTransform;
+import com.sun.javafx.sg.prism.NGCamera;
 import com.sun.prism.CompositeMode;
+import com.sun.prism.GraphicsPipeline;
 import com.sun.prism.RenderTarget;
 import com.sun.prism.impl.ps.BaseShaderGraphics;
 import com.sun.prism.paint.Color;
@@ -92,4 +95,42 @@
         context.forceRenderTarget(this);
     }
 
+    @Override
+    public void transform(BaseTransform transform) {
+        // Treat transform as identity matrix if platform doesn't support 3D
+        // and transform isn't a 2D matrix
+        if (!GraphicsPipeline.getPipeline().is3DSupported() 
+                && !transform.is2D()) {
+            return;
+        }
+        super.transform(transform);
+    }
+
+    @Override
+    public void translate(float tx, float ty, float tz) {
+        // Treat translate as identity translate if platform doesn't support 3D
+        // and it isn't a 2D translate
+        if (!GraphicsPipeline.getPipeline().is3DSupported() &&  tz != 0.0f) {
+            return;
+        } 
+        super.translate(tx, ty, tz);
+    }
+
+    @Override
+    public void scale(float sx, float sy, float sz) {
+        // Treat scale as identity scale if platform doesn't support 3D
+        // and it isn't a 2D scale
+        if (!GraphicsPipeline.getPipeline().is3DSupported() &&  sz != 1.0f) {
+            return;
+        } 
+        super.scale(sx, sy, sz);
+    }
+
+    @Override
+    public void setCamera(NGCamera camera) {
+        // Use the default ParallelCamera if platform doesn't support 3D
+        if (GraphicsPipeline.getPipeline().is3DSupported()) {
+            super.setCamera(camera);
+        }
+    }
 }
--- a/modules/graphics/src/main/java/com/sun/prism/es2/ES2MeshView.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/es2/ES2MeshView.java	Tue Sep 10 14:12:43 2013 -0700
@@ -42,6 +42,7 @@
     private float ambientLightBlue = 0;
     private float ambientLightGreen = 0;
 
+    // NOTE: We only support up to 3 point lights at the present
     private ES2Light[] lights = new ES2Light[3];
 
     // TODO: 3D - Need a mechanism to "decRefCount" Mesh and Material
@@ -101,8 +102,11 @@
 
     @Override
     public void setPointLight(int index, float x, float y, float z, float r, float g, float b, float w) {
-        lights[index] = new ES2Light(x, y, z, r, g, b, w);
-        context.setPointLight(nativeHandle, index, x, y, z, r, g, b, w);
+        // NOTE: We only support up to 3 point lights at the present
+        if (index >= 0 && index <= 2) {
+            lights[index] = new ES2Light(x, y, z, r, g, b, w);
+            context.setPointLight(nativeHandle, index, x, y, z, r, g, b, w);
+        }
     }
 
     ES2Light[] getPointLights() {
--- a/modules/graphics/src/main/java/com/sun/prism/es2/GLContext.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/es2/GLContext.java	Tue Sep 10 14:12:43 2013 -0700
@@ -150,7 +150,6 @@
     private static native int nGetMaxTextureSize();
     private static native int nGetUniformLocation(long nativeCtxInfo,
             int programID, String name);
-    private static native int nOneValueGetIntegerv(int pname);
     private static native void nPixelStorei(int pname, int param);
     private static native boolean nReadPixelsByte(long nativeCtxInfo, int length,
             Buffer buffer, byte[] pixelArr, int x, int y, int w, int h);
@@ -428,11 +427,6 @@
         }
     }
 
-    int getBoundTextureID() {
-        // return the single value param
-        return nOneValueGetIntegerv(GL_TEXTURE_BINDING_2D);
-    }
-
     long getNativeCtxInfo() {
         return nativeCtxInfo;
     }
--- a/modules/graphics/src/main/java/com/sun/prism/impl/BaseContext.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/BaseContext.java	Tue Sep 10 14:12:43 2013 -0700
@@ -150,6 +150,10 @@
         return getGlyphCache(strike, glyphCaches);
     }
 
+    public boolean isSuperShaderEnabled() {
+        return false;
+    }
+
     private GlyphCache getGlyphCache(FontStrike strike,
                                      Map<FontStrike, GlyphCache> glyphCaches) {
         GlyphCache glyphCache = glyphCaches.get(strike);
--- a/modules/graphics/src/main/java/com/sun/prism/impl/BaseGraphics.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/BaseGraphics.java	Tue Sep 10 14:12:43 2013 -0700
@@ -115,7 +115,7 @@
 
     @Override
     public void setState3D(boolean flag) {
-        this.state3D = flag;            
+        this.state3D = flag;
     }
 
     @Override
@@ -399,8 +399,12 @@
         float tx2 = (cx1 + sx2) / pw;
         float ty2 = (cy1 + sy2) / ph;
 
-        context.getVertexBuffer().addQuad(dx1, dy1, dx2, dy2,
-                                          tx1, ty1, tx2, ty2);
+        VertexBuffer vb = context.getVertexBuffer();
+        if (context.isSuperShaderEnabled()) {
+            vb.addSuperQuad(dx1, dy1, dx2, dy2, tx1, ty1, tx2, ty2, false);
+        } else {
+            vb.addQuad(dx1, dy1, dx2, dy2, tx1, ty1, tx2, ty2);
+        }
     }
 
     @Override
@@ -448,9 +452,15 @@
      // float tv2 = (cy1 + sv2) / ph;
 
         VertexBuffer vb = context.getVertexBuffer();
-        vb.addQuad(dx1, dy1, dh1, dy2, tx1, ty1, th1, ty2);
-        vb.addQuad(dh1, dy1, dh2, dy2, th1, ty1, th2, ty2);
-        vb.addQuad(dh2, dy1, dx2, dy2, th2, ty1, tx2, ty2);
+        if (context.isSuperShaderEnabled()) {
+            vb.addSuperQuad(dx1, dy1, dh1, dy2, tx1, ty1, th1, ty2, false);
+            vb.addSuperQuad(dh1, dy1, dh2, dy2, th1, ty1, th2, ty2, false);
+            vb.addSuperQuad(dh2, dy1, dx2, dy2, th2, ty1, tx2, ty2, false);
+        } else {
+            vb.addQuad(dx1, dy1, dh1, dy2, tx1, ty1, th1, ty2);
+            vb.addQuad(dh1, dy1, dh2, dy2, th1, ty1, th2, ty2);
+            vb.addQuad(dh2, dy1, dx2, dy2, th2, ty1, tx2, ty2);
+        }
     }
 
     @Override
@@ -498,9 +508,15 @@
         float tv2 = (cy1 + sv2) / ph;
 
         VertexBuffer vb = context.getVertexBuffer();
-        vb.addQuad(dx1, dy1, dx2, dv1, tx1, ty1, tx2, tv1);
-        vb.addQuad(dx1, dv1, dx2, dv2, tx1, tv1, tx2, tv2);
-        vb.addQuad(dx1, dv2, dx2, dy2, tx1, tv2, tx2, ty2);
+        if (context.isSuperShaderEnabled()) {
+            vb.addSuperQuad(dx1, dy1, dx2, dv1, tx1, ty1, tx2, tv1, false);
+            vb.addSuperQuad(dx1, dv1, dx2, dv2, tx1, tv1, tx2, tv2, false);
+            vb.addSuperQuad(dx1, dv2, dx2, dy2, tx1, tv2, tx2, ty2, false);
+        } else {
+            vb.addQuad(dx1, dy1, dx2, dv1, tx1, ty1, tx2, tv1);
+            vb.addQuad(dx1, dv1, dx2, dv2, tx1, tv1, tx2, tv2);
+            vb.addQuad(dx1, dv2, dx2, dy2, tx1, tv2, tx2, ty2);
+        }
     }
 
     @Override
@@ -549,17 +565,31 @@
         float tv2 = (cy1 + sv2) / ph;
 
         VertexBuffer vb = context.getVertexBuffer();
-        vb.addQuad(dx1, dy1, dh1, dv1, tx1, ty1, th1, tv1);
-        vb.addQuad(dh1, dy1, dh2, dv1, th1, ty1, th2, tv1);
-        vb.addQuad(dh2, dy1, dx2, dv1, th2, ty1, tx2, tv1);
+        if (context.isSuperShaderEnabled()) {
+            vb.addSuperQuad(dx1, dy1, dh1, dv1, tx1, ty1, th1, tv1, false);
+            vb.addSuperQuad(dh1, dy1, dh2, dv1, th1, ty1, th2, tv1, false);
+            vb.addSuperQuad(dh2, dy1, dx2, dv1, th2, ty1, tx2, tv1, false);
 
-        vb.addQuad(dx1, dv1, dh1, dv2, tx1, tv1, th1, tv2);
-        vb.addQuad(dh1, dv1, dh2, dv2, th1, tv1, th2, tv2);
-        vb.addQuad(dh2, dv1, dx2, dv2, th2, tv1, tx2, tv2);
+            vb.addSuperQuad(dx1, dv1, dh1, dv2, tx1, tv1, th1, tv2, false);
+            vb.addSuperQuad(dh1, dv1, dh2, dv2, th1, tv1, th2, tv2, false);
+            vb.addSuperQuad(dh2, dv1, dx2, dv2, th2, tv1, tx2, tv2, false);
 
-        vb.addQuad(dx1, dv2, dh1, dy2, tx1, tv2, th1, ty2);
-        vb.addQuad(dh1, dv2, dh2, dy2, th1, tv2, th2, ty2);
-        vb.addQuad(dh2, dv2, dx2, dy2, th2, tv2, tx2, ty2);
+            vb.addSuperQuad(dx1, dv2, dh1, dy2, tx1, tv2, th1, ty2, false);
+            vb.addSuperQuad(dh1, dv2, dh2, dy2, th1, tv2, th2, ty2, false);
+            vb.addSuperQuad(dh2, dv2, dx2, dy2, th2, tv2, tx2, ty2, false);
+        } else {
+            vb.addQuad(dx1, dy1, dh1, dv1, tx1, ty1, th1, tv1);
+            vb.addQuad(dh1, dy1, dh2, dv1, th1, ty1, th2, tv1);
+            vb.addQuad(dh2, dy1, dx2, dv1, th2, ty1, tx2, tv1);
+
+            vb.addQuad(dx1, dv1, dh1, dv2, tx1, tv1, th1, tv2);
+            vb.addQuad(dh1, dv1, dh2, dv2, th1, tv1, th2, tv2);
+            vb.addQuad(dh2, dv1, dx2, dv2, th2, tv1, tx2, tv2);
+
+            vb.addQuad(dx1, dv2, dh1, dy2, tx1, tv2, th1, ty2);
+            vb.addQuad(dh1, dv2, dh2, dy2, th1, tv2, th2, ty2);
+            vb.addQuad(dh2, dv2, dx2, dy2, th2, tv2, tx2, ty2);
+        }
     }
 
     public void drawTextureVO(Texture tex,
--- a/modules/graphics/src/main/java/com/sun/prism/impl/BaseResourceFactory.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/BaseResourceFactory.java	Tue Sep 10 14:12:43 2013 -0700
@@ -48,6 +48,10 @@
     private final WeakHashMap<ResourceFactoryListener,Boolean> listenerMap =
             new WeakHashMap<ResourceFactoryListener,Boolean>();
 
+    private Texture regionTexture;
+    private Texture glyphTexture;
+    private boolean superShaderAllowed;
+
     @Override public void addFactoryListener(ResourceFactoryListener l) {
         listenerMap.put(l, Boolean.TRUE);
     }
@@ -211,4 +215,35 @@
                              width, height);
     }
 
+    @Override
+    public void setRegionTexture(Texture texture) {
+        regionTexture = texture;
+        superShaderAllowed = PrismSettings.superShader &&
+                             regionTexture != null &&
+                             glyphTexture != null;
     }
+
+    @Override
+    public Texture getRegionTexture() {
+        return regionTexture;
+    }
+
+    @Override
+    public void setGlyphTexture(Texture texture) {
+        glyphTexture = texture;
+        superShaderAllowed = PrismSettings.superShader &&
+                             regionTexture != null &&
+                             glyphTexture != null;
+    }
+
+    @Override
+    public Texture getGlyphTexture() {
+        return glyphTexture;
+    }
+
+    @Override
+    public boolean isSuperShaderAllowed() {
+        return superShaderAllowed;
+    }
+
+}
--- a/modules/graphics/src/main/java/com/sun/prism/impl/GlyphCache.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/GlyphCache.java	Tue Sep 10 14:12:43 2013 -0700
@@ -108,6 +108,9 @@
                                                     WrapMode.CLAMP_NOT_NEEDED);
             tex.contentsUseful();
             tex.makePermanent();
+            if (!isLCDCache) {
+                factory.setGlyphTexture(tex);
+            }
             tex.setLinearFiltering(false);
             packer = new RectanglePacker(tex, WIDTH, HEIGHT);
             packerMap.put(context, packer);
@@ -223,7 +226,11 @@
         } else {
             dx1 = Math.round(dx1);
             dx2 = dx1 + gw;
-            vb.addQuad(dx1, dy1, dx2, dy2, tx1, ty1, tx2, ty2);
+            if (context.isSuperShaderEnabled()) {
+                vb.addSuperQuad(dx1, dy1, dx2, dy2, tx1, ty1, tx2, ty2, true);
+            } else {
+                vb.addQuad(dx1, dy1, dx2, dy2, tx1, ty1, tx2, ty2);
+            }
         }
     }
 
--- a/modules/graphics/src/main/java/com/sun/prism/impl/PrismSettings.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/PrismSettings.java	Tue Sep 10 14:12:43 2013 -0700
@@ -33,6 +33,7 @@
 import java.util.Properties;
 import java.util.StringTokenizer;
 import com.sun.javafx.PlatformUtil;
+import com.sun.javafx.Utils;
 
 /**
  * Contains the runtime arguments used by Prism.
@@ -82,6 +83,11 @@
     public static final boolean disableEffects;
     public static final int glyphCacheWidth;
     public static final int glyphCacheHeight;
+    public static final boolean perfLog;
+    public static final boolean perfLogExitFlush;
+    public static final boolean perfLogFirstPaintFlush;
+    public static final boolean perfLogFirstPaintExit;
+    public static final boolean superShader;
 
     private PrismSettings() {
     }
@@ -122,8 +128,7 @@
 
         // The maximum number of dirty regions to use. The absolute max that we can
         // support at present is 15.
-        dirtyRegionCount = Math.max(getInt(systemProperties, "prism.dirtyregioncount",
-                                  6, null), 15);
+        dirtyRegionCount = Utils.clamp(0, getInt(systemProperties, "prism.dirtyregioncount", 6, null), 15);
 
         /* Dirty region optimizations */
         threadCheck = getBoolean(systemProperties, "prism.threadcheck", false);
@@ -318,7 +323,7 @@
          * This is needed for some embedded platforms to avoid rendering artifacts
          * when rendering into small RTT.
          */
-       minRTTSize = getInt(systemProperties, "prism.minrttsize",                       
+       minRTTSize = getInt(systemProperties, "prism.minrttsize",
                PlatformUtil.isEmbedded() ? 16 : 0, "Try -Dprism.minrttsize=<number>");
 
         disableRegionCaching = getBoolean(systemProperties,
@@ -326,13 +331,24 @@
                                           false);
 
         disableD3D9Ex = getBoolean(systemProperties, "prism.disableD3D9Ex", true);
-        
+
         disableEffects = getBoolean(systemProperties, "prism.disableEffects", false);
 
         glyphCacheWidth = getInt(systemProperties, "prism.glyphCacheWidth", 1024,
                 "Try -Dprism.glyphCacheWidth=<number>");
         glyphCacheHeight = getInt(systemProperties, "prism.glyphCacheHeight", 1024,
                 "Try -Dprism.glyphCacheHeight=<number>");
+
+        /*
+         * Performance Logger flags
+         * Enable the performance logger, print on exit, print on first paint etc.
+         */
+        perfLog = getBoolean(systemProperties, "sun.perflog", false, true);
+        perfLogExitFlush = getBoolean(systemProperties, "sun.perflog.fx.exitflush", false, true);
+        perfLogFirstPaintFlush = getBoolean(systemProperties, "sun.perflog.fx.firstpaintflush", false, true);
+        perfLogFirstPaintExit = getBoolean(systemProperties, "sun.perflog.fx.firstpaintexit", false, true);
+
+        superShader = getBoolean(systemProperties, "prism.supershader", true);
     }
 
     private static int parseInt(String s, int dflt, int trueDflt,
@@ -399,6 +415,15 @@
         return (strval != null) ? Boolean.parseBoolean(strval) : dflt;
     }
 
+    private static boolean getBoolean(Properties properties,
+                                      String key,
+                                      boolean dflt,
+                                      boolean dfltIfDefined) {
+        final String strval = properties.getProperty(key);
+        if (strval != null && strval.length() == 0) return dfltIfDefined;
+        return (strval != null) ? Boolean.parseBoolean(strval) : dflt;
+    }
+
     private static int getInt(Properties properties,
                               String key,
                               int dflt,
--- a/modules/graphics/src/main/java/com/sun/prism/impl/VertexBuffer.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/VertexBuffer.java	Tue Sep 10 14:12:43 2013 -0700
@@ -36,7 +36,7 @@
     protected static final int FLOATS_PER_TC   = 2;
     protected static final int FLOATS_PER_VC   = 3;
     protected static final int FLOATS_PER_VERT = FLOATS_PER_VC + (2 * FLOATS_PER_TC);
-    
+
     protected static final int BYTES_PER_VERT = 4;
 
     protected static final int VCOFF = 0;
@@ -46,22 +46,22 @@
     protected int capacity, index;
 
     protected byte r, g, b, a;
-    
+
     protected byte  colorArray[];
     protected float coordArray[];
-    
+
     public VertexBuffer(int maxQuads) {
         capacity = maxQuads * VERTS_PER_QUAD;
         index = 0;
-        
+
         colorArray = new byte [capacity * BYTES_PER_VERT];
         coordArray = new float[capacity * FLOATS_PER_VERT];
     }
-    
+
     protected void drawQuads(int numVertices) {
         throw new Error ("flush not implemented for lightweight");
     }
-    
+
     // it had better be the case if this method be moved to Graphics
     // so that we can delete D3DVertexBuffer and ES2(N)VertexBuffer
     protected void drawTriangles(int numTriangles, float fData[], byte cData[]) {
@@ -85,7 +85,7 @@
             putColor(i);
         }
     }
-    
+
     private void putColor(int idx) {
         int i = idx * BYTES_PER_VERT;
         colorArray[i+0] = r;
@@ -93,7 +93,7 @@
         colorArray[i+2] = b;
         colorArray[i+3] = a;
     }
-    
+
     /**
      * Flushes (renders) all pending vertices (triangles) in the buffer to the
      * destination render target.  This operation only applies to heavyweight
@@ -106,7 +106,7 @@
             index = 0;
         }
     }
-    
+
     public final void rewind() {
         index = 0;
     }
@@ -142,7 +142,7 @@
         coordArray[i+1] = y;
         coordArray[i+2] = 0f;
         coordArray[i+3] = tx;
-        coordArray[i+4] = ty;       
+        coordArray[i+4] = ty;
         putColor(index);
         index++;
     }
@@ -152,7 +152,7 @@
         if (index == capacity) {
             grow();
         }
-        
+
         int i = FLOATS_PER_VERT * index;
         coordArray[i+0] = x;
         coordArray[i+1] = y;
@@ -182,7 +182,7 @@
         coordArray[i+1] = y;
         coordArray[i+2] = 0f;
         coordArray[i+3] = tx;
-        coordArray[i+4] = ty;         
+        coordArray[i+4] = ty;
         putColor(index);
         index++;
     }
@@ -194,9 +194,9 @@
         coordArray[i+1] = y;
         coordArray[i+2] = 0f;
         coordArray[i+3] = t0x;
-        coordArray[i+4] = t0y;         
+        coordArray[i+4] = t0y;
         coordArray[i+5] = t1x;
-        coordArray[i+6] = t1y;         
+        coordArray[i+6] = t1y;
         putColor(index);
         index++;
     }
@@ -226,7 +226,7 @@
     public final void addQuad(
             float dx1, float dy1, float dx2, float dy2,
             float t1x1, float t1y1, float t1x2, float t1y2,
-            float t2x1, float t2y1, float t2x2, float t2y2) 
+            float t2x1, float t2y1, float t2x2, float t2y2)
     {
         ensureCapacityForQuad();
 
@@ -239,7 +239,7 @@
     public final void addMappedQuad(
             float dx1, float dy1, float dx2, float dy2,
             float tx11, float ty11, float tx21, float ty21,
-            float tx12, float ty12, float tx22, float ty22) 
+            float tx12, float ty12, float tx22, float ty22)
     {
         ensureCapacityForQuad();
 
@@ -254,7 +254,7 @@
             float ux11, float uy11, float ux21, float uy21,
             float ux12, float uy12, float ux22, float uy22,
             float vx11, float vy11, float vx21, float vy21,
-            float vx12, float vy12, float vx22, float vy22) 
+            float vx12, float vy12, float vx22, float vy22)
     {
         ensureCapacityForQuad();
 
@@ -267,7 +267,7 @@
     public final void addQuad(
             float dx1, float dy1, float dx2, float dy2,
             float tx1, float ty1, float tx2, float ty2,
-            AffineBase tx) 
+            AffineBase tx)
     {
         addQuad(dx1, dy1, dx2, dy2, tx1, ty1, tx2, ty2);
 
@@ -283,9 +283,56 @@
         }
     }
 
+    public final void addSuperQuad(
+            float dx1, float dy1, float dx2, float dy2,
+            float tx1, float ty1, float tx2, float ty2,
+            boolean isText)
+    {
+//        ensureCapacityForQuad();
+        int idx = index;
+        if (idx + VERTS_PER_QUAD > capacity) {
+//            grow();
+            drawQuads(idx);
+            idx = index = 0;
+        }
+
+        int i = FLOATS_PER_VERT * idx;
+        float farr[] = coordArray;
+
+        float text = isText ? 1 : 0;
+        float image = isText ? 0 : 1;
+
+//        addVertNoCheck(dx1, dy1, tx1, ty1);
+        farr[  i] = dx1; farr[++i] = dy1; farr[++i] = 0;
+        farr[++i] = tx1; farr[++i] = ty1;
+        farr[++i] = image; farr[++i] = text; i++;
+//        addVertNoCheck(dx1, dy2, tx1, ty2);
+        farr[  i] = dx1; farr[++i] = dy2; farr[++i] = 0;
+        farr[++i] = tx1; farr[++i] = ty2;
+        farr[++i] = image; farr[++i] = text; i++;
+//        addVertNoCheck(dx2, dy1, tx2, ty1);
+        farr[  i] = dx2; farr[++i] = dy1; farr[++i] = 0;
+        farr[++i] = tx2; farr[++i] = ty1;
+        farr[++i] = image; farr[++i] = text; i++;
+//        addVertNoCheck(dx2, dy2, tx2, ty2);
+        farr[  i] = dx2; farr[++i] = dy2; farr[++i] = 0;
+        farr[++i] = tx2; farr[++i] = ty2;
+        farr[++i] = image; farr[++i] = text; i++;
+
+        byte barr[] = colorArray;
+        byte r = this.r, g = this.g, b = this.b, a = this.a;
+        int j = BYTES_PER_VERT * idx;
+        barr[  j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
+        barr[++j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
+        barr[++j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
+        barr[++j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
+
+        index = idx + VERTS_PER_QUAD;
+    }
+
     public final void addQuad(
             float dx1, float dy1, float dx2, float dy2,
-            float tx1, float ty1, float tx2, float ty2) 
+            float tx1, float ty1, float tx2, float ty2)
     {
 //        ensureCapacityForQuad();
         int idx = index;
@@ -293,7 +340,7 @@
             drawQuads(idx);
             idx = index = 0;
         }
-        
+
         int i = FLOATS_PER_VERT * idx;
         float farr[] = coordArray;
 
@@ -321,32 +368,32 @@
         barr[++j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
         barr[++j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
 
-        index = idx + VERTS_PER_QUAD;        
+        index = idx + VERTS_PER_QUAD;
     }
-    
+
     public final void addQuadVO(float topopacity, float botopacity,
             float dx1, float dy1, float dx2, float dy2,
-            float tx1, float ty1, float tx2, float ty2) 
+            float tx1, float ty1, float tx2, float ty2)
     {
         int idx = index;
         if (idx + VERTS_PER_QUAD > capacity) {
             drawQuads(idx);
             idx = index = 0;
         }
-        
+
         int i = FLOATS_PER_VERT * idx;
         float farr[] = coordArray;
-  
+
         // addVertNoCheck(dx1, dy1, tx1, ty1, topopacity);
         farr[  i] = dx1; farr[++i] = dy1; farr[++i] = 0;
         farr[++i] = tx1; farr[++i] = ty1;
         i += 3;
-        
+
         // addVertNoCheck(dx1, dy2, tx1, ty2, botopacity);
         farr[  i] = dx1; farr[++i] = dy2; farr[++i] = 0;
         farr[++i] = tx1; farr[++i] = ty2;
         i += 3;
-        
+
         // addVertNoCheck(dx2, dy1, tx2, ty1, topopacity);
         farr[  i] = dx2; farr[++i] = dy1; farr[++i] = 0;
         farr[++i] = tx2; farr[++i] = ty1;
@@ -367,8 +414,8 @@
         barr[++j] = to; barr[++j] = to; barr[++j] = to; barr[++j] = to;
         barr[++j] = bo; barr[++j] = bo; barr[++j] = bo; barr[++j] = bo;
 
-        index = idx + VERTS_PER_QUAD;        
-    }   
+        index = idx + VERTS_PER_QUAD;
+    }
 
     public final void addMappedPgram(
             float dx11, float dy11, float dx21, float dy21,
@@ -397,27 +444,27 @@
             float dx12, float dy12, float dx22, float dy22,
             float ux11, float uy11, float ux21, float uy21,
             float ux12, float uy12, float ux22, float uy22,
-            float vx, float vy) 
+            float vx, float vy)
     {
         int idx = index;
         if (idx + VERTS_PER_QUAD > capacity) {
             drawQuads(idx);
             idx = index = 0;
         }
-        
+
         int i = FLOATS_PER_VERT * idx;
         float farr[] = coordArray;
-        
+
         //addVertNoCheck(dx11, dy11, ux11, uy11, vx, vy);
         farr[i]   = dx11; farr[++i] = dy11; farr[++i] = 0;
         farr[++i] = ux11; farr[++i] = uy11;
         farr[++i] = vx; farr[++i] = vy;
-        
+
         //addVertNoCheck(dx12, dy12, ux12, uy12, vx, vy);
         farr[++i] = dx12; farr[++i] = dy12; farr[++i] = 0;
         farr[++i] = ux12; farr[++i] = uy12;
         farr[++i] = vx; farr[++i] = vy;
-        
+
         //addVertNoCheck(dx21, dy21, ux21, uy21, vx, vy);
         farr[++i] = dx21; farr[++i] = dy21; farr[++i] = 0;
         farr[++i] = ux21; farr[++i] = uy21;
@@ -435,7 +482,7 @@
         barr[++j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
         barr[++j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
         barr[++j] = r; barr[++j] = g; barr[++j] = b; barr[++j] = a;
-        
+
         index = idx + VERTS_PER_QUAD;
     }
 
@@ -445,7 +492,7 @@
             float ux11, float uy11, float ux21, float uy21,
             float ux12, float uy12, float ux22, float uy22,
             float vx11, float vy11, float vx21, float vy21,
-            float vx12, float vy12, float vx22, float vy22) 
+            float vx12, float vy12, float vx22, float vy22)
     {
         int idx = index;
         if (idx + VERTS_PER_QUAD > capacity) {
--- a/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java	Tue Sep 10 14:12:43 2013 -0700
@@ -126,6 +126,7 @@
     private Shader textureYV12Shader;
     private Shader textureFirstLCDShader;
     private Shader textureSecondLCDShader;
+    private Shader superShader;
     private Shader externalShader;
 
     private RTTexture lcdBuffer;
@@ -178,7 +179,7 @@
 
     protected abstract void updateShaderTransform(Shader shader,
                                                   BaseTransform xform);
-    
+
     protected abstract void updateWorldTransform(BaseTransform xform);
 
     protected abstract void updateClipRect(Rectangle clipRect);
@@ -319,6 +320,20 @@
         return textureSecondLCDShader;
     }
 
+    private Shader getSuperShader() {
+        if (superShader != null && !superShader.isValid()) {
+            superShader.dispose();
+            superShader = null;
+        }
+        if (superShader == null) {
+            superShader = factory.createStockShader("Mask_TextureSuper");
+        }
+        return superShader;
+    }
+
+    public boolean isSuperShaderEnabled() {
+        return state.lastShader == superShader;
+    }
 
     private void updatePerVertexColor(Paint paint, float extraAlpha) {
         if (paint != null && paint.getType() == Paint.Type.COLOR) {
@@ -439,23 +454,36 @@
                 ResourceFactory rf = g.getResourceFactory();
                 paintTex = rf.getCachedTexture(texPaint.getImage(), Texture.WrapMode.REPEAT);
             }
-            // NOTE: We are making assumptions here about which texture
-            // corresponds to which texture unit.  In a JSL file the
-            // first sampler mentioned will correspond to texture unit 0,
-            // the second sampler will correspond to texture unit 1,
-            // and so on, and there's currently no way to explicitly
-            // associate a sampler with a texture unit in the JSL file.
-            // So for now we assume that mask-related samplers are
-            // declared before any paint-related samplers in the
-            // composed JSL files.
-            if (maskTex != null) {
-                tex0 = maskTex;
-                tex1 = paintTex;
+            Shader shader = null;
+            if (factory.isSuperShaderAllowed() &&
+                paintTex == null &&
+                maskTex == factory.getGlyphTexture())
+            {
+                // Enabling the super shader to be used to render text.
+                // The texture pointed by tex0 is the region cache texture
+                // and it does not affect text rendering
+                shader = getSuperShader();
+                tex0 = factory.getRegionTexture();
+                tex1 = maskTex;
             } else {
-                tex0 = paintTex;
-                tex1 = null;
+                // NOTE: We are making assumptions here about which texture
+                // corresponds to which texture unit.  In a JSL file the
+                // first sampler mentioned will correspond to texture unit 0,
+                // the second sampler will correspond to texture unit 1,
+                // and so on, and there's currently no way to explicitly
+                // associate a sampler with a texture unit in the JSL file.
+                // So for now we assume that mask-related samplers are
+                // declared before any paint-related samplers in the
+                // composed JSL files.
+                if (maskTex != null) {
+                    tex0 = maskTex;
+                    tex1 = paintTex;
+                } else {
+                    tex0 = paintTex;
+                    tex1 = null;
+                }
+                shader = getPaintShader(maskType, paint);
             }
-            Shader shader = getPaintShader(maskType, paint);
             checkState(g, xform, shader, tex0, tex1);
             updatePaintShader(g, shader, maskType, paint, bx, by, bw, bh);
             updatePerVertexColor(paint, g.getExtraAlpha());
@@ -476,7 +504,6 @@
         validateTextureOp((BaseShaderGraphics)g, xform, tex0, null, format);
     }
 
-
     //This function sets the first LCD sample shader.
     public Shader validateLCDOp(BaseShaderGraphics g, BaseTransform xform,
                                 Texture tex0, Texture tex1, boolean firstPass,
@@ -528,7 +555,19 @@
             case BYTE_RGB:
             case BYTE_GRAY:
             case BYTE_APPLE_422: // uses GL_RGBA as internal format
-                shader = getTextureRGBShader();
+                if (factory.isSuperShaderAllowed() &&
+                    tex0 == factory.getRegionTexture() &&
+                    tex1 == null)
+                {
+                    // Enabling the super shader to be used for texture rendering.
+                    // The shader was designed to render many Regions (from the Region
+                    // texture cache) and text (from the glyph cache texture) without
+                    // changing the state in the context.
+                    shader = getSuperShader();
+                    tex1 = factory.getGlyphTexture();
+                } else {
+                    shader = getTextureRGBShader();
+                }
                 break;
             case MULTI_YCbCr_420: // Must use multitexture method
             case BYTE_ALPHA:
--- a/modules/graphics/src/main/java/com/sun/prism/j2d/print/J2DPrinterJob.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/j2d/print/J2DPrinterJob.java	Tue Sep 10 14:12:43 2013 -0700
@@ -130,19 +130,13 @@
 
     private class PrintDialogRunnable implements Runnable {
 
-        volatile boolean inNestedLoop = true;
-
         public void run() {
             boolean rv = false;
             try {
                 rv = pJob2D.printDialog(printReqAttrSet);
             } catch (Exception e) {
             } finally {
-                synchronized (this) {
-                    inNestedLoop = false;
-                    Application.invokeLater(new ExitLoopRunnable(this, rv));
-                    this.notify();
-                }
+                Application.invokeLater(new ExitLoopRunnable(this, rv));
             }
         }
     }
@@ -152,16 +146,8 @@
         Thread prtThread = new Thread(dr, "FX Print Dialog Thread");
         prtThread.start();
         // the nested event loop will return after the runnable exits.
-        Object rv = null;
-        synchronized (dr) {
-            if (dr.inNestedLoop) {
-                try {
-                    dr.wait();
-                } catch (InterruptedException e) {
-                }
-                rv = Toolkit.getToolkit().enterNestedEventLoop(dr);
-            }
-        }
+        Object rv = Toolkit.getToolkit().enterNestedEventLoop(dr);
+
         boolean rvbool = false;
         try {
             rvbool = ((Boolean)rv).booleanValue();
@@ -193,20 +179,14 @@
 
     private class PageDialogRunnable implements Runnable {
 
-        volatile boolean inNestedLoop = true;
-
         public void run() {
             PageFormat pf = null;
             try {
                 pf = pJob2D.pageDialog(printReqAttrSet);
             } catch (Exception e) {
             } finally {
-                synchronized (this) {
-                    inNestedLoop = false;
-                    Boolean rv = Boolean.valueOf(pf != null);
-                    Application.invokeLater(new ExitLoopRunnable(this, rv));
-                    this.notify();
-                }
+                Boolean rv = Boolean.valueOf(pf != null);
+                Application.invokeLater(new ExitLoopRunnable(this, rv));
             }
         }
     }
@@ -217,16 +197,7 @@
         Thread prtThread = new Thread(dr, "FX Page Setup Dialog Thread");
         prtThread.start();
         // the nested event loop will return after the runnable exits.
-        Object rv = null;
-        synchronized (dr) {
-            if (dr.inNestedLoop) {
-                try {
-                    dr.wait();
-                } catch (InterruptedException e) {
-                }
-                rv = Toolkit.getToolkit().enterNestedEventLoop(dr);
-            }
-        }
+        Object rv = Toolkit.getToolkit().enterNestedEventLoop(dr);
         boolean rvbool = false;
         try {
             rvbool = ((Boolean)rv).booleanValue();
--- a/modules/graphics/src/main/java/javafx/scene/CssStyleHelper.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/CssStyleHelper.java	Tue Sep 10 14:12:43 2013 -0700
@@ -1704,40 +1704,48 @@
         }
 
         CascadingStyle fontSize = getStyle(styleable, property.concat("-size"), styleMap, states);
-        // don't look past current node for font size if user set the font
-        // or if we're looking up the font for font cache.
-        if (fontSize == null && origin != StyleOrigin.USER) {
-            fontSize = lookupInheritedFont(styleable, property.concat("-size"), styleMap, distance);
+        if (fontSize != null) {
+            // if we have a font shorthand and it is more specific than font-size, then don't use the font-size style
+            if (fontShorthand != null && fontShorthand.compareTo(fontSize) < 0) {
+                fontSize = null;
+            }
+
+        } else if (origin != StyleOrigin.USER) {
+            //
+            // If we don't have a font-size, see if there is an inherited font-size.
+            // If lookupInheritedFontProperty returns other than null, then we know that font-size is closer (more specific)
+            // than the font shorthand
+            //
+            fontSize = lookupInheritedFontProperty(styleable, property.concat("-size"), styleMap, distance, fontShorthand);
         }
 
-        // font-size must be closer and more specific than font shorthand
         if (fontSize != null) {
 
-            if (fontShorthand == null || fontShorthand.compareTo(fontSize) >= 0) {
+            // The logic above ensures that, if fontSize is not null, then it is either
+            // 1) a style matching this node and is more specific than the font shorthand or
+            // 2) an inherited style that is more specific than the font shorthand
+            // and, therefore, we can use the fontSize style
+            final CalculatedValue cv =
+                    calculateValue(fontSize, styleable, dummyFontProperty,
+                            styleMap, states, styleable, cvFont, styleList);
 
-                final CalculatedValue cv =
-                        calculateValue(fontSize, styleable, dummyFontProperty,
-                                styleMap, states, styleable, cvFont, styleList);
+            if (cv.getValue() instanceof Double) {
+                if (origin == null || origin.compareTo(fontSize.getOrigin()) <= 0) {
 
-                if (cv.getValue() instanceof Double) {
-                    if (origin == null || origin.compareTo(fontSize.getOrigin()) <= 0) {
+                    origin = cv.getOrigin();
+                }
+                size = ((Double) cv.getValue()).doubleValue();
 
-                        origin = cv.getOrigin();
-                    }
-                    size = ((Double) cv.getValue()).doubleValue();
-
-                    if (cvFont != null) {
-                        boolean isRelative = cvFont.isRelative() || cv.isRelative();
-                        Font font = deriveFont((Font) cvFont.getValue(), family, weight, posture, size);
-                        cvFont = new CalculatedValue(font, origin, isRelative);
-                    } else {
-                        boolean isRelative = cv.isRelative();
-                        Font font = deriveFont(Font.getDefault(), family, weight, posture, size);
-                        cvFont = new CalculatedValue(font, origin, isRelative);
-                    }
-                    foundStyle = true;
+                if (cvFont != null) {
+                    boolean isRelative = cvFont.isRelative() || cv.isRelative();
+                    Font font = deriveFont((Font) cvFont.getValue(), family, weight, posture, size);
+                    cvFont = new CalculatedValue(font, origin, isRelative);
+                } else {
+                    boolean isRelative = cv.isRelative();
+                    Font font = deriveFont(Font.getDefault(), family, weight, posture, size);
+                    cvFont = new CalculatedValue(font, origin, isRelative);
                 }
-
+                foundStyle = true;
             }
 
         }
@@ -1749,76 +1757,112 @@
         }
 
         CascadingStyle fontWeight = getStyle(styleable, property.concat("-weight"), styleMap, states);
-        // don't look past current node for font weight if user set the font
-        if (fontWeight == null && origin != StyleOrigin.USER) {
-            fontWeight = lookupInheritedFont(styleable,property.concat("-weight"), styleMap, distance);
+        if (fontWeight != null) {
+            // if we have a font shorthand and it is more specific than font-weight, then don't use the font-weight style
+            if (fontShorthand != null && fontShorthand.compareTo(fontWeight) < 0) {
+                fontWeight = null;
+            }
+
+        } else if (origin != StyleOrigin.USER) {
+            //
+            // If we don't have a font-weight, see if there is an inherited font-weight.
+            // If lookupInheritedFontProperty returns other than null, then we know that font-weight is closer (more specific)
+            // than the font shorthand
+            //
+            fontWeight = lookupInheritedFontProperty(styleable, property.concat("-weight"), styleMap, distance, fontShorthand);
         }
 
         if (fontWeight != null) {
 
-            if (fontShorthand == null || fontShorthand.compareTo(fontWeight) >= 0) {
+            // The logic above ensures that, if fontWeight is not null, then it is either
+            // 1) a style matching this node and is more specific than the font shorthand or
+            // 2) an inherited style that is more specific than the font shorthand
+            // and, therefore, we can use the fontWeight style
 
-                final CalculatedValue cv =
-                        calculateValue(fontWeight, styleable, dummyFontProperty,
-                                styleMap, states, styleable, null, null);
+            final CalculatedValue cv =
+                    calculateValue(fontWeight, styleable, dummyFontProperty,
+                            styleMap, states, styleable, null, null);
 
-                if (cv.getValue() instanceof FontWeight) {
-                    if (origin == null || origin.compareTo(fontWeight.getOrigin()) <= 0) {
-                        origin = cv.getOrigin();
-                    }
-                    weight = (FontWeight)cv.getValue();
-                    foundStyle = true;
+            if (cv.getValue() instanceof FontWeight) {
+                if (origin == null || origin.compareTo(fontWeight.getOrigin()) <= 0) {
+                    origin = cv.getOrigin();
                 }
+                weight = (FontWeight)cv.getValue();
+                foundStyle = true;
+            }
+        }
+
+
+        CascadingStyle fontStyle = getStyle(styleable, property.concat("-style"), styleMap, states);
+        if (fontStyle != null) {
+            // if we have a font shorthand and it is more specific than font-style, then don't use the font-style style
+            if (fontShorthand != null && fontShorthand.compareTo(fontStyle) < 0) {
+                fontStyle = null;
+            }
+
+        } else if (origin != StyleOrigin.USER) {
+            //
+            // If we don't have a font-style, see if there is an inherited font-style.
+            // If lookupInheritedFontProperty returns other than null, then we know that font-style is closer (more specific)
+            // than the font shorthand
+            //
+            fontStyle = lookupInheritedFontProperty(styleable, property.concat("-style"), styleMap, distance, fontShorthand);
+        }
+
+        if (fontStyle != null) {
+
+            // The logic above ensures that, if fontStyle is not null, then it is either
+            // 1) a style matching this node and is more specific than the font shorthand or
+            // 2) an inherited style that is more specific than the font shorthand
+            // and, therefore, we can use the fontStyle style
+
+            final CalculatedValue cv =
+                    calculateValue(fontStyle, styleable, dummyFontProperty,
+                            styleMap, states, styleable, null, null);
+
+            if (cv.getValue() instanceof FontPosture) {
+                if (origin == null || origin.compareTo(fontStyle.getOrigin()) <= 0) {
+                    origin = cv.getOrigin();
+                }
+                posture = (FontPosture)cv.getValue();
+                foundStyle = true;
             }
 
         }
 
-        CascadingStyle fontStyle = getStyle(styleable, property.concat("-style"), styleMap, states);
-        // don't look past current node for font style if user set the font
-        if (fontStyle == null && origin != StyleOrigin.USER) {
-            fontStyle = lookupInheritedFont(styleable, property.concat("-style"), styleMap, distance);
-        }
+        CascadingStyle fontFamily = getStyle(styleable, property.concat("-family"), styleMap, states);
+        if (fontFamily != null) {
+            // if we have a font shorthand and it is more specific than font-family, then don't use the font-family style
+            if (fontShorthand != null && fontShorthand.compareTo(fontFamily) < 0) {
+                fontFamily = null;
+            }
 
-        if (fontStyle != null) {
-
-            if (fontShorthand == null || fontShorthand.compareTo(fontStyle) >= 0) {
-
-                final CalculatedValue cv =
-                        calculateValue(fontStyle, styleable, dummyFontProperty,
-                                styleMap, states, styleable, null, null);
-
-                if (cv.getValue() instanceof FontPosture) {
-                    if (origin == null || origin.compareTo(fontStyle.getOrigin()) <= 0) {
-                        origin = cv.getOrigin();
-                    }
-                    posture = (FontPosture)cv.getValue();
-                    foundStyle = true;
-                }
-
-            }
-        }
-
-        CascadingStyle fontFamily = getStyle(styleable, property.concat("-family"), styleMap, states);
-        // don't look past current node for font family if user set the font
-        if (fontFamily == null && origin != StyleOrigin.USER) {
-            fontFamily = lookupInheritedFont(styleable,property.concat("-family"), styleMap, distance);
+        } else if (origin != StyleOrigin.USER) {
+            //
+            // If we don't have a font-family, see if there is an inherited font-family.
+            // If lookupInheritedFontProperty returns other than null, then we know that font-family is closer (more specific)
+            // than the font shorthand
+            //
+            fontFamily = lookupInheritedFontProperty(styleable, property.concat("-family"), styleMap, distance, fontShorthand);
         }
 
         if (fontFamily != null) {
 
-            if (fontShorthand == null || fontShorthand.compareTo(fontFamily) >= 0) {
+            // The logic above ensures that, if fontFamily is not null, then it is either
+            // 1) a style matching this node and is more specific than the font shorthand or
+            // 2) an inherited style that is more specific than the font shorthand
+            // and, therefore, we can use the fontFamily style
 
-                final CalculatedValue cv =
-                        calculateValue(fontFamily, styleable, dummyFontProperty,
-                                styleMap, states, styleable, null, null);
+            final CalculatedValue cv =
+                    calculateValue(fontFamily, styleable, dummyFontProperty,
+                            styleMap, states, styleable, null, null);
 
-                if (cv.getValue() instanceof String) {
-                    if (origin == null || origin.compareTo(fontFamily.getOrigin()) <= 0) {
-                        origin = cv.getOrigin();
-                    }
-                    family = (String)cv.getValue();
-                    foundStyle = true;
+            if (cv.getValue() instanceof String) {
+                if (origin == null || origin.compareTo(fontFamily.getOrigin()) <= 0) {
+                    origin = cv.getOrigin();
                 }
+                family = (String)cv.getValue();
+                foundStyle = true;
             }
 
         }
@@ -1834,14 +1878,12 @@
         return SKIP;
     }
 
-    /**
-     * Called when we must getInheritedStyle a value from a parent node in the scenegraph.
-     */
-    private CascadingStyle lookupInheritedFont(
+    private CascadingStyle lookupInheritedFontProperty(
             final Styleable styleable,
             final String property,
             final StyleMap styleMap,
-            final int distance) {
+            final int distance,
+            CascadingStyle fontShorthand) {
 
         Styleable parent = styleable != null ? styleable.getStyleableParent() : null;
 
@@ -1859,6 +1901,14 @@
 
                 if (cascadingStyle != null) {
 
+                    // If we are closer to the node than the font shorthand, then font shorthand doesn't matter.
+                    // If the font shorthand and this style are the same distance, then we need to compare.
+                    if (fontShorthand != null && nlooks == 0) {
+                        if (fontShorthand.compareTo(cascadingStyle) < 0) {
+                            return null;
+                        }
+                    }
+
                     final ParsedValueImpl cssValue = cascadingStyle.getParsedValueImpl();
 
                     if ("inherit".equals(cssValue.getValue()) == false) {
--- a/modules/graphics/src/main/java/javafx/scene/Node.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Node.java	Tue Sep 10 14:12:43 2013 -0700
@@ -149,7 +149,12 @@
 import com.sun.javafx.scene.traversal.Direction;
 import com.sun.javafx.sg.prism.NGNode;
 import com.sun.javafx.tk.Toolkit;
+import com.sun.javafx.accessible.providers.AccessibleProvider;
+import com.sun.javafx.geom.transform.Affine2D;
+import com.sun.javafx.geom.transform.AffineBase;
+import com.sun.javafx.geom.transform.Translate2D;
 import com.sun.prism.impl.PrismSettings;
+import javafx.scene.transform.Translate;
 import sun.util.logging.PlatformLogger;
 import sun.util.logging.PlatformLogger.Level;
 
@@ -3237,7 +3242,7 @@
      * This is the concatenation of all transforms in this node, including all
      * of the convenience transforms.
      */
-    private final Affine3D localToParentTx = new Affine3D();
+    private BaseTransform localToParentTx = BaseTransform.IDENTITY_TRANSFORM;
 
     /**
      * This flag is used to indicate that localToParentTx is dirty and needs
@@ -4443,9 +4448,12 @@
                     // (must be the last transformation)
                     mirroringCenter = sceneValue.getWidth() / 2;
 
-                    localToParentTx.translate(mirroringCenter, 0, 0);
-                    localToParentTx.scale(-1, 1);
-                    localToParentTx.translate(-mirroringCenter, 0, 0);
+                    localToParentTx = localToParentTx.deriveWithTranslation(
+                            mirroringCenter, 0.0);
+                    localToParentTx = localToParentTx.deriveWithScale(
+                            -1.0, 1.0, 1.0);
+                    localToParentTx = localToParentTx.deriveWithTranslation(
+                            -mirroringCenter, 0.0);
                 } else {
                     // mirror later
                     mirror = true;
@@ -4458,25 +4466,39 @@
                 double pivotX = impl_getPivotX();
                 double pivotY = impl_getPivotY();
                 double pivotZ = impl_getPivotZ();
-                localToParentTx.translate(getTranslateX() + getLayoutX() + pivotX, getTranslateY() + getLayoutY() + pivotY, getTranslateZ() + pivotZ);
-                localToParentTx.rotate(Math.toRadians(getRotate()), getRotationAxis().getX(), getRotationAxis().getY(), getRotationAxis().getZ());
-                localToParentTx.scale(getScaleX(), getScaleY(), getScaleZ());
-                localToParentTx.translate(-pivotX, -pivotY, -pivotZ);
+
+                localToParentTx = localToParentTx.deriveWithTranslation(
+                        getTranslateX() + getLayoutX() + pivotX,
+                        getTranslateY() + getLayoutY() + pivotY,
+                        getTranslateZ() + pivotZ);
+                localToParentTx = localToParentTx.deriveWithRotation(
+                        Math.toRadians(getRotate()), getRotationAxis().getX(),
+                        getRotationAxis().getY(), getRotationAxis().getZ());
+                localToParentTx = localToParentTx.deriveWithScale(
+                        getScaleX(), getScaleY(), getScaleZ());
+                localToParentTx = localToParentTx.deriveWithTranslation(
+                        -pivotX, -pivotY, -pivotZ);
             } else {
-                localToParentTx.translate(getTranslateX() + getLayoutX(), getTranslateY() + getLayoutY(), getTranslateZ());
+                localToParentTx = localToParentTx.deriveWithTranslation(
+                        getTranslateX() + getLayoutX(),
+                        getTranslateY() + getLayoutY(),
+                        getTranslateZ());
             }
 
             if (impl_hasTransforms()) {
                 for (Transform t : getTransforms()) {
-                    t.impl_apply(localToParentTx);
+                    localToParentTx = t.impl_derive(localToParentTx);
                 }
             }
 
             // Check to see whether the node requires mirroring
             if (mirror) {
-                localToParentTx.translate(mirroringCenter, 0, 0);
-                localToParentTx.scale(-1, 1);
-                localToParentTx.translate(-mirroringCenter, 0, 0);
+                localToParentTx = localToParentTx.deriveWithTranslation(
+                        mirroringCenter, 0);
+                localToParentTx = localToParentTx.deriveWithScale(
+                        -1.0, 1.0, 1.0);
+                localToParentTx = localToParentTx.deriveWithTranslation(
+                        -mirroringCenter, 0);
             }
 
             transformDirty = false;
@@ -8669,21 +8691,34 @@
             return;
         }
 
+        if (cssFlag == CssFlags.RECALCULATE) {
+            // TODO: re-evalutate handling of CssFlags.RECALCULATE - see below
+            cssFlag = CssFlags.REAPPLY;
+        }
+
         if (cssFlag == CssFlags.REAPPLY) {
 
+            // RT-24621 - If this node's parent's cssFlag is REAPPLY, then CSS should be applied to the parent first,
+            // otherwise the styles this node uses will be incomplete (missing lookups, missing inherited styles, etc).
+            // find the top-most parent whose flag is REAPPLY and start from there, if there is one.
+            Parent _parent = getParent();
+            if(_parent != null && _parent.cssFlag == this.cssFlag) {
+                // TODO: danger of infinite loop here!
+                _parent.impl_processCSS();
+            }
+
             // Match new styles if my own indicates I need to reapply
             styleHelper = CssStyleHelper.createStyleHelper(this);
 
-        } else if (cssFlag == CssFlags.RECALCULATE) {
-
-            // Recalculate means that the in-line style has changed.
-
-            // Note: recalculate used to do something different than reapply,
-            // but the way calculated values are cached has changed.
-            // TODO: re-evalutate handling of CssFlags.RECALCULATE
-            cssFlag = CssFlags.REAPPLY;
-            styleHelper = CssStyleHelper.createStyleHelper(this);
-
+//        } else if (cssFlag == CssFlags.RECALCULATE) {
+//
+//            // Recalculate means that the in-line style has changed.
+//
+//            // Note: recalculate used to do something different than reapply,
+//            // but the way calculated values are cached has changed.
+//            cssFlag = CssFlags.REAPPLY;
+//            styleHelper = CssStyleHelper.createStyleHelper(this);
+//
         }
 
         final CssFlags flag = cssFlag;
--- a/modules/graphics/src/main/java/javafx/scene/Scene.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Scene.java	Tue Sep 10 14:12:43 2013 -0700
@@ -138,6 +138,7 @@
 import com.sun.javafx.tk.TKStage;
 import com.sun.javafx.tk.Toolkit;
 import com.sun.javafx.scene.LayoutFlags;
+import com.sun.prism.impl.PrismSettings;
 
 import sun.util.logging.PlatformLogger;
 import sun.util.logging.PlatformLogger.Level;
@@ -2337,14 +2338,12 @@
             if (firstPulse) {
                 if (PerformanceTracker.isLoggingEnabled()) {
                     PerformanceTracker.logEvent("Scene - first repaint - layout complete");
-                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
-                        @Override public Object run() {
-                            if (System.getProperty("sun.perflog.fx.firstpaintflush") != null) {
-                                PerformanceTracker.outputLog();
-                            }
-                            return null;
-                        }
-                    });
+                    if (PrismSettings.perfLogFirstPaintFlush) {
+                        PerformanceTracker.outputLog();
+                    }
+                    if (PrismSettings.perfLogFirstPaintExit) {
+                        System.exit(0);
+                    }
                 }
                 firstPulse = false;
             }
@@ -3445,6 +3444,30 @@
             }
 
             queue.fire();
+
+            if (pdrInProgress && pdrEventTargets.contains(removing)) {
+                int i = 0;
+                EventTarget trg = null;
+                while (trg != removing) {
+                    trg = pdrEventTargets.get(i++);
+
+                    // trg.setHover(false) - already taken care of
+                    // by the code above which sent a mouse exited event
+                    ((Node) trg).setPressed(false);
+                }
+                pdrEventTargets.subList(0, i).clear();
+
+                trg = pdrEventTargets.get(0);
+                final PickResult res = pdrEventTarget.getResult();
+                if (trg instanceof Node) {
+                    pdrEventTarget.setNodeResult(new PickResult((Node) trg,
+                            res.getIntersectedPoint(), res.getIntersectedDistance()));
+                } else {
+                    pdrEventTarget.setSceneResult(new PickResult(null,
+                            res.getIntersectedPoint(), res.getIntersectedDistance()),
+                            (Scene) trg);
+                }
+            }
         }
 
         private void handleEnterExit(MouseEvent e, TargetWrapper pickedTarget) {
--- a/modules/graphics/src/main/java/javafx/scene/input/ScrollEvent.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/input/ScrollEvent.java	Tue Sep 10 14:12:43 2013 -0700
@@ -226,14 +226,14 @@
             boolean direct,
             boolean inertia,
             double deltaX, double deltaY,
-            double gestureDeltaX, double gestureDeltaY,
+            double totalDeltaX, double totalDeltaY,
             HorizontalTextScrollUnits textDeltaXUnits, double textDeltaX,
             VerticalTextScrollUnits textDeltaYUnits, double textDeltaY,
             int touchCount,
             PickResult pickResult) {
         this(null, null, eventType, x, y, screenX, screenY, shiftDown, controlDown,
-                altDown, metaDown, direct, inertia, deltaX, deltaY, gestureDeltaX,
-                gestureDeltaY, textDeltaXUnits, textDeltaX, textDeltaYUnits, textDeltaY, 
+                altDown, metaDown, direct, inertia, deltaX, deltaY, totalDeltaX,
+                totalDeltaY, textDeltaXUnits, textDeltaX, textDeltaYUnits, textDeltaY,
                 touchCount, pickResult);
     }
     
--- a/modules/graphics/src/main/java/javafx/scene/layout/Background.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/layout/Background.java	Tue Sep 10 14:12:43 2013 -0700
@@ -506,12 +506,16 @@
         for (BackgroundImage bi : images) {
             if (bi.opaque == null) {
                 // If the image is not yet loaded, just skip it
-                final com.sun.prism.Image platformImage = (com.sun.prism.Image) acc.getImageProperty(bi.image).get();
+                // Note: Unit test wants this to be com.sun.javafx.tk.PlatformImage, not com.sun.prism.Image
+                final com.sun.javafx.tk.PlatformImage platformImage = acc.getImageProperty(bi.image).get();
                 if (platformImage == null) continue;
 
                 // The image has been loaded, so update the opaque flag
-                assert platformImage != null;
-                bi.opaque = platformImage.isOpaque();
+                if (platformImage instanceof com.sun.prism.Image) {
+                    bi.opaque = ((com.sun.prism.Image)platformImage).isOpaque();
+                } else {
+                    continue;
+                }
             }
 
             // At this point we know that we're processing an image which has already been resolved
--- a/modules/graphics/src/main/java/javafx/scene/layout/BackgroundConverter.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/layout/BackgroundConverter.java	Tue Sep 10 14:12:43 2013 -0700
@@ -109,6 +109,8 @@
                 if (imageUrls[i] == null) continue;
 
                 final Image image = StyleManager.getInstance().getCachedImage(imageUrls[i]);
+                if (image == null) continue;
+
                 final RepeatStruct repeat = (repeats.length > 0) ?
                         repeats[i <= lastRepeatIndex ? i : lastRepeatIndex] : null; // min
                 final BackgroundPosition position = (positions.length > 0) ?
--- a/modules/graphics/src/main/java/javafx/scene/shape/TriangleMesh.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/shape/TriangleMesh.java	Tue Sep 10 14:12:43 2013 -0700
@@ -267,16 +267,30 @@
 
     /**
      * Computes the centroid of the given triangle
-     * @param v0 vertex of the triangle
-     * @param v1 vertex of the triangle
-     * @param v2 vertex of the triangle
+     * @param v0x x coord of first vertex of the triangle
+     * @param v0y y coord of first vertex of the triangle
+     * @param v0z z coord of first vertex of the triangle
+     * @param v1x x coord of second vertex of the triangle
+     * @param v1y y coord of second vertex of the triangle
+     * @param v1z z coord of second vertex of the triangle
+     * @param v2x x coord of third vertex of the triangle
+     * @param v2y y coord of third vertex of the triangle
+     * @param v2z z coord of third vertex of the triangle
      * @return the triangle centroid
      */
-    private Point3D computeCentroid(Point3D v0, Point3D v1, Point3D v2) {
-        Point3D center = v1.midpoint(v2);
+    private Point3D computeCentroid(
+            double v0x, double v0y, double v0z,
+            double v1x, double v1y, double v1z,
+            double v2x, double v2y, double v2z) {
 
-        Point3D vec = center.subtract(v0);
-        return v0.add(new Point3D(vec.getX() / 3.0, vec.getY() / 3.0, vec.getZ() / 3.0));
+//        Point3D center = v1.midpoint(v2);
+//        Point3D vec = center.subtract(v0);
+//        return v0.add(new Point3D(vec.getX() / 3.0, vec.getY() / 3.0, vec.getZ() / 3.0));
+
+        return new Point3D(
+            v0x + (v2x + (v1x - v2x) / 2.0 - v0x) / 3.0,
+            v0y + (v2y + (v1y - v2y) / 2.0 - v0y) / 3.0,
+            v0z + (v2z + (v1z - v2z) / 2.0 - v0z) / 3.0);
     }
 
     /**
@@ -313,50 +327,89 @@
      *              the result has been updated)
      */
     private boolean computeIntersectsFace(
-            PickRay pickRay, Point3D origin, Point3D dir, int faceIndex,
-            CullFace cullFace, Node candidate, boolean reportFace, PickResultChooser result) {
+            PickRay pickRay, Vec3d origin, Vec3d dir, int faceIndex,
+            CullFace cullFace, Node candidate, boolean reportFace, PickResultChooser result) {//, BoxBounds rayBounds) {
+
+        // This computation was naturally done by Point3D and its operations,
+        // but it needs a lot of points and there is often a lot of triangles
+        // so it is vital for performance to use only primitive variables
+        // and do the computing manually.
 
         final int v0Idx = faces.get(faceIndex) * NUM_COMPONENTS_PER_POINT;
         final int v1Idx = faces.get(faceIndex + 2) * NUM_COMPONENTS_PER_POINT;
         final int v2Idx = faces.get(faceIndex + 4) * NUM_COMPONENTS_PER_POINT;
 
-        final Point3D v0 = new Point3D(points.get(v0Idx), points.get(v0Idx + 1), points.get(v0Idx + 2));
-        final Point3D v1 = new Point3D(points.get(v1Idx), points.get(v1Idx + 1), points.get(v1Idx + 2));
-        final Point3D v2 = new Point3D(points.get(v2Idx), points.get(v2Idx + 1), points.get(v2Idx + 2));
+        final float v0x = points.get(v0Idx);
+        final float v0y = points.get(v0Idx + 1);
+        final float v0z = points.get(v0Idx + 2);
+        final float v1x = points.get(v1Idx);
+        final float v1y = points.get(v1Idx + 1);
+        final float v1z = points.get(v1Idx + 2);
+        final float v2x = points.get(v2Idx);
+        final float v2y = points.get(v2Idx + 1);
+        final float v2z = points.get(v2Idx + 2);
 
-        final Point3D e1 = v1.subtract(v0);
-        final Point3D e2 = v2.subtract(v0);
+        // e1 = v1.subtract(v0)
+        final float e1x = v1x - v0x;
+        final float e1y = v1y - v0y;
+        final float e1z = v1z - v0z;
+        // e2 = v2.subtract(v0)
+        final float e2x = v2x - v0x;
+        final float e2y = v2y - v0y;
+        final float e2z = v2z - v0z;
 
-        final Point3D h = dir.crossProduct(e2);
+        // h = dir.crossProduct(e2)
+        final double hx = dir.y * e2z - dir.z * e2y;
+        final double hy = dir.z * e2x - dir.x * e2z;
+        final double hz = dir.x * e2y - dir.y * e2x;
 
-        final double a = e1.dotProduct(h);
+        // a = e1.dotProduct(h)
+        final double a = e1x * hx + e1y * hy + e1z * hz;
         if (a == 0.0) {
             return false;
         }
         final double f = 1.0 / a;
 
-        final Point3D s = origin.subtract(v0);
+        // s = origin.subtract(v0)
+        final double sx = origin.x - v0x;
+        final double sy = origin.y - v0y;
+        final double sz = origin.z - v0z;
 
-        final double u = f * (s.dotProduct(h));
+        // u = f * (s.dotProduct(h))
+        final double u = f * (sx * hx + sy * hy + sz * hz);
 
         if (u < 0.0 || u > 1.0) {
             return false;
         }
 
-        Point3D q = s.crossProduct(e1);
-        double v = f * dir.dotProduct(q);
+        // q = s.crossProduct(e1)
+        final double qx = sy * e1z - sz * e1y;
+        final double qy = sz * e1x - sx * e1z;
+        final double qz = sx * e1y - sy * e1x;
+
+        // v = f * dir.dotProduct(q)
+        double v = f * (dir.x * qx + dir.y * qy + dir.z * qz);
 
         if (v < 0.0 || u + v > 1.0) {
             return false;
         }
 
-        final double t = f * e2.dotProduct(q);
+        // t = f * e2.dotProduct(q)
+        final double t = f * (e2x * qx + e2y * qy + e2z * qz);
 
         if (t >= pickRay.getNearClip() && t <= pickRay.getFarClip()) {
+            // This branch is entered only for hit triangles (not so often),
+            // so we can get smoothly back to the nice code using Point3Ds.
+
             if (cullFace != CullFace.NONE) {
-                final Point3D normal = e1.crossProduct(e2);
+                // normal = e1.crossProduct(e2)
+                final Point3D normal = new Point3D(
+                    e1y * e2z - e1z * e2y,
+                    e1z * e2x - e1x * e2z,
+                    e1x * e2y - e1y * e2x);
+
                 final double nangle = normal.angle(
-                        new Point3D(-dir.getX(), -dir.getY(), -dir.getZ()));
+                        new Point3D(-dir.x, -dir.y, -dir.z));
                 if ((nangle >= 90 || cullFace != CullFace.BACK) &&
                         (nangle <= 90 || cullFace != CullFace.FRONT)) {
                     // hit culled face
@@ -381,10 +434,27 @@
             // Now compute texture mapping. First rotate the triangle
             // so that we can compute in 2D
 
-            final Point3D centroid = computeCentroid(v0, v1, v2);
-            final Point3D cv0 = v0.subtract(centroid);
-            final Point3D cv1 = v1.subtract(centroid);
-            final Point3D cv2 = v2.subtract(centroid);
+            // centroid = computeCentroid(v0, v1, v2);
+            final Point3D centroid = computeCentroid(
+                    v0x, v0y, v0z,
+                    v1x, v1y, v1z,
+                    v2x, v2y, v2z);
+
+            // cv0 = v0.subtract(centroid)
+            final Point3D cv0 = new Point3D(
+                    v0x - centroid.getX(),
+                    v0y - centroid.getY(),
+                    v0z - centroid.getZ());
+            // cv1 = v1.subtract(centroid)
+            final Point3D cv1 = new Point3D(
+                    v1x - centroid.getX(),
+                    v1y - centroid.getY(),
+                    v1z - centroid.getZ());
+            // cv2 = v2.subtract(centroid)
+            final Point3D cv2 = new Point3D(
+                    v2x - centroid.getX(),
+                    v2y - centroid.getY(),
+                    v2z - centroid.getZ());
 
             final Point3D ce1 = cv1.subtract(cv0);
             final Point3D ce2 = cv2.subtract(cv0);
@@ -465,13 +535,11 @@
         final int size = faces.size();
 
         final Vec3d o = pickRay.getOriginNoClone();
-        final Point3D origin = new Point3D(o.x, o.y, o.z);
 
         final Vec3d d = pickRay.getDirectionNoClone();
-        final Point3D dir = new Point3D(d.x, d.y, d.z);
 
         for (int i = 0; i < size; i += NUM_COMPONENTS_PER_FACE) {
-            if (computeIntersectsFace(pickRay, origin, dir, i, cullFace, candidate, 
+            if (computeIntersectsFace(pickRay, o, d, i, cullFace, candidate, 
                     reportFace, pickResult)) {
                 found = true;
             }
--- a/modules/graphics/src/main/java/javafx/scene/transform/Affine.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/transform/Affine.java	Tue Sep 10 14:12:43 2013 -0700
@@ -27,6 +27,7 @@
 
 
 import com.sun.javafx.geom.transform.Affine3D;
+import com.sun.javafx.geom.transform.BaseTransform;
 import javafx.beans.property.DoubleProperty;
 import javafx.beans.property.SimpleDoubleProperty;
 import javafx.geometry.Point2D;
@@ -5714,6 +5715,47 @@
     }
 
     /**
+     * @treatAsPrivate implementation detail
+     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+     */
+    @Deprecated
+    @Override
+    public BaseTransform impl_derive(final BaseTransform trans) {
+        switch(state3d) {
+            default:
+                stateError();
+                // cannot reach
+            case APPLY_NON_3D:
+                switch(state2d) {
+                    case APPLY_IDENTITY:
+                        return trans;
+                    case APPLY_TRANSLATE:
+                        return trans.deriveWithTranslation(getTx(), getTy());
+                    case APPLY_SCALE:
+                        return trans.deriveWithScale(getMxx(), getMyy(), 1.0);
+                    case APPLY_SCALE | APPLY_TRANSLATE:
+                        // fall through
+                    default:
+                        return trans.deriveWithConcatenation(
+                                getMxx(), getMyx(),
+                                getMxy(), getMyy(),
+                                getTx(), getTy());
+                }
+            case APPLY_TRANSLATE:
+                return trans.deriveWithTranslation(getTx(), getTy(), getTz());
+            case APPLY_SCALE:
+                return trans.deriveWithScale(getMxx(), getMyy(), getMzz());
+            case APPLY_SCALE | APPLY_TRANSLATE:
+                // fall through
+            case APPLY_3D_COMPLEX:
+                return trans.deriveWithConcatenation(
+                        getMxx(), getMxy(), getMxz(), getTx(),
+                        getMyx(), getMyy(), getMyz(), getTy(),
+                        getMzx(), getMzy(), getMzz(), getTz());
+        }
+    }
+
+    /**
      * Keeps track of the atomic changes of more elements.
      * Don't forget to end or cancel a running atomic operation
      * when an exception is to be thrown during one.
--- a/modules/graphics/src/main/java/javafx/scene/transform/Rotate.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/transform/Rotate.java	Tue Sep 10 14:12:43 2013 -0700
@@ -32,6 +32,7 @@
 import javafx.geometry.Point3D;
 
 import com.sun.javafx.geom.transform.Affine3D;
+import com.sun.javafx.geom.transform.BaseTransform;
 import javafx.geometry.Point2D;
 
 
@@ -734,6 +735,33 @@
         }
     }
 
+    /**
+     * @treatAsPrivate implementation detail
+     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+     */
+    @Deprecated
+    @Override
+    public BaseTransform impl_derive(BaseTransform trans) {
+        if (isIdentity()) {
+            return trans;
+        }
+
+        double localPivotX = getPivotX();
+        double localPivotY = getPivotY();
+        double localPivotZ = getPivotZ();
+        double localAngle = getAngle();
+
+        if (localPivotX != 0 || localPivotY != 0 || localPivotZ != 0) {
+            trans = trans.deriveWithTranslation(localPivotX, localPivotY, localPivotZ);
+            trans = trans.deriveWithRotation(Math.toRadians(localAngle),
+                         getAxis().getX(),getAxis().getY(), getAxis().getZ());
+            return trans.deriveWithTranslation(-localPivotX, -localPivotY, -localPivotZ);
+        } else {
+            return trans.deriveWithRotation(Math.toRadians(localAngle),
+                         getAxis().getX(), getAxis().getY(), getAxis().getZ());
+        }
+    }
+
     @Override
     void validate() {
         getAxis();
--- a/modules/graphics/src/main/java/javafx/scene/transform/Scale.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/transform/Scale.java	Tue Sep 10 14:12:43 2013 -0700
@@ -29,6 +29,7 @@
 import javafx.beans.property.DoublePropertyBase;
 
 import com.sun.javafx.geom.transform.Affine3D;
+import com.sun.javafx.geom.transform.BaseTransform;
 import javafx.geometry.Point2D;
 import javafx.geometry.Point3D;
 
@@ -763,6 +764,25 @@
         }
     }
 
+    /**
+     * @treatAsPrivate implementation detail
+     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+     */
+    @Deprecated
+    @Override
+    public BaseTransform impl_derive(BaseTransform trans) {
+        if (isIdentity()) {
+            return trans;
+        }
+        if (getPivotX() != 0 || getPivotY() != 0 || getPivotZ() != 0) {
+            trans = trans.deriveWithTranslation(getPivotX(), getPivotY(), getPivotZ());
+            trans = trans.deriveWithScale(getX(), getY(), getZ());
+            return trans.deriveWithTranslation(-getPivotX(), -getPivotY(), -getPivotZ());
+        } else {
+            return trans.deriveWithScale(getX(), getY(), getZ());
+        }
+    }
+
     @Override
     void validate() {
         getX(); getPivotX();
--- a/modules/graphics/src/main/java/javafx/scene/transform/Shear.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/transform/Shear.java	Tue Sep 10 14:12:43 2013 -0700
@@ -29,6 +29,7 @@
 import javafx.beans.property.DoublePropertyBase;
 
 import com.sun.javafx.geom.transform.Affine3D;
+import com.sun.javafx.geom.transform.BaseTransform;
 import javafx.geometry.Point2D;
 import javafx.geometry.Point3D;
 
@@ -698,6 +699,19 @@
         }
     }
 
+    /**
+     * @treatAsPrivate implementation detail
+     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+     */
+    @Deprecated
+    @Override
+    public BaseTransform impl_derive(final BaseTransform trans) {
+        return trans.deriveWithConcatenation(
+                1.0, getY(),
+                getX(), 1.0,
+                getTx(), getTy());
+    }
+
     @Override
     void validate() {
         getX(); getPivotX();
--- a/modules/graphics/src/main/java/javafx/scene/transform/Transform.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/transform/Transform.java	Tue Sep 10 14:12:43 2013 -0700
@@ -33,7 +33,10 @@
 import com.sun.javafx.WeakReferenceQueue;
 import com.sun.javafx.binding.ExpressionHelper;
 import com.sun.javafx.event.EventHandlerManager;
+import com.sun.javafx.geom.transform.Affine2D;
 import com.sun.javafx.geom.transform.Affine3D;
+import com.sun.javafx.geom.transform.AffineBase;
+import com.sun.javafx.geom.transform.BaseTransform;
 import com.sun.javafx.scene.transform.TransformUtils;
 import java.lang.ref.SoftReference;
 import javafx.beans.InvalidationListener;
@@ -1982,6 +1985,13 @@
      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
      */
     @Deprecated
+    public abstract BaseTransform impl_derive(BaseTransform t);
+
+    /**
+     * @treatAsPrivate implementation detail
+     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+     */
+    @Deprecated
     public void impl_add(final Node node) {
         impl_nodes.add(node);
     }
--- a/modules/graphics/src/main/java/javafx/scene/transform/Translate.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/transform/Translate.java	Tue Sep 10 14:12:43 2013 -0700
@@ -29,6 +29,7 @@
 import javafx.beans.property.DoublePropertyBase;
 
 import com.sun.javafx.geom.transform.Affine3D;
+import com.sun.javafx.geom.transform.BaseTransform;
 import javafx.geometry.Point2D;
 import javafx.geometry.Point3D;
 
@@ -526,6 +527,16 @@
         trans.translate(getX(), getY(), getZ());
     }
 
+    /**
+     * @treatAsPrivate implementation detail
+     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
+     */
+    @Deprecated
+    @Override
+    public BaseTransform impl_derive(final BaseTransform trans) {
+        return trans.deriveWithTranslation(getX(), getY(), getZ());
+    }
+
     @Override
     void validate() {
         getX();
--- a/modules/graphics/src/main/jsl-prism/CompileJSL.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/jsl-prism/CompileJSL.java	Tue Sep 10 14:12:43 2013 -0700
@@ -488,6 +488,7 @@
         // create the basic Solid+Texture* shaders
         compileSolidTexture(jslcinfo, "RGB");
         compileMaskTexture(jslcinfo, "RGB");
+        compileMaskTexture(jslcinfo, "Super");
         compileSolidTexture(jslcinfo, "YV12");
         compileSolidTexture(jslcinfo, "FirstPassLCD");
         compileLCDShader(jslcinfo, "SecondPassLCD");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/jsl-prism/PaintMaskTextureSuper.jsl	Tue Sep 10 14:12:43 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+param sampler inputTex0; // Used for NGRegion image cache
+param sampler inputTex1; // Used for GlyphCache (note it is mask)
+
+float4 paint(float2 texCoord0, float2 texCoord1)
+{
+    //texCoord0: the actual texture coordinates
+    //texCoord1: the weight for each texture (usually 0 or 1)
+    return (sample(inputTex0, texCoord0) * texCoord1.x)  + 
+           (sample(inputTex1, texCoord0).a * texCoord1.y) ;
+}
--- a/modules/graphics/src/main/native-font/directwrite.cpp	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-font/directwrite.cpp	Tue Sep 10 14:12:43 2013 -0700
@@ -204,7 +204,7 @@
     lpStruct->fontFace = (IDWriteFontFace *)env->GetLongField(lpObject, DWRITE_GLYPH_RUNFc.fontFace);
     lpStruct->fontEmSize = env->GetFloatField(lpObject, DWRITE_GLYPH_RUNFc.fontEmSize);
     ((jshort*)lpStruct->glyphIndices)[0] = env->GetShortField(lpObject, DWRITE_GLYPH_RUNFc.glyphIndices);
-    ((float*)lpStruct->glyphAdvances)[0] = env->GetShortField(lpObject, DWRITE_GLYPH_RUNFc.glyphAdvances);
+    ((float*)lpStruct->glyphAdvances)[0] = env->GetFloatField(lpObject, DWRITE_GLYPH_RUNFc.glyphAdvances);
     ((float)lpStruct->glyphOffsets[0].advanceOffset) = env->GetFloatField(lpObject, DWRITE_GLYPH_RUNFc.advanceOffset);
     ((float)lpStruct->glyphOffsets[0].ascenderOffset) = env->GetFloatField(lpObject, DWRITE_GLYPH_RUNFc.ascenderOffset);
     lpStruct->isSideways = env->GetBooleanField(lpObject, DWRITE_GLYPH_RUNFc.isSideways);
--- a/modules/graphics/src/main/native-glass/lens/android/android.c	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/android/android.c	Tue Sep 10 14:12:43 2013 -0700
@@ -105,7 +105,7 @@
 jobject jFXActivity;
 jclass jFXActivityClass;
 jmethodID jFXActivity_getInstance;
-jmethodID jFXActivity_getLDPath;
+jmethodID jFXActivity_getDataDir;
 jmethodID jFXActivity_showIME;
 jmethodID jFXActivity_hideIME;
 jmethodID jFXActivity_shutdown;
@@ -134,20 +134,27 @@
     jFXActivity = (*env)->CallStaticObjectMethod(env, jFXActivityClass, jFXActivity_getInstance);
     CHECK_EXCEPTION(env);
 
-    jFXActivity_getLDPath = (*env)->GetMethodID(env, jFXActivityClass,
-            "getLDPath", "()Ljava/lang/String;");
+    jFXActivity_getDataDir = (*env)->GetMethodID(env, jFXActivityClass,
+            "getDataDir", "()Ljava/lang/String;");
     CHECK_EXCEPTION(env);
 }
 
+#define LIB_DIR     "lib"
+#define PATH_SEP    "/"
+
 void init_functions(JNIEnv *env) {
     const char *libglass_name = "libglass_lens_eglfb.so";
-    jstring jldpath = (*env)->CallObjectMethod(env, jFXActivity, jFXActivity_getLDPath);
-    const char *cpath = (*env)->GetStringUTFChars(env, jldpath, 0);
-    int cpath_len = (*env)->GetStringUTFLength(env, jldpath);
+    jstring jdatadir = (*env)->CallObjectMethod(env, jFXActivity, jFXActivity_getDataDir);
+    
+    const char *cpath = (*env)->GetStringUTFChars(env, jdatadir, 0);
+    int cpath_len = (*env)->GetStringUTFLength(env, jdatadir);
 
-    char *fullpath = (char *) calloc(cpath_len + strlen(libglass_name) + 2, 1);
+    char *fullpath = (char *) calloc(cpath_len + strlen(libglass_name) + 
+                                     2 * strlen(PATH_SEP) + strlen(LIB_DIR) + 1, 1);
     strcpy(fullpath, cpath);
-    strcat(fullpath, "/");
+    strcat(fullpath, PATH_SEP);
+    strcat(fullpath, LIB_DIR);
+    strcat(fullpath, PATH_SEP);
     strcat(fullpath, libglass_name);
 
     void *libglass = dlopen(fullpath, RTLD_LAZY | RTLD_GLOBAL);
--- a/modules/graphics/src/main/native-glass/lens/platform-util/dispmanCursor.c	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/dispmanCursor.c	Tue Sep 10 14:12:43 2013 -0700
@@ -93,14 +93,14 @@
 
             fbDispmanAddDispmanxElement();
         }
+        cursor.currentCursor = nativeCursorHandle;
 
-        update = vc_dispmanx_update_start(0);
-        vc_dispmanx_element_change_source(update, cursor.element, cursorImage->resource);
-        vc_dispmanx_update_submit_sync(update);
+        if (cursor.isVisible) {
+            update = vc_dispmanx_update_start(0);
+            vc_dispmanx_element_change_source(update, cursor.element, cursorImage->resource);
+            vc_dispmanx_update_submit_sync(update);
+        }
 
-        cursor.isVisible = 1;
-
-        cursor.currentCursor = nativeCursorHandle;
     }
 }
 
@@ -257,10 +257,20 @@
     DispmanCursorImage *cursorImage = (DispmanCursorImage *)jlong_to_ptr(nativeCursorHandle);
 
     if (cursorImage != NULL && cursorImage->resource != 0) {
+        if (cursor.currentCursor == nativeCursorHandle && cursor.isVisible) {
+            DISPMANX_UPDATE_HANDLE_T update;
+            update = vc_dispmanx_update_start(0);
+            vc_dispmanx_element_change_source(update, 
+                                              cursor.element, 0 /* resource*/);
+            vc_dispmanx_update_submit_sync(update);
+        }
         vc_dispmanx_resource_delete(cursorImage->resource);
     }
 
     free(cursorImage);
+    if (cursor.currentCursor == nativeCursorHandle) {
+        cursor.currentCursor = 0;
+    }
 }
 
 
@@ -269,15 +279,20 @@
     if (isVisible) {
         if (!cursor.isVisible && cursor.currentCursor != 0) {
             fbDispmanSetNativeCursor(cursor.currentCursor);
+            DispmanCursorImage *cursorImage = 
+                (DispmanCursorImage *)jlong_to_ptr(cursor.currentCursor);
+            DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
+            vc_dispmanx_element_change_source(update, cursor.element, 
+                                              cursorImage->resource);
+            vc_dispmanx_update_submit_sync(update);
         }
     } else {
         DISPMANX_UPDATE_HANDLE_T update;
         update = vc_dispmanx_update_start(0);
         vc_dispmanx_element_change_source(update, cursor.element, 0 );
         vc_dispmanx_update_submit_sync(update);
-
-        cursor.isVisible = 0;
     }
+    cursor.isVisible = isVisible;
 }
 
 
--- a/modules/graphics/src/main/native-glass/lens/platform-util/omapCursor.c	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/omapCursor.c	Tue Sep 10 14:12:43 2013 -0700
@@ -132,7 +132,6 @@
         GLASS_LOG_SEVERE("Cannot write cursor plane");
         return;
     }
-    cursor.isVisible = 1;   
 }
 
 jlong fbOmapCreateNativeCursor(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height) {
@@ -223,8 +222,10 @@
 void fbOmapSetVisible(jboolean isVisible) {
     if (isVisible) {
         if (!cursor.isVisible && cursor.currentCursor != 0) {
-            FBCursorImage *cursorImage = (FBCursorImage *)jlong_to_ptr(cursor.currentCursor);
-            fbOmapCreateCursor(cursorImage->buffer, cursorImage->width, cursorImage->height, cursorImage->bpp);
+            FBCursorImage *cursorImage = 
+                (FBCursorImage *)jlong_to_ptr(cursor.currentCursor);
+            fbOmapCreateCursor(cursorImage->buffer, cursorImage->width, 
+                               cursorImage->height, cursorImage->bpp);
         }
     } else {
         fbOmapCursorClose();
--- a/modules/graphics/src/main/native-glass/lens/wm/LensWindowManager.c	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/wm/LensWindowManager.c	Tue Sep 10 14:12:43 2013 -0700
@@ -1235,17 +1235,17 @@
                                                _dragGrabbingWindow,
                                                com_sun_glass_events_TouchEvent_TOUCH_MOVED,
                                                touchId , relX, relY, _mousePosX, _mousePosY);
+        } else {
+            GLASS_LOG_FINEST("MouseEvent_MOVE on window %i[%p]",
+                           (_dragGrabbingWindow)?_dragGrabbingWindow->id:-1,
+                           _dragGrabbingWindow);
+            glass_application_notifyMouseEvent(env,
+                                               _dragGrabbingWindow,
+                                               com_sun_glass_events_MouseEvent_MOVE,
+                                               relX, relY, _mousePosX, _mousePosY,
+                                               com_sun_glass_events_MouseEvent_BUTTON_NONE);
         }
 
-        GLASS_LOG_FINEST("MouseEvent_MOVE on window %i[%p]",
-                       (_dragGrabbingWindow)?_dragGrabbingWindow->id:-1,
-                       _dragGrabbingWindow);
-        glass_application_notifyMouseEvent(env,
-                                           _dragGrabbingWindow,
-                                           com_sun_glass_events_MouseEvent_MOVE,
-                                           relX, relY, _mousePosX, _mousePosY,
-                                           com_sun_glass_events_MouseEvent_BUTTON_NONE);
-
 
     } else if (!_onDraggingAction && window != NULL) {
 
@@ -1254,17 +1254,17 @@
                                                window,
                                                com_sun_glass_events_TouchEvent_TOUCH_MOVED,
                                                touchId , relX, relY, _mousePosX, _mousePosY);
+        } else {
+            GLASS_LOG_FINEST("MouseEvent_MOVE on window %i[%p]",
+                           (window)?window->id:-1,
+                           window);
+            glass_application_notifyMouseEvent(env,
+                                               window,
+                                               com_sun_glass_events_MouseEvent_MOVE,
+                                               relX, relY, _mousePosX, _mousePosY,
+                                               com_sun_glass_events_MouseEvent_BUTTON_NONE);
         }
 
-         GLASS_LOG_FINEST("MouseEvent_MOVE on window %i[%p]",
-                       (window)?window->id:-1,
-                       window);
-        glass_application_notifyMouseEvent(env,
-                                           window,
-                                           com_sun_glass_events_MouseEvent_MOVE,
-                                           relX, relY, _mousePosX, _mousePosY,
-                                           com_sun_glass_events_MouseEvent_BUTTON_NONE);
-
     }
 
 }
--- a/modules/graphics/src/main/native-glass/win/GlassWindow.cpp	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-glass/win/GlassWindow.cpp	Tue Sep 10 14:12:43 2013 -0700
@@ -81,7 +81,8 @@
     m_beforeFullScreenMenu(NULL),
     m_pProvider(NULL),
     m_a11yInitRequested(false),
-    m_a11yTreeIsReady(false)
+    m_a11yTreeIsReady(false),
+    m_hIcon(NULL)
 {
     m_grefThis = GetEnv()->NewGlobalRef(jrefThis);
     m_minSize.x = m_minSize.y = -1;   // "not set" value
@@ -104,6 +105,10 @@
 
 GlassWindow::~GlassWindow()
 {
+    if (m_hIcon) {
+        ::DestroyIcon(m_hIcon);
+    }
+
     if (m_grefThis) {
         GetEnv()->DeleteGlobalRef(m_grefThis);
     }
@@ -940,6 +945,17 @@
     m_isEnabled = enabled;
 }
 
+void GlassWindow::SetIcon(HICON hIcon)
+{
+    ::SendMessage(GetHWND(), WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
+    ::SendMessage(GetHWND(), WM_SETICON, ICON_BIG, (LPARAM)hIcon);
+
+    if (m_hIcon) {
+        ::DestroyIcon(m_hIcon);
+    }
+    m_hIcon = hIcon;
+}
+
 /*
  * JNI methods section
  *
@@ -1627,16 +1643,9 @@
     (JNIEnv *env, jobject jThis, jlong ptr, jobject jPixels)
 {
     HWND hWnd = (HWND)ptr;
-
-    // ::SendMessage() is OK to call from any thread - don't bother with ENTER...
-    if (!jPixels) {
-        ::SendMessage(hWnd, WM_SETICON, ICON_SMALL, NULL);
-        ::SendMessage(hWnd, WM_SETICON, ICON_BIG, NULL);
-    } else {
-        HICON hIcon = Pixels::CreateIcon(env, jPixels);
-
-        ::SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
-        ::SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
+    GlassWindow *pWindow = GlassWindow::FromHandle(hWnd);
+    if (pWindow) {
+        pWindow->SetIcon(!jPixels ? NULL : Pixels::CreateIcon(env, jPixels));
     }
 }
 
--- a/modules/graphics/src/main/native-glass/win/GlassWindow.h	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-glass/win/GlassWindow.h	Tue Sep 10 14:12:43 2013 -0700
@@ -104,6 +104,9 @@
 
     virtual BOOL EnterFullScreenMode(GlassView * view, BOOL animate, BOOL keepRatio);
     virtual void ExitFullScreenMode(BOOL animate);
+
+    void SetIcon(HICON hIcon);
+
 protected:
     virtual LRESULT WindowProc(UINT msg, WPARAM wParam, LPARAM lParam);
 
@@ -146,6 +149,8 @@
 
     HMENU m_hMenu;
 
+    HICON m_hIcon;
+
     //NOTE: this is not a rectangle. The left, top, right, and bottom
     //components contain corresponding insets values.
     RECT m_insets;
--- a/modules/graphics/src/main/native-prism-d3d/D3DContext.cc	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-d3d/D3DContext.cc	Tue Sep 10 14:12:43 2013 -0700
@@ -88,7 +88,6 @@
     pd3dObjectEx = pd3dEx;
     pd3dDevice = NULL;
     pd3dDeviceEx = NULL;
-    deviceWindow = 0;
     adapterOrdinal = adapter;
     defaulResourcePool = D3DPOOL_SYSTEMMEM;
 
@@ -161,10 +160,6 @@
     SAFE_RELEASE(pd3dDevice);
     SAFE_RELEASE(pd3dDeviceEx);
 
-    if (deviceWindow) {
-        DestroyWindow(deviceWindow);
-    }
-
     if (phongShader) {
         delete phongShader;
         phongShader = NULL;
--- a/modules/graphics/src/main/native-prism-d3d/D3DContext.h	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-d3d/D3DContext.h	Tue Sep 10 14:12:43 2013 -0700
@@ -268,7 +268,6 @@
     IDirect3DDevice9        *pd3dDevice;
     IDirect3DDevice9Ex      *pd3dDeviceEx;
     IDirect3DSurface9       *currentSurface;
-    HWND                     deviceWindow;
     IDirect3D9              *pd3dObject;
     IDirect3D9Ex            *pd3dObjectEx;
 
--- a/modules/graphics/src/main/native-prism-d3d/D3DContextInit.cc	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-d3d/D3DContextInit.cc	Tue Sep 10 14:12:43 2013 -0700
@@ -38,6 +38,7 @@
 
     params.Windowed = TRUE;
     params.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    params.hDeviceWindow = GetDesktopWindow();
 
     D3DCAPS9 d3dCaps;
 
@@ -54,16 +55,14 @@
 
     RlsTraceLn(NWT_TRACE_VERBOSE, (hwVertexProcessing ? "\tHARDWARE_VERTEXPROCESSING": "\tSOFTWARE_VERTEXPROCESSING"));
 
-    deviceWindow = D3DPipelineManager::GetInstance()->CreateDeviceFocusWindow(adapterOrdinal);
-
     if (pd3dObjectEx) {
-        hr = pd3dObjectEx->CreateDeviceEx(adapterOrdinal, devType, deviceWindow,
+        hr = pd3dObjectEx->CreateDeviceEx(adapterOrdinal, devType, 0,
             dwBehaviorFlags, &params, 0, &pd3dDeviceEx);
         if (SUCCEEDED(hr)) {
             pd3dDevice = addRef<IDirect3DDevice9>(pd3dDeviceEx);
         }
     } else {
-        hr = pd3dObject->CreateDevice(adapterOrdinal, devType, deviceWindow,
+        hr = pd3dObject->CreateDevice(adapterOrdinal, devType, 0,
             dwBehaviorFlags, &params, &pd3dDevice);
     }
 
--- a/modules/graphics/src/main/native-prism-d3d/D3DMeshView.cc	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-d3d/D3DMeshView.cc	Tue Sep 10 14:12:43 2013 -0700
@@ -74,18 +74,17 @@
 
 void D3DMeshView::setPointLight(int index, float x, float y, float z,
     float r, float g, float b, float w) {
-    if (index < 0 && index > 2) {
-        cerr << "Error in D3DMeshView::setPointLight: index out of range! index = "
-                << index << endl;
+    // NOTE: We only support up to 3 point lights at the present
+    if (index >= 0 && index <= 2) {
+        lights[index].position[0] = x;
+        lights[index].position[1] = y;
+        lights[index].position[2] = z;
+        lights[index].color[0] = r;
+        lights[index].color[1] = g;
+        lights[index].color[2] = b;
+        lights[index].w = w;
+        lightsDirty = TRUE;
     }
-    lights[index].position[0] = x;
-    lights[index].position[1] = y;
-    lights[index].position[2] = z;
-    lights[index].color[0] = r;
-    lights[index].color[1] = g;
-    lights[index].color[2] = b;
-    lights[index].w = w;
-    lightsDirty = TRUE;
 }
 
 void D3DMeshView::sortLights() {
--- a/modules/graphics/src/main/native-prism-d3d/D3DPipelineManager.cc	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-d3d/D3DPipelineManager.cc	Tue Sep 10 14:12:43 2013 -0700
@@ -48,8 +48,6 @@
         maj == LOBYTE(LOWORD(winVer)) && min <= HIBYTE(LOWORD(winVer));
 }
 
-static LPCTSTR D3DFocusWindowClassName = L"D3DPrismFocusWindow";
-
 inline bool isForcedGPU(IConfig &cfg) { return cfg.getBool("forceGPU"); }
 
 D3DPipelineManager * D3DPipelineManager::CreateInstance(IConfig &cfg) {
@@ -74,7 +72,6 @@
     pd3d9Ex = NULL;
     pAdapters = NULL;
     adapterCount = 0;
-    classAtom = 0;
 
     devType = SelectDeviceType();
 
@@ -170,10 +167,6 @@
         delete[] pAdapters;
         pAdapters = NULL;
     }
-    if (classAtom != 0) {
-        UnregisterClass(D3DFocusWindowClassName, GetModuleHandle(NULL));
-        classAtom = 0;
-    }
     return S_OK;
 }
 
@@ -592,42 +585,6 @@
     return newFormat;
 }
 
-HWND D3DPipelineManager::CreateDeviceFocusWindow(int adapterOrdinal) {
-
-    if (classAtom == 0) {
-        WNDCLASS wc = {};
-        wc.hInstance = GetModuleHandle(NULL);
-        wc.lpfnWndProc = DefWindowProc;
-        wc.lpszClassName = D3DFocusWindowClassName;
-
-        classAtom = RegisterClass(&wc);
-        if (classAtom == 0) {
-            DWORD lastError = GetLastError();
-            RlsTraceLn1(NWT_TRACE_ERROR,
-                "CreateFocusWindow: error registering window class, lastError=%d", lastError);
-            return 0;
-        }
-    }
-
-    MONITORINFO mi = { sizeof(MONITORINFO) };
-    HMONITOR hMon = pd3d9->GetAdapterMonitor(adapterOrdinal);
-    if (hMon == 0 || !GetMonitorInfo(hMon, (LPMONITORINFO)&mi)) {
-        RlsTraceLn1(NWT_TRACE_ERROR,
-            "CreateFocusWindow: error getting monitor info for adapter=%d", adapterOrdinal);
-        return 0;
-    }
-
-    HWND hWnd = CreateWindow(D3DFocusWindowClassName, D3DFocusWindowClassName, WS_POPUP,
-        mi.rcMonitor.left, mi.rcMonitor.top, 1, 1,
-        NULL, NULL, GetModuleHandle(NULL), NULL);
-
-    if (hWnd == 0) {
-        RlsTraceLn(NWT_TRACE_ERROR, "CreateFocusWindow: CreateWindow failed");
-    }
-
-    return hWnd;
-}
-
 HRESULT D3DPipelineManager::GetD3DContext(UINT adapterOrdinal,
                                           D3DContext **ppd3dContext)
 {
--- a/modules/graphics/src/main/native-prism-d3d/D3DPipelineManager.h	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-d3d/D3DPipelineManager.h	Tue Sep 10 14:12:43 2013 -0700
@@ -95,8 +95,6 @@
     static void SetErrorMessage(char const *msg);
     static void SetErrorMessageV(char const *msg, ...);
 
-    HWND CreateDeviceFocusWindow(int adapterOrdinal);
-
 private:
     D3DPipelineManager(IConfig &);
 
@@ -149,7 +147,6 @@
     static D3DPipelineManager* pMgr;
 
     D3DMULTISAMPLE_TYPE userMultiSampleType;
-    ATOM classAtom;
 };
 
 #define OS_UNDEFINED    (0 << 0)
--- a/modules/graphics/src/main/native-prism-d3d/D3DResourceManager.cc	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-d3d/D3DResourceManager.cc	Tue Sep 10 14:12:43 2013 -0700
@@ -432,8 +432,8 @@
     if(FAILED(res = pd3dObject->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
                                     D3DDEVTYPE_HAL, format, false,
                                     msType, &totalSamples))) {
-        DebugPrintD3DError(res, "D3DRM::CreateRenderTarget failed D3DMULTISAMPLE_"/
-                + (int)msType +"_SAMPLES not supported");
+        DebugPrintD3DError(res, "D3DRM::CreateRenderTarget failed, specified"
+                                " D3DMULTISAMPLE type is not supported");
         return res;
     }
 
--- a/modules/graphics/src/main/native-prism-d3d/D3DWindow.cc	Fri Sep 06 13:22:16 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, 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.
- */
-
-// this whole file comment related to huge comment in D3DWindow.java
-
-#if 0
-#include <jni.h>
-#include <jni_md.h>
-#define NO_JAWT
-#ifndef NO_JAWT
-#include <jawt.h>
-#include <jawt_md.h>
-#else
-#include <windows.h>
-#endif
-
-#include <assert.h>
-
-#include "com_sun_prism_d3d_D3DWindow.h"
-
-
-JNIEXPORT  void JNICALL Java_com_sun_prism_d3d_D3DWindow_setParentWindow(JNIEnv *env, jclass clz, jlong hChild, jlong hParent) {
-    HWND result = SetParent((HWND)hChild, (HWND)hParent);
-    // printf("SetParent returned result=%x, lastError=%d", result, GetLastError());fflush(stdout);
-    // SetWindowStyle(hChild, WS_OVERLAPPED|WS_CHILD);
-}
-
-
-JNIEXPORT jlong JNICALL Java_com_sun_prism_d3d_D3DWindow_getWindowHandle
-  (JNIEnv *env, jclass clz, jobject object) {
-#ifndef NO_JAWT
-    JAWT awt;
-    JAWT_DrawingSurface* ds;
-    JAWT_DrawingSurfaceInfo* dsi;
-    JAWT_Win32DrawingSurfaceInfo* dsi_win;
-    jboolean result;
-    jint lock;
-    jlong ret = 0;
-
-    // Get the AWT interface, 1.3 or greater
-    awt.version = JAWT_VERSION_1_3;
-    result = JAWT_GetAWT(env, &awt);
-    if (result == JNI_FALSE) {
-        printf("D3DWindow:: failed to get AWT Native Interface.\n");
-        fflush(stdout);
-        return (jlong) 0;
-    };
-
-    // Get the drawing surface
-    ds = awt.GetDrawingSurface(env, object);
-    if (ds == NULL) {
-        printf("D3DWindow:: failed to get AWT Native Interface.\n");
-        fflush(stdout);
-        return (jlong) 0;
-    };
-
-    // Lock the drawing surface
-    lock = ds->Lock(ds);
-    if ((lock & JAWT_LOCK_ERROR) != 0) {
-        printf("D3DWindow:: lock failed.\n");
-        fflush(stdout);
-        awt.FreeDrawingSurface(ds);
-        return (jlong) 0;
-    };
-
-    // Get the drawing surface info
-    dsi = ds->GetDrawingSurfaceInfo(ds);
-
-    if (dsi == NULL) {
-        printf("Error getting surface info\n");
-        ds->Unlock(ds);
-        awt.FreeDrawingSurface(ds);
-        return (jlong) 0;
-    }
-    ret = NULL;
-    // Get the platform-specific drawing info
-    dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
-//    printf("HWND=%x\n", dsi_win->hwnd); fflush(stdout);
-//    printf("showing window.\n"); fflush(stdout);
-    ShowWindow(dsi_win->hwnd, SW_SHOW);
-    {
-        // NOTE: investigate AWT issues with window being non-visible child?
-        ret = (jlong)dsi_win->hwnd;
-    }
-
-
-    // Free the drawing surface info
-    ds->FreeDrawingSurfaceInfo(dsi);
-
-    // Unlock the drawing surface
-    ds->Unlock(ds);
-
-    // Free the drawing surface
-    awt.FreeDrawingSurface(ds);
-    return ret;
-#else
-    printf("Incompatible jawt, skipping\n");fflush(stdout);
-    return (jlong)NULL;
-#endif
-
-}
-#endif
--- a/modules/graphics/src/main/native-prism-es2/GLContext.c	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-es2/GLContext.c	Tue Sep 10 14:12:43 2013 -0700
@@ -153,6 +153,7 @@
     ctxInfo->state.fillMode = GL_FILL;
     ctxInfo->state.cullEnable = JNI_FALSE;
     ctxInfo->state.cullMode = GL_BACK;
+    ctxInfo->state.fbo = 0;    
 }
 
 void clearBuffers(ContextInfo *ctxInfo,
@@ -855,7 +856,11 @@
 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nGetFBO
 (JNIEnv *env, jclass class) {
     GLint param;
-    /* TODO: Should use state.fbo vs Querying GL */
+    /* The caching logic has been done on Java side if 
+     * platform isn't MAC or IOS. On these platforms Glass
+     * can change the FBO under us. We should be able to simplify the
+     * logic in Java and remove this method once once Glass stop doing it.
+     */
     glGetIntegerv(GL_FRAMEBUFFER_BINDING, &param);
     return (jint) param;
 }
@@ -955,18 +960,6 @@
     return value;
 }
 
-/*
- * Class:     com_sun_prism_es2_GLContext
- * Method:    nOneValueGetIntegerv
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nOneValueGetIntegerv
-(JNIEnv *env, jclass class, jint pname) {
-    GLint param;
-    glGetIntegerv((GLenum) translatePrismToGL(pname), &param);
-    return (jint) param;
-}
-
 GLint translatePixelStore(int pname) {
     switch (pname) {
             // Use by glPixelStorei
@@ -2259,7 +2252,8 @@
 {
     ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo);
     MeshViewInfo *meshViewInfo = (MeshViewInfo *) jlong_to_ptr(nativeMeshViewInfo);
-    if ((ctxInfo == NULL) || (meshViewInfo == NULL)) {
+    // NOTE: We only support up to 3 point lights at the present
+    if ((ctxInfo == NULL) || (meshViewInfo == NULL) || (index < 0) || (index > 2)) {
         return;
     }
     meshViewInfo->pointLightIndex = index;
--- a/modules/graphics/src/main/native-prism-es2/windows/WinGLContext.c	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-es2/windows/WinGLContext.c	Tue Sep 10 14:12:43 2013 -0700
@@ -287,7 +287,9 @@
 
     // initialize platform states and properties to match
     // cached states and properties
-    ctxInfo->wglSwapIntervalEXT(0);
+    if (ctxInfo->wglSwapIntervalEXT != NULL) {
+        ctxInfo->wglSwapIntervalEXT(0);
+    }
     ctxInfo->state.vSyncEnabled = JNI_FALSE;
     ctxInfo->vSyncRequested = vSyncRequested;
 
@@ -339,5 +341,7 @@
     }
     interval = (vSyncNeeded) ? 1 : 0;
     ctxInfo->state.vSyncEnabled = vSyncNeeded;
-    ctxInfo->wglSwapIntervalEXT(interval);
+    if (ctxInfo->wglSwapIntervalEXT != NULL) {
+        ctxInfo->wglSwapIntervalEXT(interval);
+    }
 }
--- a/modules/graphics/src/main/native-prism-es2/x11/X11GLContext.c	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-es2/x11/X11GLContext.c	Tue Sep 10 14:12:43 2013 -0700
@@ -271,11 +271,18 @@
             "GLX_SGI_swap_control")) {
         ctxInfo->glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
                 dlsym(RTLD_DEFAULT, "glXSwapIntervalSGI");
+
+        if (ctxInfo->glXSwapIntervalSGI == NULL) {
+            ctxInfo->glXSwapIntervalSGI = glXGetProcAddress("glXSwapIntervalSGI");
+        }
+
     }
 
     // initialize platform states and properties to match
     // cached states and properties
-    ctxInfo->glXSwapIntervalSGI(0);
+    if (ctxInfo->glXSwapIntervalSGI != NULL) {
+        ctxInfo->glXSwapIntervalSGI(0);
+    }
     ctxInfo->state.vSyncEnabled = JNI_FALSE;
     ctxInfo->vSyncRequested = vSyncRequested;
 
@@ -323,5 +330,7 @@
     }
     interval = (vSyncNeeded) ? 1 : 0;
     ctxInfo->state.vSyncEnabled = vSyncNeeded;
-    ctxInfo->glXSwapIntervalSGI(interval);
+    if (ctxInfo->glXSwapIntervalSGI != NULL) {
+        ctxInfo->glXSwapIntervalSGI(interval);
+    }
 }
--- a/modules/graphics/src/main/native-prism-sw/PiscesPaint.c	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/main/native-prism-sw/PiscesPaint.c	Tue Sep 10 14:12:43 2013 -0700
@@ -29,6 +29,12 @@
 #include <PiscesSysutils.h>
 #include <PiscesMath.h>
 
+#define NO_REPEAT_NO_INTERPOLATE        0
+#define REPEAT_NO_INTERPOLATE           1
+#define NO_REPEAT_INTERPOLATE_NO_ALPHA  2
+#define NO_REPEAT_INTERPOLATE_ALPHA     3
+#define REPEAT_INTERPOLATE_NO_ALPHA     4
+#define REPEAT_INTERPOLATE_ALPHA        5
 
 static jlong lmod(jlong x, jlong y) {
     x = x % y;
@@ -342,21 +348,11 @@
     return (0xff000000) | (rr << 16) | (gg << 8) | bb;
 }
 
-static INLINE jboolean isInBounds(jint *a, jlong *la, jint min, jint max, jboolean repeat) {
+static INLINE jboolean isInBoundsNoRepeat(jint *a, jlong *la, jint min, jint max) {
     jboolean inBounds = XNI_TRUE;
     jint aval = *a;
     if (aval < min || aval > max) {
-        if (repeat) {
-            if (max > 0) {
-                *la = lmod(*la, (max+1) << 16);
-                *a = (jint)(*la >> 16);
-            } else {
-                *la = 0;
-                *a = 0;
-            }
-        } else {
-            inBounds = XNI_FALSE;
-        }
+        inBounds = XNI_FALSE;
     }
     return inBounds;
 }
@@ -365,27 +361,30 @@
 // this function is called when transform is translate or scale
 // because the bounding box will be always fully filled
 //
-static INLINE void isInBoundsFull(jint *a, jlong *la, jint min, jint max, jboolean repeat) {
+static INLINE void checkBoundsRepeat(jint *a, jlong *la, jint min, jint max) {
     jint aval = *a;
     if (aval < min || aval > max) {
-        if (repeat) {
-            if (max > 0) {
-                *la = lmod(*la, (max+1) << 16);
-                *a = (jint)(*la >> 16);
-            } else {
-                *la = 0;
-                *a = 0;
-            }
-        } else if (aval < min) {
-            *la = (min << 16);
-            *a = min;
+        if (max > 0) {
+            *la = lmod(*la, (max+1) << 16);
+            *a = (jint)(*la >> 16);
         } else {
-            *la = (max << 16);
-            *a = max;
+            *la = 0;
+            *a = 0;
         }
     }
 }
 
+static INLINE void checkBoundsNoRepeat(jint *a, jlong *la, jint min, jint max) {
+    jint aval = *a;
+    if (aval < min) {
+        *la = (min << 16);
+        *a = min;
+    } else if (aval > max) {
+        *la = (max << 16);
+        *a = max;
+    }
+}
+
 static INLINE void getPointsToInterpolate(jint *pts, jint *data, jint sidx, jint stride, jint p00,
     jint tx, jint txMin, jint txMax, jint ty, jint tyMin, jint tyMax)
 {
@@ -427,6 +426,20 @@
     jint tyMin = rdr->_texture_interpolateMinY;
     jint txMax = rdr->_texture_interpolateMaxX;
     jint tyMax = rdr->_texture_interpolateMaxY;
+    jint repeatInterpolateMode;
+
+    if (rdr->_texture_interpolate) {
+        if (rdr->_texture_hasAlpha) {
+            repeatInterpolateMode = (rdr->_texture_repeat) ?
+                REPEAT_INTERPOLATE_ALPHA : NO_REPEAT_INTERPOLATE_ALPHA;
+        } else {
+            repeatInterpolateMode = (rdr->_texture_repeat) ?
+                REPEAT_INTERPOLATE_NO_ALPHA : NO_REPEAT_INTERPOLATE_NO_ALPHA;
+        }
+    } else {
+        repeatInterpolateMode = (rdr->_texture_repeat) ?
+            REPEAT_NO_INTERPOLATE : NO_REPEAT_NO_INTERPOLATE;
+    }
 
     minX = rdr->_minTouched;
     maxX = rdr->_maxTouched;
@@ -482,39 +495,436 @@
 
         y = rdr->_currY;
 
-        if (rdr->_texture_hasAlpha == XNI_TRUE) {
-            for (j = 0; j < height; j++, y++) {
-                pidx = paintOffset;
+        for (j = 0; j < height; j++, y++) {
+            pidx = paintOffset;
 
-                x = rdr->_currX;
+            x = rdr->_currX;
 
-                ltx = (x << 16) + rdr->_texture_m02;
-                lty = (y << 16) + rdr->_texture_m12;
+            ltx = (x << 16) + rdr->_texture_m02;
+            lty = (y << 16) + rdr->_texture_m12;
 
-                // we can compute here since (m00 == 65536) && (m10 == 0)                    
-                tx = (jint)(ltx >> 16);
-                ty = (jint)(lty >> 16);
-                hfrac = (jint)(ltx & 0xffff);
-                vfrac = (jint)(lty & 0xffff);
+            // we can compute here since (m00 == 65536) && (m10 == 0)
+            tx = (jint)(ltx >> 16);
+            ty = (jint)(lty >> 16);
+            hfrac = (jint)(ltx & 0xffff);
+            vfrac = (jint)(lty & 0xffff);
 
-                isInBoundsFull(&ty, &lty, tyMin-1, tyMax, rdr->_texture_repeat);
+            if (rdr->_texture_repeat) {
+                checkBoundsRepeat(&ty, &lty, tyMin-1, tyMax);
+            } else {
+                checkBoundsNoRepeat(&ty, &lty, tyMin-1, tyMax);
+            }
 
-                a = paint + pidx;
-                am = a + paintStride;
+            a = paint + pidx;
+            am = a + paintStride;
+
+            switch (repeatInterpolateMode) {
+            case NO_REPEAT_NO_INTERPOLATE:
                 while (a < am) {
-                    isInBoundsFull(&tx, &ltx, txMin-1, txMax, rdr->_texture_repeat);
-
+                    checkBoundsNoRepeat(&tx, &ltx, txMin-1, txMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = txtData[sidx];
+                    ++a;
+                    ++pidx;
+                    ++tx;
+                    ltx += 0x10000;
+                } // while (a < am)
+                break;
+            case REPEAT_NO_INTERPOLATE:
+                while (a < am) {
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = txtData[sidx];
+                    ++a;
+                    ++pidx;
+                    ++tx;
+                    ltx += 0x10000;
+                } // while (a < am)
+                break;
+            case NO_REPEAT_INTERPOLATE_ALPHA:
+                while (a < am) {
+                    checkBoundsNoRepeat(&tx, &ltx, txMin-1, txMax);
                     sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
                     p00 = txtData[sidx];
-                    if (rdr->_texture_interpolate) {
-                        if (rdr->_texture_repeat) {
-                            getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                tx, txMin, txMax, ty, tyMin, tyMax);
-                        } else {
-                            getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                tx, txMin, txMax, ty, tyMin, tyMax);
-                        }
+                    getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4points(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2points(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2points(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+                    ++a;
+                    ++pidx;
+                    ++tx;
+                    ltx += 0x10000;
+                } // while (a < am)
+                break;
+            case REPEAT_INTERPOLATE_ALPHA:
+                while (a < am) {
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    p00 = txtData[sidx];
+                    getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4points(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2points(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2points(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+                    ++a;
+                    ++pidx;
+                    ++tx;
+                    ltx += 0x10000;
+                } // while (a < am)
+                break;
+            case NO_REPEAT_INTERPOLATE_NO_ALPHA:
+                while (a < am) {
+                    checkBoundsNoRepeat(&tx, &ltx, txMin-1, txMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    p00 = txtData[sidx];
+                    getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4pointsNoAlpha(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+                    ++a;
+                    ++pidx;
+                    ++tx;
+                    ltx += 0x10000;
+                } // while (a < am)
+                break;
+            case REPEAT_INTERPOLATE_NO_ALPHA:
+                while (a < am) {
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    p00 = txtData[sidx];
+                    getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4pointsNoAlpha(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+                    ++a;
+                    ++pidx;
+                    ++tx;
+                    ltx += 0x10000;
+                } // while (a < am)
+                break;
+            }
+            paintOffset += paintStride;
+        } // for
+        }
+        break;
 
+    // scale transform
+    case TEXTURE_TRANSFORM_SCALE_TRANSLATE:
+        {
+        jint cval, pidx;
+        jint *a, *am;
+        jlong ltx, lty;
+        jint paintOffset = 0;
+        jint pts[3];
+        jint sidx, p00;
+
+        y = rdr->_currY;
+
+        for (j = 0; j < height; j++, y++) {
+            pidx = paintOffset;
+
+            x = rdr->_currX;
+
+            ltx = x * rdr->_texture_m00 + y * rdr->_texture_m01 + rdr->_texture_m02;
+            lty = x * rdr->_texture_m10 + y * rdr->_texture_m11 + rdr->_texture_m12;
+
+            a = paint + pidx;
+            am = a + paintStride;
+            switch (repeatInterpolateMode) {
+            case NO_REPEAT_NO_INTERPOLATE:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+                    checkBoundsNoRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsNoRepeat(&ty, &lty, tyMin-1, tyMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = txtData[sidx];
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case REPEAT_NO_INTERPOLATE:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsRepeat(&ty, &lty, tyMin-1, tyMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = txtData[sidx];
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case NO_REPEAT_INTERPOLATE_ALPHA:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+                    checkBoundsNoRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsNoRepeat(&ty, &lty, tyMin-1, tyMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    p00 = txtData[sidx];
+                    getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4points(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2points(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2points(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case REPEAT_INTERPOLATE_ALPHA:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsRepeat(&ty, &lty, tyMin-1, tyMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    p00 = txtData[sidx];
+                    getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4points(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2points(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2points(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case NO_REPEAT_INTERPOLATE_NO_ALPHA:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+                    checkBoundsNoRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsNoRepeat(&ty, &lty, tyMin-1, tyMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    p00 = txtData[sidx];
+                    getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4pointsNoAlpha(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case REPEAT_INTERPOLATE_NO_ALPHA:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsRepeat(&ty, &lty, tyMin-1, tyMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    p00 = txtData[sidx];
+                    getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4pointsNoAlpha(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            }
+            paintOffset += paintStride;
+        }//for
+        }
+        break;
+
+    // generic transform
+    case TEXTURE_TRANSFORM_GENERIC:
+        {
+        jint cval, pidx;
+        jint *a, *am;
+        jlong ltx, lty;
+        jint paintOffset = 0;
+        jint pts[3];
+        jint sidx, p00;
+
+        y = rdr->_currY;
+
+        for (j = 0; j < height; j++, y++) {
+            pidx = paintOffset;
+
+            x = rdr->_currX;
+
+            ltx = x * rdr->_texture_m00 + y * rdr->_texture_m01 + rdr->_texture_m02;
+            lty = x * rdr->_texture_m10 + y * rdr->_texture_m11 + rdr->_texture_m12;
+
+            a = paint + pidx;
+            am = a + paintStride;
+            switch (repeatInterpolateMode) {
+            case NO_REPEAT_NO_INTERPOLATE:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+
+                    jboolean inBounds =
+                        isInBoundsNoRepeat(&tx, &ltx, txMin-1, txMax) &&
+                        isInBoundsNoRepeat(&ty, &lty, tyMin-1, tyMax);
+                    if (inBounds) {
+                        sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                        p00 = txtData[sidx];
+                        assert(pidx >= 0);
+                        assert(pidx < rdr->_paint_length);
+                        paint[pidx] = p00;
+                    } else {
+                        assert(pidx >= 0);
+                        assert(pidx < rdr->_paint_length);
+                        paint[pidx] = 0x00000000;
+                    }
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case REPEAT_NO_INTERPOLATE:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsRepeat(&ty, &lty, tyMin-1, tyMax);
+                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                    p00 = txtData[sidx];
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = p00;
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case NO_REPEAT_INTERPOLATE_ALPHA:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+
+                    jboolean inBounds =
+                        isInBoundsNoRepeat(&tx, &ltx, txMin-1, txMax) &&
+                        isInBoundsNoRepeat(&ty, &lty, tyMin-1, tyMax);
+                    if (inBounds) {
+                        sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                        p00 = txtData[sidx];
+
+                        getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
+                            tx, txMin, txMax, ty, tyMin, tyMax);
                         if (hfrac && vfrac) {
                             cval = interpolate4points(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
                         } else if (hfrac) {
@@ -530,49 +940,60 @@
                     } else {
                         assert(pidx >= 0);
                         assert(pidx < rdr->_paint_length);
-                        paint[pidx] = p00;
+                        paint[pidx] = 0x00000000;
                     }
-
                     ++a;
                     ++pidx;
-                    ++tx;
-                    ltx += 0x10000;
-                } // while (a < am)
-                paintOffset += paintStride;
-            } // for
-        } else { // alpha
-            for (j = 0; j < height; j++, y++) {
-                pidx = paintOffset;
-
-                x = rdr->_currX;
-
-                ltx = (x << 16) + rdr->_texture_m02;
-                lty = (y << 16) + rdr->_texture_m12;
-
-                // we can compute here since (m00 == 65536) && (m10 == 0)                    
-                tx = (jint)(ltx >> 16);
-                ty = (jint)(lty >> 16);
-                hfrac = (jint)(ltx & 0xffff);
-                vfrac = (jint)(lty & 0xffff);
-
-                isInBoundsFull(&ty, &lty, tyMin-1, tyMax, rdr->_texture_repeat);
-
-                a = paint + pidx;
-                am = a + paintStride;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case REPEAT_INTERPOLATE_ALPHA:
                 while (a < am) {
-                    isInBoundsFull(&tx, &ltx, txMin-1, txMax, rdr->_texture_repeat);
-
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsRepeat(&ty, &lty, tyMin-1, tyMax);
                     sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
                     p00 = txtData[sidx];
-                    if (rdr->_texture_interpolate) {
-                        if (rdr->_texture_repeat) {
-                            getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                tx, txMin, txMax, ty, tyMin, tyMax);
-                        } else {
-                            getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                tx, txMin, txMax, ty, tyMin, tyMax);
-                        }
+                    getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4points(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2points(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2points(p00, pts[1], vfrac);
+                    } else {
+                        cval = p00;
+                    }
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
+                    ++a;
+                    ++pidx;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case NO_REPEAT_INTERPOLATE_NO_ALPHA:
+                while (a < am) {
+                    jint tx = (jint)(ltx >> 16);
+                    jint ty = (jint)(lty >> 16);
+                    jint hfrac = (jint)(ltx & 0xffff);
+                    jint vfrac = (jint)(lty & 0xffff);
 
+                    jboolean inBounds =
+                        isInBoundsNoRepeat(&tx, &ltx, txMin-1, txMax) &&
+                        isInBoundsNoRepeat(&ty, &lty, tyMin-1, tyMax);
+                    if (inBounds) {
+                        sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
+                        p00 = txtData[sidx];
+
+                        getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
+                            tx, txMin, txMax, ty, tyMin, tyMax);
                         if (hfrac && vfrac) {
                             cval = interpolate4pointsNoAlpha(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
                         } else if (hfrac) {
@@ -588,310 +1009,47 @@
                     } else {
                         assert(pidx >= 0);
                         assert(pidx < rdr->_paint_length);
-                        paint[pidx] = p00;
+                        paint[pidx] = 0x00000000;
                     }
-
                     ++a;
                     ++pidx;
-                    ++tx;
-                    ltx += 0x10000;
-                } // while (a < am)
-                paintOffset += paintStride;
-            } // for
-        }
-        }
-        break;
-
-    // scale transform
-    case TEXTURE_TRANSFORM_SCALE_TRANSLATE:
-        {
-        jint cval, pidx;
-        jint *a, *am;
-        jlong ltx, lty;
-        jint paintOffset = 0;
-        jint pts[3];
-        jint sidx, p00;
-
-        y = rdr->_currY;
-
-        if (rdr->_texture_hasAlpha == XNI_TRUE) {
-            for (j = 0; j < height; j++, y++) {
-                pidx = paintOffset;
-
-                x = rdr->_currX;
-
-                ltx = x * rdr->_texture_m00 + y * rdr->_texture_m01 + rdr->_texture_m02;
-                lty = x * rdr->_texture_m10 + y * rdr->_texture_m11 + rdr->_texture_m12;
-
-                a = paint + pidx;
-                am = a + paintStride;
+                    ltx += rdr->_texture_m00;
+                    lty += rdr->_texture_m10;
+                } // while (a < am)b
+                break;
+            case REPEAT_INTERPOLATE_NO_ALPHA:
                 while (a < am) {
                     jint tx = (jint)(ltx >> 16);
                     jint ty = (jint)(lty >> 16);
-
                     jint hfrac = (jint)(ltx & 0xffff);
                     jint vfrac = (jint)(lty & 0xffff);
-
-                    isInBoundsFull(&tx, &ltx, txMin-1, txMax, rdr->_texture_repeat);
-                    isInBoundsFull(&ty, &lty, tyMin-1, tyMax, rdr->_texture_repeat);
-
+                    checkBoundsRepeat(&tx, &ltx, txMin-1, txMax);
+                    checkBoundsRepeat(&ty, &lty, tyMin-1, tyMax);
                     sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
                     p00 = txtData[sidx];
-                    if (rdr->_texture_interpolate) {
-                        if (rdr->_texture_repeat) {
-                            getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                tx, txMin, txMax, ty, tyMin, tyMax);
-                        } else {
-                            getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                tx, txMin, txMax, ty, tyMin, tyMax);
-                        }
-
-                        if (hfrac && vfrac) {
-                            cval = interpolate4points(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
-                        } else if (hfrac) {
-                            cval = interpolate2points(p00, pts[0], hfrac);
-                        } else if (vfrac) {
-                            cval = interpolate2points(p00, pts[1], vfrac);
-                        } else {
-                            cval = p00;
-                        }
-
-                        assert(pidx >= 0);
-                        assert(pidx < rdr->_paint_length);
-
-                        paint[pidx] = cval;
+                    getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
+                        tx, txMin, txMax, ty, tyMin, tyMax);
+                    if (hfrac && vfrac) {
+                        cval = interpolate4pointsNoAlpha(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
+                    } else if (hfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[0], hfrac);
+                    } else if (vfrac) {
+                        cval = interpolate2pointsNoAlpha(p00, pts[1], vfrac);
                     } else {
-                        assert(pidx >= 0);
-                        assert(pidx < rdr->_paint_length);
-
-                        paint[pidx] = p00;
+                        cval = p00;
                     }
-
+                    assert(pidx >= 0);
+                    assert(pidx < rdr->_paint_length);
+                    paint[pidx] = cval;
                     ++a;
                     ++pidx;
-
                     ltx += rdr->_texture_m00;
                     lty += rdr->_texture_m10;
                 } // while (a < am)b
-                paintOffset += paintStride;
-            }//for
-        }//else _texture_hasAlpha == XNI_FALSE
-        else {
-            for (j = 0; j < height; j++, y++) {
-                pidx = paintOffset;
-
-                x = rdr->_currX;
-
-                ltx = x * rdr->_texture_m00 + y * rdr->_texture_m01 + rdr->_texture_m02;
-                lty = x * rdr->_texture_m10 + y * rdr->_texture_m11 + rdr->_texture_m12;
-
-                a = paint + pidx;
-                am = a + paintStride;
-                while (a < am) {
-                    jint tx = (jint)(ltx >> 16);
-                    jint ty = (jint)(lty >> 16);
-
-                    jint hfrac = (jint)(ltx & 0xffff);
-                    jint vfrac = (jint)(lty & 0xffff);
-
-                    isInBoundsFull(&tx, &ltx, txMin-1, txMax, rdr->_texture_repeat);
-                    isInBoundsFull(&ty, &lty, tyMin-1, tyMax, rdr->_texture_repeat);
-
-                    sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
-                    p00 = txtData[sidx];
-                    if (rdr->_texture_interpolate) {
-                        if (rdr->_texture_repeat) {
-                            getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                tx, txMin, txMax, ty, tyMin, tyMax);
-                        } else {
-                            getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                tx, txMin, txMax, ty, tyMin, tyMax);
-                        }
-
-                        if (hfrac && vfrac) {
-                            cval = interpolate4pointsNoAlpha(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
-                        } else if (hfrac) {
-                            cval = interpolate2pointsNoAlpha(p00, pts[0], hfrac);
-                        } else if (vfrac) {
-                            cval = interpolate2pointsNoAlpha(p00, pts[1], vfrac);
-                        } else {
-                            cval = p00;
-                        }
-
-                        assert(pidx >= 0);
-                        assert(pidx < rdr->_paint_length);
-
-                        paint[pidx] = cval;
-                    } else {
-                        assert(pidx >= 0);
-                        assert(pidx < rdr->_paint_length);
-
-                        paint[pidx] = p00;
-                    }
-
-                    ++a;
-                    ++pidx;
-
-                    ltx += rdr->_texture_m00;
-                    lty += rdr->_texture_m10;
-                }
-                paintOffset += paintStride;
+                break;
             }
-        }
-        }
-        break;
-
-    // generic transform
-    case TEXTURE_TRANSFORM_GENERIC:
-        {
-        jint cval, pidx;
-        jint *a, *am;
-        jlong ltx, lty;
-        jint paintOffset = 0;
-        jint pts[3];
-
-        y = rdr->_currY;
-
-        if (rdr->_texture_hasAlpha == XNI_TRUE) {
-            for (j = 0; j < height; j++, y++) {
-                pidx = paintOffset;
-
-                x = rdr->_currX;
-
-                ltx = x * rdr->_texture_m00 + y * rdr->_texture_m01 + rdr->_texture_m02;
-                lty = x * rdr->_texture_m10 + y * rdr->_texture_m11 + rdr->_texture_m12;
-
-                a = paint + pidx;
-                am = a + paintStride;
-                while (a < am) {
-                    jint tx = (jint)(ltx >> 16);
-                    jint ty = (jint)(lty >> 16);
-
-                    jint hfrac = (jint)(ltx & 0xffff);
-                    jint vfrac = (jint)(lty & 0xffff);
-
-                    jboolean inBounds =
-                        isInBounds(&tx, &ltx, txMin-1, txMax, rdr->_texture_repeat) &&
-                        isInBounds(&ty, &lty, tyMin-1, tyMax, rdr->_texture_repeat);
-
-                    if (inBounds) {
-                        jint sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
-                        jint p00 = txtData[sidx];
-                        if (rdr->_texture_interpolate) {
-                            if (rdr->_texture_repeat) {
-                                getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                    tx, txMin, txMax, ty, tyMin, tyMax);
-                            } else {
-                                getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                    tx, txMin, txMax, ty, tyMin, tyMax);
-                            }
-
-                            if (hfrac && vfrac) {
-                                cval = interpolate4points(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
-                            } else if (hfrac) {
-                                cval = interpolate2points(p00, pts[0], hfrac);
-                            } else if (vfrac) {
-                                cval = interpolate2points(p00, pts[1], vfrac);
-                            } else {
-                                cval = p00;
-                            }
-
-                            assert(pidx >= 0);
-                            assert(pidx < rdr->_paint_length);
-
-                            paint[pidx] = cval;
-                        } else {
-                            assert(pidx >= 0);
-                            assert(pidx < rdr->_paint_length);
-
-                            paint[pidx] = p00;
-                        }
-                    } else {
-                        assert(pidx >= 0);
-                        assert(pidx < rdr->_paint_length);
-
-                        paint[pidx] = 0x00000000;
-                    }
-                    
-                    ++a;
-                    ++pidx;
-
-                    ltx += rdr->_texture_m00;
-                    lty += rdr->_texture_m10;
-                } // while (a < am)b
-                paintOffset += paintStride;
-            }//for
-        }//else _texture_hasAlpha == XNI_FALSE
-        else {
-            for (j = 0; j < height; j++, y++) {
-                pidx = paintOffset;
-
-                x = rdr->_currX;
-
-                ltx = x * rdr->_texture_m00 + y * rdr->_texture_m01 + rdr->_texture_m02;
-                lty = x * rdr->_texture_m10 + y * rdr->_texture_m11 + rdr->_texture_m12;
-
-                a = paint + pidx;
-                am = a + paintStride;
-                while (a < am) {
-                    jint tx = (jint)(ltx >> 16);
-                    jint ty = (jint)(lty >> 16);
-
-                    jint hfrac = (jint)(ltx & 0xffff);
-                    jint vfrac = (jint)(lty & 0xffff);
-
-                    jboolean inBounds = 
-                        isInBounds(&tx, &ltx, txMin-1, txMax, rdr->_texture_repeat) &&
-                        isInBounds(&ty, &lty, tyMin-1, tyMax, rdr->_texture_repeat);
-
-                    if (inBounds) {
-                        jint sidx = MAX(tyMin, ty) * rdr->_texture_stride + MAX(txMin, tx);
-                        jint p00 = txtData[sidx];
-                        if (rdr->_texture_interpolate) {
-                            if (rdr->_texture_repeat) {
-                                getPointsToInterpolateRepeat(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                    tx, txMin, txMax, ty, tyMin, tyMax);
-                            } else {
-                                getPointsToInterpolate(pts, txtData, sidx, rdr->_texture_stride, p00,
-                                    tx, txMin, txMax, ty, tyMin, tyMax);
-                            }
-
-                            if (hfrac && vfrac) {
-                                cval = interpolate4pointsNoAlpha(p00, pts[0], pts[1], pts[2], hfrac, vfrac);
-                            } else if (hfrac) {
-                                cval = interpolate2pointsNoAlpha(p00, pts[0], hfrac);
-                            } else if (vfrac) {
-                                cval = interpolate2pointsNoAlpha(p00, pts[1], vfrac);
-                            } else {
-                                cval = p00;
-                            }
-
-                            assert(pidx >= 0);
-                            assert(pidx < rdr->_paint_length);
-
-                            paint[pidx] = cval;
-                        } else {
-                            assert(pidx >= 0);
-                            assert(pidx < rdr->_paint_length);
-
-                            paint[pidx] = p00;
-                        }
-                    } else {
-                        assert(pidx >= 0);
-                        assert(pidx < rdr->_paint_length);
-
-                        paint[pidx] = 0x00000000;
-                    }
-
-                    ++a;
-                    ++pidx;
-
-                    ltx += rdr->_texture_m00;
-                    lty += rdr->_texture_m10;
-                }
-                paintOffset += paintStride;
-            }
-        }
+            paintOffset += paintStride;
+        }//for
         }
         break;
     }
--- a/modules/graphics/src/test/java/com/sun/javafx/css/CursorTypeTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/test/java/com/sun/javafx/css/CursorTypeTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -25,7 +25,7 @@
 
 package com.sun.javafx.css;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 import javafx.css.ParsedValue;
 import javafx.scene.Cursor;
 import javafx.scene.text.Font;
@@ -52,4 +52,67 @@
         assertEquals(expResult, result);
     }
 
+    @Test
+    public void testConvert_with_hyphen() {
+        ParsedValue<String,Cursor> value = new ParsedValueImpl<String,Cursor>("open-hand", CursorConverter.getInstance());
+        Font font = null;
+        Cursor expResult = Cursor.OPEN_HAND;
+        Cursor result = value.convert(font);
+        assertEquals(expResult, result);
+    }
+
+    @Test
+    public void testConvert_with_Cursor_dot() {
+        ParsedValue<String,Cursor> value = new ParsedValueImpl<String,Cursor>("Cursor.open-hand", CursorConverter.getInstance());
+        Font font = null;
+        Cursor expResult = Cursor.OPEN_HAND;
+        Cursor result = value.convert(font);
+        assertEquals(expResult, result);
+    }
+
+    @Test
+    public void testConvert_with_package_name() {
+        ParsedValue<String,Cursor> value = new ParsedValueImpl<String,Cursor>("javafx.scene.Cursor.open-hand", CursorConverter.getInstance());
+        Font font = null;
+        Cursor expResult = Cursor.OPEN_HAND;
+        Cursor result = value.convert(font);
+        assertEquals(expResult, result);
+    }
+
+    @Test
+    public void testConvert_with_package_name_only() {
+        ParsedValue<String,Cursor> value = new ParsedValueImpl<String,Cursor>("javafx.scene.Cursor.", CursorConverter.getInstance());
+        Font font = null;
+        Cursor expResult = Cursor.DEFAULT;
+        Cursor result = value.convert(font);
+        assertEquals(expResult, result);
+    }
+
+    @Test
+    public void testConvert_with_empty_string() {
+        ParsedValue<String,Cursor> value = new ParsedValueImpl<String,Cursor>("", CursorConverter.getInstance());
+        Font font = null;
+        Cursor expResult = Cursor.DEFAULT;
+        Cursor result = value.convert(font);
+        assertEquals(expResult, result);
+    }
+
+    @Test
+    public void testConvert_with_null() {
+        ParsedValue<String,Cursor> value = new ParsedValueImpl<String,Cursor>(null, CursorConverter.getInstance());
+        Font font = null;
+        Cursor expResult = Cursor.DEFAULT;
+        Cursor result = value.convert(font);
+        assertEquals(expResult, result);
+    }
+
+    @Test
+    public void testConvert_with_bogus_value() {
+        ParsedValue<String,Cursor> value = new ParsedValueImpl<String,Cursor>("bogus", CursorConverter.getInstance());
+        Font font = null;
+        Cursor expResult = Cursor.DEFAULT;
+        Cursor result = value.convert(font);
+        assertEquals(expResult, result);
+    }
+
 }
--- a/modules/graphics/src/test/java/com/sun/javafx/css/FontTypeTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/test/java/com/sun/javafx/css/FontTypeTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -261,5 +261,23 @@
 
     }
 
+    @Test public void testRT_29773() {
 
+        Text txt = new Text("testRT_29773");
+        txt.setId("test-rt-29773");
+
+        Group g = new Group();
+
+        Scene scene  = new Scene(g);
+        scene.getStylesheets().add(FontTypeTest.class.getResource("HonorDeveloperSettingsTest_AUTHOR.css").toExternalForm());
+        g.getChildren().add(txt);
+
+        g.impl_processCSS(true);
+
+        Font f = txt.getFont();
+        // should get size and amble from .root, 'italic' from #test-rt-32551, bold from inline.
+        assertEquals("Amble Condensed", f.getName());
+        assertEquals(20, f.getSize(),0);
+
+    }
 }
--- a/modules/graphics/src/test/java/com/sun/javafx/sg/prism/TestGraphics.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/test/java/com/sun/javafx/sg/prism/TestGraphics.java	Tue Sep 10 14:12:43 2013 -0700
@@ -251,6 +251,12 @@
         @Override public PhongMaterial createPhongMaterial() { return null; }
         @Override public MeshView createMeshView(Mesh mesh) { return null; }
         @Override public Mesh createMesh() { return null; }
+        @Override public void setRegionTexture(Texture texture) { }
+        @Override public Texture getRegionTexture() { return null; }
+        @Override public void setGlyphTexture(Texture texture) { }
+        @Override public Texture getGlyphTexture() { return null; }
+        @Override public boolean isSuperShaderAllowed() {return false; }
+
     }
 
     private static class TestRenderTarget implements RenderTarget {
--- a/modules/graphics/src/test/java/com/sun/javafx/test/TransformHelper.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/test/java/com/sun/javafx/test/TransformHelper.java	Tue Sep 10 14:12:43 2013 -0700
@@ -69,7 +69,7 @@
     /**
      * Asserts the {@code matrix} equals to the specified expected values
      */
-    public static void assertMatrix(Affine3D matrix,
+    public static void assertMatrix(BaseTransform matrix,
             double mxx, double mxy, double mxz, double tx,
             double myx, double myy, double myz, double ty,
             double mzx, double mzy, double mzz, double tz) {
@@ -247,6 +247,41 @@
                 rzx, rzy, rzz, rzt);
     }
 
+    /**
+     * Concatenates the two transforms.
+     */
+    public static Transform concatenate(BaseTransform t1, Transform t2) {
+
+        final double txx = t2.getMxx();
+        final double txy = t2.getMxy();
+        final double txz = t2.getMxz();
+        final double ttx = t2.getTx();
+        final double tyx = t2.getMyx();
+        final double tyy = t2.getMyy();
+        final double tyz = t2.getMyz();
+        final double tty = t2.getTy();
+        final double tzx = t2.getMzx();
+        final double tzy = t2.getMzy();
+        final double tzz = t2.getMzz();
+        final double ttz = t2.getTz();
+        final double rxx = (t1.getMxx() * txx + t1.getMxy() * tyx + t1.getMxz() * tzx /* + getMxt * 0.0 */);
+        final double rxy = (t1.getMxx() * txy + t1.getMxy() * tyy + t1.getMxz() * tzy /* + getMxt * 0.0 */);
+        final double rxz = (t1.getMxx() * txz + t1.getMxy() * tyz + t1.getMxz() * tzz /* + getMxt * 0.0 */);
+        final double rxt = (t1.getMxx() * ttx + t1.getMxy() * tty + t1.getMxz() * ttz + t1.getMxt() /* * 1.0 */);
+        final double ryx = (t1.getMyx() * txx + t1.getMyy() * tyx + t1.getMyz() * tzx /* + getMyt * 0.0 */);
+        final double ryy = (t1.getMyx() * txy + t1.getMyy() * tyy + t1.getMyz() * tzy /* + getMyt * 0.0 */);
+        final double ryz = (t1.getMyx() * txz + t1.getMyy() * tyz + t1.getMyz() * tzz /* + getMyt * 0.0 */);
+        final double ryt = (t1.getMyx() * ttx + t1.getMyy() * tty + t1.getMyz() * ttz + t1.getMyt() /* * 1.0 */);
+        final double rzx = (t1.getMzx() * txx + t1.getMzy() * tyx + t1.getMzz() * tzx /* + getMzt * 0.0 */);
+        final double rzy = (t1.getMzx() * txy + t1.getMzy() * tyy + t1.getMzz() * tzy /* + getMzt * 0.0 */);
+        final double rzz = (t1.getMzx() * txz + t1.getMzy() * tyz + t1.getMzz() * tzz /* + getMzt * 0.0 */);
+        final double rzt = (t1.getMzx() * ttx + t1.getMzy() * tty + t1.getMzz() * ttz + t1.getMzt() /* * 1.0 */);
+
+        return TransformUtils.immutableTransform(
+                rxx, rxy, rxz, rxt,
+                ryx, ryy, ryz, ryt,
+                rzx, rzy, rzz, rzt);
+    }
 
     /**
      * Computes determinant of the specified transform.
@@ -719,5 +754,13 @@
                     getMyx(), getMyy(), getMyz(), getTy(),
                     getMzx(), getMzy(), getMzz(), getTz());
         }
+
+        @Override
+        public BaseTransform impl_derive(BaseTransform t) {
+            return t.deriveWithConcatenation(
+                    getMxx(), getMxy(), getMxz(), getTx(),
+                    getMyx(), getMyy(), getMyz(), getTy(),
+                    getMzx(), getMzy(), getMzz(), getTz());
+        }
     }
 }
--- a/modules/graphics/src/test/java/javafx/scene/MouseTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/test/java/javafx/scene/MouseTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -1465,9 +1465,61 @@
         assertTrue(s.smallSquareTracker.exitedMe);
     }
 
+    @Test
+    public void pdrGestureShouldHandleDraggedNodeRemoval() {
+        final SimpleTestScene s = new SimpleTestScene();
+
+        s.processEvent(MouseEventGenerator.generateMouseEvent(
+                MouseEvent.MOUSE_MOVED, 250, 250));
+        assertTrue(s.smallSquareTracker.node.isHover());
+        assertFalse(s.smallSquareTracker.node.isPressed());
+
+        s.processEvent(MouseEventGenerator.generateMouseEvent(
+                MouseEvent.MOUSE_PRESSED, 250, 250));
+        assertTrue(s.smallSquareTracker.node.isHover());
+        assertTrue(s.smallSquareTracker.node.isPressed());
+        assertTrue(s.smallSquareTracker.wasPressed());
+        assertTrue(s.groupTracker.wasPressed());
+
+        s.processEvent(MouseEventGenerator.generateMouseEvent(
+                MouseEvent.MOUSE_DRAGGED, 255, 255));
+        assertTrue(s.smallSquareTracker.node.isHover());
+        assertTrue(s.smallSquareTracker.node.isPressed());
+        assertTrue(s.smallSquareTracker.wasDragged());
+        assertTrue(s.groupTracker.wasDragged());
+
+        s.smallSquareTracker.clear();
+        s.groupTracker.clear();
+        s.rootTracker.clear();
+
+        s.scene.getRoot().getChildren().clear();
+        assertFalse(s.smallSquareTracker.node.isHover());
+        assertFalse(s.smallSquareTracker.node.isPressed());
+        assertFalse(s.groupTracker.node.isHover());
+        assertFalse(s.groupTracker.node.isPressed());
+        assertTrue(s.rootTracker.node.isHover());
+        assertTrue(s.rootTracker.node.isPressed());
+        assertTrue(s.smallSquareTracker.wasExitedMe());
+        assertTrue(s.groupTracker.wasExitedMe());
+        assertFalse(s.rootTracker.wasExitedMe());
+
+        s.processEvent(MouseEventGenerator.generateMouseEvent(
+                MouseEvent.MOUSE_DRAGGED, 260, 260));
+        assertFalse(s.smallSquareTracker.wasDragged());
+        assertFalse(s.groupTracker.wasDragged());
+        assertTrue(s.rootTracker.wasDragged());
+
+        s.processEvent(MouseEventGenerator.generateMouseEvent(
+                MouseEvent.MOUSE_RELEASED, 270, 270));
+        assertFalse(s.smallSquareTracker.wasReleased());
+        assertFalse(s.groupTracker.wasReleased());
+        assertTrue(s.rootTracker.wasReleased());
+    }
+
     private static class SimpleTestScene {
 
         MouseEventTracker sceneTracker;
+        MouseEventTracker rootTracker;
         MouseEventTracker groupTracker;
         MouseEventTracker bigSquareTracker;
         MouseEventTracker smallSquareTracker;
@@ -1499,6 +1551,7 @@
             root.getChildren().add(group);
 
             sceneTracker = new MouseEventTracker(scene);
+            rootTracker = new MouseEventTracker(root);
             groupTracker = new MouseEventTracker(group);
             bigSquareTracker = new MouseEventTracker(bigSquare);
             smallSquareTracker = new MouseEventTracker(smallSquare);
--- a/modules/graphics/src/test/java/javafx/scene/NodeTest.java	Fri Sep 06 13:22:16 2013 -0700
+++ b/modules/graphics/src/test/java/javafx/scene/NodeTest.java	Tue Sep 10 14:12:43 2013 -0700
@@ -27,7 +27,10 @@
 
 import com.sun.javafx.geom.BoxBounds;
 import com.sun.javafx.geom.PickRay;
+import com.sun.javafx.geom.transform.Affine2D;
+import com.sun.javafx.geom.transform.Affine3D;
 import com.sun.javafx.geom.transform.BaseTransform;
+import com.sun.javafx.geom.transform.Translate2D;
 import com.sun.javafx.pgstub.StubToolkit;
 import com.sun.javafx.scene.DirtyBits;
 import com.sun.javafx.scene.input.PickResultChooser;
@@ -55,9 +58,14 @@
 import java.lang.reflect.Method;
 import java.util.Comparator;
 import javafx.scene.layout.AnchorPane;
+import javafx.scene.transform.Affine;
+import javafx.scene.transform.Scale;
+import javafx.scene.transform.Shear;
+import javafx.scene.transform.Translate;
 import javafx.stage.Stage;
 
 import static org.junit.Assert.*;
+import org.junit.Ignore;
 /**
  * Tests various aspects of Node.
  *
@@ -1360,7 +1368,7 @@
 
         final Rectangle clip = new Rectangle(100, 100) {
             @Override protected NGNode impl_createPeer() {
-                return new MockClip();
+                return new MockNGRect();
             }
         };
         circle.setClip(clip);
@@ -1378,15 +1386,261 @@
 
         ((StubToolkit) Toolkit.getToolkit()).firePulse();
 
-        assertEquals(300, ((MockClip) clip.impl_getPeer()).w, 1e-10);
+        assertEquals(300, ((MockNGRect) clip.impl_getPeer()).w, 1e-10);
     }
 
-    private class MockClip extends NGRectangle {
+    @Test
+    public void untransformedNodeShouldSyncIdentityTransform() {
+        final Node node = createTestRect();
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(BaseTransform.IDENTITY_TRANSFORM,
+                ((MockNGRect) node.impl_getPeer()).t);
+    }
+
+    @Test
+    public void nodeTransfomedByIdentitiesShouldSyncIdentityTransform() {
+        final Node node = createTestRect();
+        node.setRotationAxis(Rotate.X_AXIS);
+        node.getTransforms().add(new Translate());
+        node.getTransforms().add(new Scale());
+        node.getTransforms().add(new Affine());
+        node.getTransforms().add(new Rotate(0, Rotate.Y_AXIS));
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(BaseTransform.IDENTITY_TRANSFORM,
+                ((MockNGRect) node.impl_getPeer()).t);
+    }
+
+    @Test
+    public void translatedNodeShouldSyncTranslateTransform1() {
+        final Node node = createTestRect();
+        node.setTranslateX(30);
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Translate2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }
+
+    @Test
+    public void translatedNodeShouldSyncTranslateTransform2() {
+        final Node node = createTestRect();
+        node.getTransforms().add(new Translate(20, 10));
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Translate2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }
+
+    @Test
+    public void multitranslatedNodeShouldSyncTranslateTransform() {
+        final Node node = createTestRect();
+        node.setTranslateX(30);
+        node.getTransforms().add(new Translate(20, 10));
+        node.getTransforms().add(new Translate(10, 20));
+        node.getTransforms().add(new Translate(5, 5, 0));
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Translate2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }
+
+    @Test
+    public void mirroringShouldSyncAffine2DTransform() {
+        final Node node = createTestRect();
+        node.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Affine2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }
+
+    @Test
+    public void rotatedNodeShouldSyncAffine2DTransform1() {
+        final Node node = createTestRect();
+        node.setRotate(20);
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Affine2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }
+
+    @Test
+    public void rotatedNodeShouldSyncAffine2DTransform2() {
+        final Node node = createTestRect();
+        node.getTransforms().add(new Rotate(20));
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Affine2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }
+
+    @Test
+    public void multiRotatedNodeShouldSyncAffine2DTransform() {
+        final Node node = createTestRect();
+        node.setRotate(20);
+        node.getTransforms().add(new Rotate(20));
+        node.getTransforms().add(new Rotate(0, Rotate.X_AXIS));
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Affine2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }
+
+    @Test
+    public void scaledNodeShouldSyncAffine2DTransform1() {
+        final Node node = createTestRect();
+        node.setScaleX(2);
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Affine2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }
+
+    @Test
+    public void scaledNodeShouldSyncAffine2DTransform2() {
+        final Node node = createTestRect();
+        node.getTransforms().add(new Scale(2, 1));
+        ((StubToolkit) Toolkit.getToolkit()).firePulse();
+        assertSame(Affine2D.class,
+                ((MockNGRect) node.impl_getPeer()).t.getClass());
+    }