changeset 4750:c218ee2b9ac2

Automated merge with ssh://jfxsrc.us.oracle.com//javafx/8.0/MASTER/jfx/rt
author jgodinez
date Tue, 20 Aug 2013 09:38:00 -0700
parents e4257e8a68fe 473856d8d530
children 61b8d7420fc9
files modules/graphics/src/main/native-glass/lens/cursor/fbCursor/fbCursor.h modules/graphics/src/main/native-glass/lens/cursor/fbCursor/fbDispman.c modules/graphics/src/main/native-glass/lens/cursor/fbCursor/wrapped_bcm.c modules/web/src/main/native/Source/WebCore/platform/java/javalibs.pl
diffstat 125 files changed, 17821 insertions(+), 2119 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Aug 20 08:59:55 2013 -0400
+++ b/.hgignore	Tue Aug 20 09:38:00 2013 -0700
@@ -26,5 +26,3 @@
 */Debug/*
 *~
 modules/web/src/main/native/LayoutTests
-modules/web/src/main/native/WebKitBuild
-modules/web/src/main/native/WebKitLibraries/import
--- a/apps/samples/Ensemble8/src/app/java/ensemble/EnsembleApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/EnsembleApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -96,10 +96,6 @@
         System.out.println("IS_IOS = " + IS_IOS);
         System.out.println("IS_EMBEDDED = " + IS_EMBEDDED);
         System.out.println("IS_DESKTOP = " + IS_DESKTOP);
-        System.setProperty("http.proxyHost", "www-proxy.us.oracle.com");
-        System.setProperty("http.proxyPort", "80");
-        System.setProperty("https.proxyHost", "www-proxy.us.oracle.com");
-        System.setProperty("https.proxyPort", "80");
     }
 
     @Override public void init() throws Exception {
--- a/apps/samples/Ensemble8/src/generated/java/ensemble/generated/Samples.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/generated/java/ensemble/generated/Samples.java	Tue Aug 20 09:38:00 2013 -0700
@@ -7,16 +7,16 @@
     private static final SampleInfo SAMPLE_0 = new SampleInfo("Interpolator","A sample that shows various types of interpolation between key frames in a timeline. There are five circles, each animated with a different interpolation method. The Linear interpolator is the default. Use the controls to reduce opacity to zero for some circles to compare with others, or change circle color to distinguish between individual interpolators. ","/Animation/Interpolator","/ensemble/samples/animation/interpolator","ensemble.samples.animation.interpolator.InterpolatorApp","/ensemble/samples/animation/interpolator/preview.png",new String[]{"/ensemble/samples/animation/interpolator/InterpolatorApp.java",},new String[]{"javafx.animation.Interpolator","javafx.animation.KeyFrame","javafx.animation.KeyValue","javafx.animation.Timeline","javafx.util.Duration",},new String[]{},new String[]{},"/ensemble/samples/animation/interpolator/InterpolatorApp.java",new PlaygroundProperty[]{new PlaygroundProperty(null,"-","name","LINEAR"),new PlaygroundProperty("circle1","opacity","min","0","max","1"),new PlaygroundProperty("circle1","fill"),new PlaygroundProperty(null,"-","name","EASE_BOTH"),new PlaygroundProperty("circle2","opacity","min","0","max","1"),new PlaygroundProperty("circle2","fill"),new PlaygroundProperty(null,"-","name","EASE_IN"),new PlaygroundProperty("circle3","opacity","min","0","max","1"),new PlaygroundProperty("circle3","fill"),new PlaygroundProperty(null,"-","name","EASE_OUT"),new PlaygroundProperty("circle4","opacity","min","0","max","1"),new PlaygroundProperty("circle4","fill"),new PlaygroundProperty(null,"-","name","SPLINE"),new PlaygroundProperty("circle5","opacity","min","0","max","1"),new PlaygroundProperty("circle5","fill"),},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_1 = new SampleInfo("Timeline","A sample that demonstrates the basics of timeline creation. ","/Animation/Timeline/Timeline","/ensemble/samples/animation/timeline/timeline","ensemble.samples.animation.timeline.timeline.TimelineApp","/ensemble/samples/animation/timeline/timeline/preview.png",new String[]{"/ensemble/samples/animation/timeline/timeline/TimelineApp.java",},new String[]{"javafx.animation.KeyFrame","javafx.animation.KeyValue","javafx.animation.Timeline","javafx.util.Duration",},new String[]{},new String[]{},"/ensemble/samples/animation/timeline/timeline/TimelineApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_2 = new SampleInfo("Timeline Events","A sample that demonstrates events triggered during time line play. The circle changes its radius in a linear fashion during each key frame and randomly jumps to a new location along the x coordinate at the end of the key frame. ","/Animation/Timeline/Timeline Events","/ensemble/samples/animation/timeline/timelineevents","ensemble.samples.animation.timeline.timelineevents.TimelineEventsApp","/ensemble/samples/animation/timeline/timelineevents/preview.png",new String[]{"/ensemble/samples/animation/timeline/timelineevents/TimelineEventsApp.java",},new String[]{"javafx.animation.KeyFrame","javafx.animation.KeyValue","javafx.animation.Timeline","javafx.util.Duration","javafx.event.ActionEvent","javafx.event.EventHandler",},new String[]{},new String[]{},"/ensemble/samples/animation/timeline/timelineevents/TimelineEventsApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_3 = new SampleInfo("Fade Transition","A sample in which the opacity of a node changes over a given time. ","/Animation/Transitions/Fade Transition","/ensemble/samples/animation/transitions/fadetransition","ensemble.samples.animation.transitions.fadetransition.FadeTransitionApp","/ensemble/samples/animation/transitions/fadetransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/fadetransition/FadeTransitionApp.java",},new String[]{"javafx.animation.FadeTransition","javafx.animation.FadeTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/fadetransition/FadeTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_4 = new SampleInfo("Fill Transition","A sample in which the filling of a shape changes over a given time. ","/Animation/Transitions/Fill Transition","/ensemble/samples/animation/transitions/filltransition","ensemble.samples.animation.transitions.filltransition.FillTransitionApp","/ensemble/samples/animation/transitions/filltransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/filltransition/FillTransitionApp.java",},new String[]{"javafx.animation.FillTransition","javafx.animation.FillTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/filltransition/FillTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_5 = new SampleInfo("Parallel Transition","A sample in which various transitions are executed in parallel. ","/Animation/Transitions/Parallel Transition","/ensemble/samples/animation/transitions/paralleltransition","ensemble.samples.animation.transitions.paralleltransition.ParallelTransitionApp","/ensemble/samples/animation/transitions/paralleltransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/paralleltransition/ParallelTransitionApp.java",},new String[]{"javafx.animation.ParallelTransition","javafx.animation.ParallelTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/paralleltransition/ParallelTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_6 = new SampleInfo("Path Transition","A sample in which a node moves along a path from end to end over a given time. ","/Animation/Transitions/Path Transition","/ensemble/samples/animation/transitions/pathtransition","ensemble.samples.animation.transitions.pathtransition.PathTransitionApp","/ensemble/samples/animation/transitions/pathtransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/pathtransition/PathTransitionApp.java",},new String[]{"javafx.animation.PathTransition","javafx.animation.PathTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/pathtransition/PathTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_7 = new SampleInfo("Pause Transition","A sample in which a node pauses over a given time. ","/Animation/Transitions/Pause Transition","/ensemble/samples/animation/transitions/pausetransition","ensemble.samples.animation.transitions.pausetransition.PauseTransitionApp","/ensemble/samples/animation/transitions/pausetransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/pausetransition/PauseTransitionApp.java",},new String[]{"javafx.animation.PauseTransition","javafx.animation.PauseTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/pausetransition/PauseTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_8 = new SampleInfo("Rotate Transition","A sample in which a node rotates around its center over a given time. ","/Animation/Transitions/Rotate Transition","/ensemble/samples/animation/transitions/rotatetransition","ensemble.samples.animation.transitions.rotatetransition.RotateTransitionApp","/ensemble/samples/animation/transitions/rotatetransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/rotatetransition/RotateTransitionApp.java",},new String[]{"javafx.animation.RotateTransition","javafx.animation.RotateTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/rotatetransition/RotateTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_9 = new SampleInfo("Scale Transition","A sample in which a node scales larger and smaller over a given time. ","/Animation/Transitions/Scale Transition","/ensemble/samples/animation/transitions/scaletransition","ensemble.samples.animation.transitions.scaletransition.ScaleTransitionApp","/ensemble/samples/animation/transitions/scaletransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/scaletransition/ScaleTransitionApp.java",},new String[]{"javafx.animation.ScaleTransition","javafx.animation.ScaleTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Aimation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/scaletransition/ScaleTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_3 = new SampleInfo("Fade Transition","A sample in which the opacity of a node changes over a given time. ","/Animation/Transitions/Fade Transition","/ensemble/samples/animation/transitions/fadetransition","ensemble.samples.animation.transitions.fadetransition.FadeTransitionApp","/ensemble/samples/animation/transitions/fadetransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/fadetransition/FadeTransitionApp.java",},new String[]{"javafx.animation.FadeTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/fadetransition/FadeTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_4 = new SampleInfo("Fill Transition","A sample in which the filling of a shape changes over a given time. ","/Animation/Transitions/Fill Transition","/ensemble/samples/animation/transitions/filltransition","ensemble.samples.animation.transitions.filltransition.FillTransitionApp","/ensemble/samples/animation/transitions/filltransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/filltransition/FillTransitionApp.java",},new String[]{"javafx.animation.FillTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/filltransition/FillTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_5 = new SampleInfo("Parallel Transition","A sample in which various transitions are executed in parallel. ","/Animation/Transitions/Parallel Transition","/ensemble/samples/animation/transitions/paralleltransition","ensemble.samples.animation.transitions.paralleltransition.ParallelTransitionApp","/ensemble/samples/animation/transitions/paralleltransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/paralleltransition/ParallelTransitionApp.java",},new String[]{"javafx.animation.ParallelTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/paralleltransition/ParallelTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_6 = new SampleInfo("Path Transition","A sample in which a node moves along a path from end to end over a given time. ","/Animation/Transitions/Path Transition","/ensemble/samples/animation/transitions/pathtransition","ensemble.samples.animation.transitions.pathtransition.PathTransitionApp","/ensemble/samples/animation/transitions/pathtransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/pathtransition/PathTransitionApp.java",},new String[]{"javafx.animation.PathTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/pathtransition/PathTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_7 = new SampleInfo("Pause Transition","A sample in which a node pauses over a given time. ","/Animation/Transitions/Pause Transition","/ensemble/samples/animation/transitions/pausetransition","ensemble.samples.animation.transitions.pausetransition.PauseTransitionApp","/ensemble/samples/animation/transitions/pausetransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/pausetransition/PauseTransitionApp.java",},new String[]{"javafx.animation.PauseTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/pausetransition/PauseTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_8 = new SampleInfo("Rotate Transition","A sample in which a node rotates around its center over a given time. ","/Animation/Transitions/Rotate Transition","/ensemble/samples/animation/transitions/rotatetransition","ensemble.samples.animation.transitions.rotatetransition.RotateTransitionApp","/ensemble/samples/animation/transitions/rotatetransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/rotatetransition/RotateTransitionApp.java",},new String[]{"javafx.animation.RotateTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/rotatetransition/RotateTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_9 = new SampleInfo("Scale Transition","A sample in which a node scales larger and smaller over a given time. ","/Animation/Transitions/Scale Transition","/ensemble/samples/animation/transitions/scaletransition","ensemble.samples.animation.transitions.scaletransition.ScaleTransitionApp","/ensemble/samples/animation/transitions/scaletransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/scaletransition/ScaleTransitionApp.java","/ensemble/samples/animation/transitions/scaletransition/ScaleTransitionApp.java.orig","/ensemble/samples/animation/transitions/scaletransition/ScaleTransitionApp.java.typoFixed",},new String[]{"javafx.animation.ScaleTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/scaletransition/ScaleTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_10 = new SampleInfo("Sequential Transition","A sample in which various transitions are executed sequentially. ","/Animation/Transitions/Sequential Transition","/ensemble/samples/animation/transitions/sequentialtransition","ensemble.samples.animation.transitions.sequentialtransition.SequentialTransitionApp","/ensemble/samples/animation/transitions/sequentialtransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/sequentialtransition/SequentialTransitionApp.java",},new String[]{"javafx.animation.SequentialTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Stroke Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/sequentialtransition/SequentialTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_11 = new SampleInfo("Stroke Transition","A sample in which the stroke color of a shape changes over a given time. ","/Animation/Transitions/Stroke Transition","/ensemble/samples/animation/transitions/stroketransition","ensemble.samples.animation.transitions.stroketransition.StrokeTransitionApp","/ensemble/samples/animation/transitions/stroketransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/stroketransition/StrokeTransitionApp.java",},new String[]{"javafx.animation.StrokeTransition","javafx.animation.StrokeTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/stroketransition/StrokeTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_12 = new SampleInfo("Translate Transition","A sample in which a node moves from one location to another over a given time. ","/Animation/Transitions/Translate Transition","/ensemble/samples/animation/transitions/translatetransition","ensemble.samples.animation.transitions.translatetransition.TranslateTransitionApp","/ensemble/samples/animation/transitions/translatetransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/translatetransition/TranslateTransitionApp.java",},new String[]{"javafx.animation.TranslateTransition","javafx.animation.TranslateTransitionBuilder","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition",},"/ensemble/samples/animation/transitions/translatetransition/TranslateTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_11 = new SampleInfo("Stroke Transition","A sample in which the stroke color of a shape changes over a given time. ","/Animation/Transitions/Stroke Transition","/ensemble/samples/animation/transitions/stroketransition","ensemble.samples.animation.transitions.stroketransition.StrokeTransitionApp","/ensemble/samples/animation/transitions/stroketransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/stroketransition/StrokeTransitionApp.java",},new String[]{"javafx.animation.StrokeTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Translate Transition",},"/ensemble/samples/animation/transitions/stroketransition/StrokeTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_12 = new SampleInfo("Translate Transition","A sample in which a node moves from one location to another over a given time. ","/Animation/Transitions/Translate Transition","/ensemble/samples/animation/transitions/translatetransition","ensemble.samples.animation.transitions.translatetransition.TranslateTransitionApp","/ensemble/samples/animation/transitions/translatetransition/preview.png",new String[]{"/ensemble/samples/animation/transitions/translatetransition/TranslateTransitionApp.java",},new String[]{"javafx.animation.TranslateTransition","javafx.animation.Transition",},new String[]{},new String[]{"/Animation/Transitions/Fade Transition","/Animation/Transitions/Fill Transition","/Animation/Transitions/Parallel Transition","/Animation/Transitions/Path Transition","/Animation/Transitions/Pause Transition","/Animation/Transitions/Rotate Transition","/Animation/Transitions/Scale Transition","/Animation/Transitions/Sequential Transition","/Animation/Transitions/Stroke Transition",},"/ensemble/samples/animation/transitions/translatetransition/TranslateTransitionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_13 = new SampleInfo("Fireworks","A sample that demonstrates how to draw and paint shapes, apply visual effects, blend colors in overlapping objects, and animate objects. ","/Canvas/Fireworks","/ensemble/samples/canvas/fireworks","ensemble.samples.canvas.fireworks.FireworksApp","/ensemble/samples/canvas/fireworks/preview.png",new String[]{"/ensemble/samples/canvas/fireworks/FireworksApp.java","/ensemble/samples/canvas/fireworks/Particle.java","/ensemble/samples/shared-resources/sf.jpg","/ensemble/samples/canvas/fireworks/SanFranciscoFireworks.java",},new String[]{"javafx.scene.canvas.Canvas","javafx.scene.canvas.GraphicsContext","javafx.scene.effect.BlendMode","javafx.scene.effect.BoxBlur","javafx.scene.shape.Circle","javafx.scene.Group","javafx.scene.paint.LinearGradient","javafx.animation.Timeline",},new String[]{},new String[]{},"/ensemble/samples/canvas/fireworks/FireworksApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_14 = new SampleInfo("Audio Area Chart","An area chart that shows audio spectrum of a music file being played. ","/Charts/Area/Audio Area Chart","/ensemble/samples/charts/area/audio","ensemble.samples.charts.area.audio.AudioAreaChartApp","/ensemble/samples/charts/area/audio/preview.png",new String[]{"/ensemble/samples/charts/area/audio/AudioAreaChartApp.java","/ensemble/samples/charts/area/audio/AudioAreaChart.css",},new String[]{"javafx.scene.chart.AreaChart","javafx.scene.chart.Chart","javafx.scene.chart.NumberAxis","javafx.scene.chart.XYChart","javafx.scene.media.AudioSpectrumListener","javafx.scene.media.Media","javafx.scene.media.MediaPlayer",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{},"/ensemble/samples/charts/area/audio/AudioAreaChartApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_15 = new SampleInfo("Area Chart","A chart that fills in the area between a line of data points and the axes. Good for comparing accumulated totals over time. ","/Charts/Area/Area Chart","/ensemble/samples/charts/area/chart","ensemble.samples.charts.area.chart.AreaChartApp","/ensemble/samples/charts/area/chart/preview.png",new String[]{"/ensemble/samples/charts/area/chart/AreaChartApp.java",},new String[]{"javafx.scene.chart.AreaChart","javafx.scene.chart.NumberAxis",},new String[]{"http://docs.oracle.com/javafx/2/charts/jfxpub-charts.htm","Using JavaFX Charts Tutorial",},new String[]{"/Charts/Line/Line Chart","/Charts/Scatter/Scatter Chart",},"/ensemble/samples/charts/area/chart/AreaChartApp.java",new PlaygroundProperty[]{new PlaygroundProperty("chart","data"),new PlaygroundProperty(null,"-","name","xAxis"),new PlaygroundProperty("xAxis","autoRanging"),new PlaygroundProperty("xAxis","forceZeroInRange"),new PlaygroundProperty("xAxis","lowerBound","min","-10","max","10","step","1"),new PlaygroundProperty("xAxis","upperBound","min","-10","max","10","step","1"),new PlaygroundProperty("xAxis","tickUnit","max","10","step","0.5"),new PlaygroundProperty("xAxis","minorTickCount","max","16"),new PlaygroundProperty("xAxis","minorTickLength","max","15"),new PlaygroundProperty("xAxis","minorTickVisible"),new PlaygroundProperty("xAxis","animated"),new PlaygroundProperty("xAxis","label"),new PlaygroundProperty("xAxis","side"),new PlaygroundProperty("xAxis","tickLabelFill"),new PlaygroundProperty("xAxis","tickLabelGap"),new PlaygroundProperty("xAxis","tickLabelRotation","min","-180","max","180","step","1"),new PlaygroundProperty("xAxis","tickLabelsVisible"),new PlaygroundProperty("xAxis","tickLength"),new PlaygroundProperty("xAxis","tickMarkVisible"),new PlaygroundProperty(null,"-","name","yAxis"),new PlaygroundProperty("yAxis","autoRanging"),new PlaygroundProperty("yAxis","forceZeroInRange"),new PlaygroundProperty("yAxis","lowerBound","min","-10","max","10","step","1"),new PlaygroundProperty("yAxis","upperBound","min","-10","max","10","step","1"),new PlaygroundProperty("yAxis","tickUnit","max","10","step","1"),new PlaygroundProperty("yAxis","minorTickCount","max","16"),new PlaygroundProperty("yAxis","minorTickLength","max","15"),new PlaygroundProperty("yAxis","minorTickVisible"),new PlaygroundProperty("yAxis","animated"),new PlaygroundProperty("yAxis","label"),new PlaygroundProperty("yAxis","side"),new PlaygroundProperty("yAxis","tickLabelFill"),new PlaygroundProperty("yAxis","tickLabelGap"),new PlaygroundProperty("yAxis","tickLabelRotation","min","-180","max","180"),new PlaygroundProperty("yAxis","tickLabelsVisible"),new PlaygroundProperty("yAxis","tickLength"),new PlaygroundProperty("yAxis","tickMarkVisible"),new PlaygroundProperty(null,"-","name","chart"),new PlaygroundProperty("chart","alternativeColumnFillVisible"),new PlaygroundProperty("chart","alternativeRowFillVisible"),new PlaygroundProperty("chart","horizontalGridLinesVisible"),new PlaygroundProperty("chart","horizontalZeroLineVisible"),new PlaygroundProperty("chart","verticalGridLinesVisible"),new PlaygroundProperty("chart","verticalZeroLineVisible"),new PlaygroundProperty("chart","animated"),new PlaygroundProperty("chart","legendSide"),new PlaygroundProperty("chart","legendVisible"),new PlaygroundProperty("chart","title"),new PlaygroundProperty("chart","titleSide"),},new ConditionalFeature[]{});
@@ -43,7 +43,7 @@
     private static final SampleInfo SAMPLE_36 = new SampleInfo("ChoiceBox","An example of a ChoiceBox with several options. The ChoiceBox control displays a default or current selection, with an icon to click that expands the list for a selection. ","/Controls/ChoiceBox","/ensemble/samples/controls/choicebox","ensemble.samples.controls.choicebox.ChoiceBoxApp","/ensemble/samples/controls/choicebox/preview.png",new String[]{"/ensemble/samples/controls/choicebox/ChoiceBoxApp.java",},new String[]{"javafx.scene.control.ChoiceBox",},new String[]{},new String[]{},"/ensemble/samples/controls/choicebox/ChoiceBoxApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_37 = new SampleInfo("ColorPicker","A sample that demonstrates the ColorPicker. ","/Controls/ColorPicker","/ensemble/samples/controls/colorpicker","ensemble.samples.controls.colorpicker.ColorPickerApp","/ensemble/samples/controls/colorpicker/preview.png",new String[]{"/ensemble/samples/controls/colorpicker/ColorPickerApp.java",},new String[]{"javafx.scene.control.ColorPicker",},new String[]{},new String[]{},"/ensemble/samples/controls/colorpicker/ColorPickerApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_38 = new SampleInfo("HyperLink","A sample that shows a simple hyperlink and a hyperlink with an image. ","/Controls/HyperLink","/ensemble/samples/controls/hyperlink","ensemble.samples.controls.hyperlink.HyperLinkApp","/ensemble/samples/controls/hyperlink/preview.png",new String[]{"/ensemble/samples/shared-resources/icon-48x48.png","/ensemble/samples/controls/hyperlink/HyperLinkApp.java",},new String[]{"javafx.scene.control.Hyperlink",},new String[]{},new String[]{},"/ensemble/samples/controls/hyperlink/HyperLinkApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_39 = new SampleInfo("Menu","An example of a menu bar. The example includes use of the system bar, if the current platform supports a system bar. ","/Controls/Menu","/ensemble/samples/controls/menu","ensemble.samples.controls.menu.MenuApp","/ensemble/samples/controls/menu/preview.png",new String[]{"/ensemble/samples/shared-resources/menuInfo.png","/ensemble/samples/controls/menu/MenuApp.java",},new String[]{"javafx.scene.control.MenuBar","javafx.scene.control.Menu","javafx.scene.control.MenuItem",},new String[]{},new String[]{},"/ensemble/samples/controls/menu/MenuApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_39 = new SampleInfo("Menu","An example of a menu bar. The example includes use of the system bar, if the current platform supports a system bar. ","/Controls/Menu","/ensemble/samples/controls/menu","ensemble.samples.controls.menu.MenuApp","/ensemble/samples/controls/menu/preview.png",new String[]{"/ensemble/samples/shared-resources/menuInfo.png","/ensemble/samples/controls/menu/MenuApp.java","/ensemble/samples/controls/menu/MenuApp.java.orig",},new String[]{"javafx.scene.control.MenuBar","javafx.scene.control.Menu","javafx.scene.control.MenuItem",},new String[]{},new String[]{},"/ensemble/samples/controls/menu/MenuApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_40 = new SampleInfo("Pagination","A sample that demonstrates pagination. ","/Controls/Pagination","/ensemble/samples/controls/pagination","ensemble.samples.controls.pagination.PaginationApp","/ensemble/samples/controls/pagination/preview.png",new String[]{"/ensemble/samples/shared-resources/Animal1.jpg","/ensemble/samples/shared-resources/Animal2.jpg","/ensemble/samples/shared-resources/Animal3.jpg","/ensemble/samples/shared-resources/Animal4.jpg","/ensemble/samples/shared-resources/Animal5.jpg","/ensemble/samples/shared-resources/Animal6.jpg","/ensemble/samples/shared-resources/Animal7.jpg","/ensemble/samples/controls/pagination/PaginationApp.java",},new String[]{"javafx.scene.control.Pagination",},new String[]{},new String[]{},"/ensemble/samples/controls/pagination/PaginationApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_41 = new SampleInfo("Progress Bar","A sample that demonstrates the ProgressBar control. ","/Controls/Progress Bar","/ensemble/samples/controls/progressbar","ensemble.samples.controls.progressbar.ProgressBarApp","/ensemble/samples/controls/progressbar/preview.png",new String[]{"/ensemble/samples/controls/progressbar/ProgressBarApp.java",},new String[]{"javafx.scene.control.ProgressBar",},new String[]{},new String[]{"/Controls/Progress Indicator",},"/ensemble/samples/controls/progressbar/ProgressBarApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_42 = new SampleInfo("Progress Indicator","A sample that demonstrates the Progress Indicator control in various modes. ","/Controls/Progress Indicator","/ensemble/samples/controls/progressindicator","ensemble.samples.controls.progressindicator.ProgressIndicatorApp","/ensemble/samples/controls/progressindicator/preview.png",new String[]{"/ensemble/samples/controls/progressindicator/ProgressIndicatorApp.java",},new String[]{"javafx.scene.control.ProgressIndicator",},new String[]{},new String[]{"/Controls/Progress Bar",},"/ensemble/samples/controls/progressindicator/ProgressIndicatorApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
@@ -59,7 +59,7 @@
     private static final SampleInfo SAMPLE_52 = new SampleInfo("Simple ListView","A simple implementation of the ListView control, in which a list of items is displayed vertically.  ListView is a powerful multirow control, in which each of a virtually unlimited number of horizontal or vertical rows is defined as a cell. The control also supports dynamically variable nonhomogenous row heights. ","/Controls/Listview/Simple ListView","/ensemble/samples/controls/listview/simplelistview","ensemble.samples.controls.listview.simplelistview.SimpleListViewApp","/ensemble/samples/controls/listview/simplelistview/preview.png",new String[]{"/ensemble/samples/controls/listview/simplelistview/SimpleListViewApp.java",},new String[]{"javafx.scene.control.ListView","javafx.scene.control.SelectionModel",},new String[]{},new String[]{"/Controls/Listview/HorizontalListView","/Controls/Listview/ListViewCellFactory",},"/ensemble/samples/controls/listview/simplelistview/SimpleListViewApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_53 = new SampleInfo("Hidden SplitPane","A sample that demonstrates styling a hidden split pane with CSS. ","/Controls/Splitpane/Hidden SplitPane","/ensemble/samples/controls/splitpane/hiddensplitpane","ensemble.samples.controls.splitpane.hiddensplitpane.HiddenSplitPaneApp","/ensemble/samples/controls/splitpane/hiddensplitpane/preview.png",new String[]{"/ensemble/samples/controls/splitpane/hiddensplitpane/HiddenSplitPaneApp.java","/ensemble/samples/controls/splitpane/hiddensplitpane/HiddenSplitPane.css",},new String[]{"javafx.scene.control.SplitPane",},new String[]{},new String[]{},"/ensemble/samples/controls/splitpane/hiddensplitpane/HiddenSplitPaneApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_54 = new SampleInfo("TabPane","Some implementations of tabs using the TabPane class. ","/Controls/Tab/TabPane","/ensemble/samples/controls/tab/tabpane","ensemble.samples.controls.tab.tabpane.TabPaneApp","/ensemble/samples/controls/tab/tabpane/preview.png",new String[]{"/ensemble/samples/controls/tab/tabpane/TabPaneApp.java","/ensemble/samples/controls/tab/tabpane/tab_16.png",},new String[]{"javafx.scene.control.Tab","javafx.scene.control.TabPane","javafx.scene.control.TabBuilder",},new String[]{},new String[]{},"/ensemble/samples/controls/tab/tabpane/TabPaneApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_55 = new SampleInfo("TableCellFactory","A simple table that uses cell factories to add a checkbox to a table column and to add textfields to table columns. The latter enables editing of first name, last name, and email. ","/Controls/Table/TableCellFactory","/ensemble/samples/controls/table/tablecellfactory","ensemble.samples.controls.table.tablecellfactory.TableCellFactoryApp","/ensemble/samples/controls/table/tablecellfactory/preview.png",new String[]{"/ensemble/samples/controls/table/tablecellfactory/Person.java","/ensemble/samples/controls/table/tablecellfactory/TableCellFactoryApp.java",},new String[]{"javafx.scene.control.TableCell","javafx.scene.control.TableColumn","javafx.scene.control.TablePosition","javafx.scene.control.TableRow","javafx.scene.control.TableView",},new String[]{},new String[]{},"/ensemble/samples/controls/table/tablecellfactory/TableCellFactoryApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_55 = new SampleInfo("TableCellFactory","A simple table that uses cell factories to add a checkbox to a table column and to add textfields to table columns. The latter enables editing of first name, last name, and email. ","/Controls/Table/TableCellFactory","/ensemble/samples/controls/table/tablecellfactory","ensemble.samples.controls.table.tablecellfactory.TableCellFactoryApp","/ensemble/samples/controls/table/tablecellfactory/preview.png",new String[]{"/ensemble/samples/controls/table/tablecellfactory/CheckBoxTableCell.java.orig","/ensemble/samples/controls/table/tablecellfactory/CheckBoxTableCell.java.save","/ensemble/samples/controls/table/tablecellfactory/EditingCell.java.orig","/ensemble/samples/controls/table/tablecellfactory/Person.java","/ensemble/samples/controls/table/tablecellfactory/TableCellFactoryApp.java",},new String[]{"javafx.scene.control.TableCell","javafx.scene.control.TableColumn","javafx.scene.control.TablePosition","javafx.scene.control.TableRow","javafx.scene.control.TableView",},new String[]{},new String[]{},"/ensemble/samples/controls/table/tablecellfactory/TableCellFactoryApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_56 = new SampleInfo("TableView","A simple table with a header row. ","/Controls/Table/TableView","/ensemble/samples/controls/table/tableview","ensemble.samples.controls.table.tableview.TableViewApp","/ensemble/samples/controls/table/tableview/preview.png",new String[]{"/ensemble/samples/controls/table/tableview/Person.java","/ensemble/samples/controls/table/tableview/TableViewApp.java",},new String[]{"javafx.scene.control.TableColumn","javafx.scene.control.TablePosition","javafx.scene.control.TableRow","javafx.scene.control.TableView",},new String[]{},new String[]{},"/ensemble/samples/controls/table/tableview/TableViewApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_57 = new SampleInfo("Advanced Label","Several Label controls, displayed in various alignments with respect to an image. ","/Controls/Text/Advanced Label","/ensemble/samples/controls/text/advancedlabel","ensemble.samples.controls.text.advancedlabel.AdvancedLabelApp","/ensemble/samples/controls/text/advancedlabel/preview.png",new String[]{"/ensemble/samples/shared-resources/icon-48x48.png","/ensemble/samples/controls/text/advancedlabel/AdvancedLabelApp.java",},new String[]{"javafx.scene.control.Label",},new String[]{},new String[]{"/Controls/Text/Simple Label","/Controls/Button/Graphic Button",},"/ensemble/samples/controls/text/advancedlabel/AdvancedLabelApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_58 = new SampleInfo("Inset Text","A sample that shows styling of text through CSS. ","/Controls/Text/Inset Text","/ensemble/samples/controls/text/insettext","ensemble.samples.controls.text.insettext.InsetTextApp","/ensemble/samples/controls/text/insettext/preview.png",new String[]{"/ensemble/samples/controls/text/insettext/InsetTextApp.java","/ensemble/samples/controls/text/insettext/InsetText.css",},new String[]{"javafx.geometry.Insets","javafx.scene.control.LabelBuilder",},new String[]{},new String[]{"/Controls/Text/Simple Label",},"/ensemble/samples/controls/text/insettext/InsetTextApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
@@ -71,7 +71,7 @@
     private static final SampleInfo SAMPLE_64 = new SampleInfo("Tool Bar","A toolbar with three buttons. ","/Controls/Toolbar/Tool Bar","/ensemble/samples/controls/toolbar/toolbar","ensemble.samples.controls.toolbar.toolbar.ToolBarApp","/ensemble/samples/controls/toolbar/toolbar/preview.png",new String[]{"/ensemble/samples/controls/toolbar/toolbar/ToolBarApp.java",},new String[]{"javafx.scene.control.ToolBar",},new String[]{},new String[]{},"/ensemble/samples/controls/toolbar/toolbar/ToolBarApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_65 = new SampleInfo("FXML Login Demo","FXML-based Login screen sample ","/Fxml/FXML Login Demo","/ensemble/samples/fxml/fxmldemo","ensemble.samples.fxml.fxmldemo.FXMLLoginDemoApp","/ensemble/samples/fxml/fxmldemo/preview.png",new String[]{"/ensemble/samples/fxml/fxmldemo/Authenticator.java","/ensemble/samples/fxml/fxmldemo/FXMLLoginDemoApp.java","/ensemble/samples/fxml/fxmldemo/LoginController.java","/ensemble/samples/fxml/fxmldemo/ProfileController.java","/ensemble/samples/fxml/fxmldemo/User.java","/ensemble/samples/fxml/fxmldemo/Login.css","/ensemble/samples/fxml/fxmldemo/Login.fxml","/ensemble/samples/fxml/fxmldemo/Profile.fxml",},new String[]{"java.util.HashMap","java.util.Map","java.io.InputStream","java.util.logging.Level","java.util.logging.Logger","javafx.fxml.FXML","javafx.fxml.FXMLLoader","javafx.fxml.Initializable","javafx.fxml.JavaFXBuilderFactory","javafx.stage.Stage",},new String[]{},new String[]{},"/ensemble/samples/fxml/fxmldemo/FXMLLoginDemoApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_66 = new SampleInfo("Bouncing Balls","A sample that shows animated bouncing balls. Select a ball to start or stop the animation. Select the reset button to stop all the balls. ","/Graphics/Bouncing Balls","/ensemble/samples/graphics/bouncingballs","ensemble.samples.graphics.bouncingballs.BouncingBallsApp","/ensemble/samples/graphics/bouncingballs/preview.png",new String[]{"/ensemble/samples/graphics/bouncingballs/Ball.java","/ensemble/samples/graphics/bouncingballs/BallsPane.java","/ensemble/samples/graphics/bouncingballs/BallsScreen.java","/ensemble/samples/graphics/bouncingballs/BouncingBallsApp.java","/ensemble/samples/graphics/bouncingballs/Constants.java",},new String[]{"java.util.ArrayList","java.util.List","javafx.util.Duration","javafx.stage.Stage","javafx.stage.Screen","javafx.scene.Parent","javafx.scene.Group","javafx.scene.Scene","javafx.scene.Node","javafx.scene.effect.Reflection","javafx.scene.shape.Rectangle","javafx.scene.shape.Line","javafx.scene.shape.Circle","javafx.scene.paint.Color","javafx.scene.paint.CycleMethod","javafx.scene.paint.RadialGradient","javafx.scene.paint.Stop","javafx.scene.control.Button","javafx.scene.text.Text","javafx.application.Application","javafx.animation.Interpolator","javafx.animation.KeyFrame","javafx.animation.KeyValue","javafx.animation.Timeline","javafx.animation.Animation.Status","javafx.event.EventHandler","javafx.event.ActionEvent","javafx.scene.input.MouseEvent","javafx.geometry.Insets",},new String[]{},new String[]{},"/ensemble/samples/graphics/bouncingballs/BouncingBallsApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_67 = new SampleInfo("Brick Breaker","The main purpose of the game is to break all the bricks and not drop the ball. ","/Graphics/Brick Breaker","/ensemble/samples/graphics/brickbreaker","ensemble.samples.graphics.brickbreaker.BrickBreakerApp","/ensemble/samples/graphics/brickbreaker/preview.png",new String[]{"/ensemble/samples/graphics/brickbreaker/Ball.java","/ensemble/samples/graphics/brickbreaker/Bat.java","/ensemble/samples/graphics/brickbreaker/Bonus.java","/ensemble/samples/graphics/brickbreaker/Brick.java","/ensemble/samples/graphics/brickbreaker/BrickBreakerApp.java","/ensemble/samples/shared-resources/brickImages/background.png","/ensemble/samples/shared-resources/brickImages/bat/left.png","/ensemble/samples/shared-resources/brickImages/bat/center.png","/ensemble/samples/shared-resources/brickImages/bat/right.png","/ensemble/samples/shared-resources/brickImages/ball/ball0.png","/ensemble/samples/shared-resources/brickImages/ball/ball1.png","/ensemble/samples/shared-resources/brickImages/ball/ball2.png","/ensemble/samples/shared-resources/brickImages/ball/ball3.png","/ensemble/samples/shared-resources/brickImages/ball/ball4.png","/ensemble/samples/shared-resources/brickImages/ball/ball5.png","/ensemble/samples/shared-resources/brickImages/logo.png","/ensemble/samples/shared-resources/brickImages/splash/brick.png","/ensemble/samples/shared-resources/brickImages/splash/brickshadow.png","/ensemble/samples/shared-resources/brickImages/splash/breaker.png","/ensemble/samples/shared-resources/brickImages/splash/breakershadow.png","/ensemble/samples/shared-resources/brickImages/splash/pressanykey.png","/ensemble/samples/shared-resources/brickImages/splash/pressanykeyshadow.png","/ensemble/samples/shared-resources/brickImages/splash/strike.png","/ensemble/samples/shared-resources/brickImages/splash/strikeshadow.png","/ensemble/samples/shared-resources/brickImages/splash/sun.png","/ensemble/samples/shared-resources/brickImages/ready.png","/ensemble/samples/shared-resources/brickImages/gameover.png","/ensemble/samples/shared-resources/brickImages/brick/blue.png","/ensemble/samples/shared-resources/brickImages/brick/broken1.png","/ensemble/samples/shared-resources/brickImages/brick/broken2.png","/ensemble/samples/shared-resources/brickImages/brick/brown.png","/ensemble/samples/shared-resources/brickImages/brick/cyan.png","/ensemble/samples/shared-resources/brickImages/brick/green.png","/ensemble/samples/shared-resources/brickImages/brick/grey.png","/ensemble/samples/shared-resources/brickImages/brick/magenta.png","/ensemble/samples/shared-resources/brickImages/brick/orange.png","/ensemble/samples/shared-resources/brickImages/brick/red.png","/ensemble/samples/shared-resources/brickImages/brick/violet.png","/ensemble/samples/shared-resources/brickImages/brick/white.png","/ensemble/samples/shared-resources/brickImages/brick/yellow.png","/ensemble/samples/shared-resources/brickImages/bonus/ballslow.png","/ensemble/samples/shared-resources/brickImages/bonus/ballfast.png","/ensemble/samples/shared-resources/brickImages/bonus/catch.png","/ensemble/samples/shared-resources/brickImages/bonus/batgrow.png","/ensemble/samples/shared-resources/brickImages/bonus/batreduce.png","/ensemble/samples/shared-resources/brickImages/bonus/ballgrow.png","/ensemble/samples/shared-resources/brickImages/bonus/ballreduce.png","/ensemble/samples/shared-resources/brickImages/bonus/strike.png","/ensemble/samples/shared-resources/brickImages/bonus/extralife.png","/ensemble/samples/graphics/brickbreaker/Config.java","/ensemble/samples/shared-resources/brickImages/vline.png","/ensemble/samples/graphics/brickbreaker/Level.java","/ensemble/samples/graphics/brickbreaker/LevelData.java","/ensemble/samples/graphics/brickbreaker/Splash.java","/ensemble/samples/graphics/brickbreaker/Utils.java",},new String[]{"javafx.scene.image.Image","javafx.scene.image.ImageView","javafx.util.Duration","javafx.animation.KeyFrame","javafx.animation.KeyValue","javafx.animation.Timeline","javafx.application.Application","javafx.application.Platform","javafx.collections.ObservableList","javafx.geometry.Rectangle2D","javafx.geometry.VPos",},new String[]{},new String[]{},"/ensemble/samples/graphics/brickbreaker/BrickBreakerApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_67 = new SampleInfo("Brick Breaker","The main purpose of the game is to break all the bricks and not drop the ball. ","/Graphics/Brick Breaker","/ensemble/samples/graphics/brickbreaker","ensemble.samples.graphics.brickbreaker.BrickBreakerApp","/ensemble/samples/graphics/brickbreaker/preview.png",new String[]{"/ensemble/samples/graphics/brickbreaker/Ball.java","/ensemble/samples/graphics/brickbreaker/Bat.java","/ensemble/samples/graphics/brickbreaker/Bonus.java","/ensemble/samples/graphics/brickbreaker/Brick.java","/ensemble/samples/graphics/brickbreaker/BrickBreakerApp.java","/ensemble/samples/graphics/brickbreaker/BrickBreakerApp.java.orig","/ensemble/samples/shared-resources/brickImages/background.png","/ensemble/samples/shared-resources/brickImages/bat/left.png","/ensemble/samples/shared-resources/brickImages/bat/center.png","/ensemble/samples/shared-resources/brickImages/bat/right.png","/ensemble/samples/shared-resources/brickImages/ball/ball0.png","/ensemble/samples/shared-resources/brickImages/ball/ball1.png","/ensemble/samples/shared-resources/brickImages/ball/ball2.png","/ensemble/samples/shared-resources/brickImages/ball/ball3.png","/ensemble/samples/shared-resources/brickImages/ball/ball4.png","/ensemble/samples/shared-resources/brickImages/ball/ball5.png","/ensemble/samples/shared-resources/brickImages/logo.png","/ensemble/samples/shared-resources/brickImages/splash/brick.png","/ensemble/samples/shared-resources/brickImages/splash/brickshadow.png","/ensemble/samples/shared-resources/brickImages/splash/breaker.png","/ensemble/samples/shared-resources/brickImages/splash/breakershadow.png","/ensemble/samples/shared-resources/brickImages/splash/pressanykey.png","/ensemble/samples/shared-resources/brickImages/splash/pressanykeyshadow.png","/ensemble/samples/shared-resources/brickImages/splash/strike.png","/ensemble/samples/shared-resources/brickImages/splash/strikeshadow.png","/ensemble/samples/shared-resources/brickImages/splash/sun.png","/ensemble/samples/shared-resources/brickImages/ready.png","/ensemble/samples/shared-resources/brickImages/gameover.png","/ensemble/samples/shared-resources/brickImages/brick/blue.png","/ensemble/samples/shared-resources/brickImages/brick/broken1.png","/ensemble/samples/shared-resources/brickImages/brick/broken2.png","/ensemble/samples/shared-resources/brickImages/brick/brown.png","/ensemble/samples/shared-resources/brickImages/brick/cyan.png","/ensemble/samples/shared-resources/brickImages/brick/green.png","/ensemble/samples/shared-resources/brickImages/brick/grey.png","/ensemble/samples/shared-resources/brickImages/brick/magenta.png","/ensemble/samples/shared-resources/brickImages/brick/orange.png","/ensemble/samples/shared-resources/brickImages/brick/red.png","/ensemble/samples/shared-resources/brickImages/brick/violet.png","/ensemble/samples/shared-resources/brickImages/brick/white.png","/ensemble/samples/shared-resources/brickImages/brick/yellow.png","/ensemble/samples/shared-resources/brickImages/bonus/ballslow.png","/ensemble/samples/shared-resources/brickImages/bonus/ballfast.png","/ensemble/samples/shared-resources/brickImages/bonus/catch.png","/ensemble/samples/shared-resources/brickImages/bonus/batgrow.png","/ensemble/samples/shared-resources/brickImages/bonus/batreduce.png","/ensemble/samples/shared-resources/brickImages/bonus/ballgrow.png","/ensemble/samples/shared-resources/brickImages/bonus/ballreduce.png","/ensemble/samples/shared-resources/brickImages/bonus/strike.png","/ensemble/samples/shared-resources/brickImages/bonus/extralife.png","/ensemble/samples/graphics/brickbreaker/Config.java","/ensemble/samples/graphics/brickbreaker/Config.java.orig","/ensemble/samples/shared-resources/brickImages/vline.png","/ensemble/samples/graphics/brickbreaker/Level.java","/ensemble/samples/graphics/brickbreaker/Level.java.orig","/ensemble/samples/graphics/brickbreaker/LevelData.java","/ensemble/samples/graphics/brickbreaker/Splash.java","/ensemble/samples/graphics/brickbreaker/Utils.java",},new String[]{"javafx.scene.image.Image","javafx.scene.image.ImageView","javafx.util.Duration","javafx.animation.KeyFrame","javafx.animation.KeyValue","javafx.animation.Timeline","javafx.application.Application","javafx.application.Platform","javafx.collections.ObservableList","javafx.geometry.Rectangle2D","javafx.geometry.VPos",},new String[]{},new String[]{},"/ensemble/samples/graphics/brickbreaker/BrickBreakerApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_68 = new SampleInfo("Calculator","A calculator that performs simple math exercises. ","/Graphics/Calculator","/ensemble/samples/graphics/calc","ensemble.samples.graphics.calc.CalculatorApp","/ensemble/samples/graphics/calc/preview.png",new String[]{"/ensemble/samples/graphics/calc/Calculator.java","/ensemble/samples/graphics/calc/CalculatorApp.java","/ensemble/samples/graphics/calc/Key.java","/ensemble/samples/graphics/calc/Util.java",},new String[]{"javafx.application.Application","javafx.stage.Stage","javafx.scene.Scene","javafx.scene.Group","javafx.scene.Parent","javafx.scene.paint.Color","javafx.scene.paint.CycleMethod","javafx.scene.paint.LinearGradient","javafx.scene.paint.Stop","javafx.scene.input.KeyEvent","javafx.scene.input.MouseEvent","javafx.scene.shape.Rectangle","javafx.scene.text.Font","javafx.scene.text.Text","javafx.event.EventHandler","javafx.geometry.VPos",},new String[]{},new String[]{},"/ensemble/samples/graphics/calc/CalculatorApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_69 = new SampleInfo("Colorful Circles","A sample that demonstrates how to draw and paint shapes, apply visual effects, blend colors in overlapping objects, and animate objects. ","/Graphics/Colorful Circles","/ensemble/samples/graphics/colorfulcircles","ensemble.samples.graphics.colorfulcircles.ColorfulCirclesApp","/ensemble/samples/graphics/colorfulcircles/preview.png",new String[]{"/ensemble/samples/graphics/colorfulcircles/ColorfulCirclesApp.java",},new String[]{"javafx.scene.effect.BlendMode","javafx.scene.effect.BoxBlur","javafx.scene.shape.Circle","javafx.scene.Group","javafx.scene.paint.LinearGradient","javafx.animation.Timeline",},new String[]{},new String[]{},"/ensemble/samples/graphics/colorfulcircles/ColorfulCirclesApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_70 = new SampleInfo("Digital Clock","A digital clock application that demonstrates JavaFX animation, images, and effects. ","/Graphics/Digital Clock","/ensemble/samples/graphics/digitalclock","ensemble.samples.graphics.digitalclock.DigitalClockApp","/ensemble/samples/graphics/digitalclock/preview.png",new String[]{"/ensemble/samples/graphics/digitalclock/Clock.java","/ensemble/samples/graphics/digitalclock/Digit.java","/ensemble/samples/shared-resources/DigitalClock-background.png","/ensemble/samples/graphics/digitalclock/DigitalClockApp.java",},new String[]{"javafx.scene.effect.Glow","javafx.scene.shape.Polygon","javafx.scene.transform.Shear",},new String[]{},new String[]{},"/ensemble/samples/graphics/digitalclock/DigitalClockApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
@@ -99,7 +99,7 @@
     private static final SampleInfo SAMPLE_92 = new SampleInfo("Polyline","A sample that demonstrates polyline construction with stroke and fill. ","/Graphics/Shapes/Polyline","/ensemble/samples/graphics/shapes/polyline","ensemble.samples.graphics.shapes.polyline.PolylineApp","/ensemble/samples/graphics/shapes/polyline/preview.png",new String[]{"/ensemble/samples/graphics/shapes/polyline/PolylineApp.java",},new String[]{"javafx.scene.shape.Polyline","javafx.scene.shape.Shape","javafx.scene.paint.Color",},new String[]{},new String[]{},"/ensemble/samples/graphics/shapes/polyline/PolylineApp.java",new PlaygroundProperty[]{new PlaygroundProperty("polyline1","fill","name","Polyline 1 Fill"),new PlaygroundProperty("polyline1","stroke","name","Polyline 1 Stroke"),new PlaygroundProperty("polyline2","stroke","name","Polyline 2 Stroke"),},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_93 = new SampleInfo("Quad Curve","An example of how various settings affect a quadratic B??zier parametric curve. ","/Graphics/Shapes/Quad Curve","/ensemble/samples/graphics/shapes/quadcurve","ensemble.samples.graphics.shapes.quadcurve.QuadCurveApp","/ensemble/samples/graphics/shapes/quadcurve/preview.png",new String[]{"/ensemble/samples/graphics/shapes/quadcurve/QuadCurveApp.java",},new String[]{"javafx.scene.shape.QuadCurve","javafx.scene.shape.Shape","javafx.scene.paint.Color",},new String[]{},new String[]{},"/ensemble/samples/graphics/shapes/quadcurve/QuadCurveApp.java",new PlaygroundProperty[]{new PlaygroundProperty("quadCurve","fill","name","Cubic Curve Fill"),new PlaygroundProperty("quadCurve","stroke","name","Cubic Curve Stroke"),new PlaygroundProperty("quadCurve","startX","min","0","max","170","name","Cubic Curve Start X"),new PlaygroundProperty("quadCurve","startY","min","10","max","80","name","Cubic Curve Start Y"),new PlaygroundProperty("quadCurve","controlX","min","0","max","180","name","Cubic Curve Control X"),new PlaygroundProperty("quadCurve","controlY","min","0","max","90","name","Cubic Curve Control Y"),new PlaygroundProperty("quadCurve","endX","min","10","max","180","name","Cubic Curve End X"),new PlaygroundProperty("quadCurve","endY","min","10","max","80","name","Cubic Curve End Y"),},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_94 = new SampleInfo("Rectangle","A sample showing how various settings effect two rectangles. ","/Graphics/Shapes/Rectangle","/ensemble/samples/graphics/shapes/rectangle","ensemble.samples.graphics.shapes.rectangle.RectangleApp","/ensemble/samples/graphics/shapes/rectangle/preview.png",new String[]{"/ensemble/samples/graphics/shapes/rectangle/RectangleApp.java",},new String[]{"javafx.scene.shape.Rectangle","javafx.scene.shape.Shape","javafx.scene.paint.Color",},new String[]{},new String[]{},"/ensemble/samples/graphics/shapes/rectangle/RectangleApp.java",new PlaygroundProperty[]{new PlaygroundProperty("rect1","fill","name","Rectangle 1 Fill"),new PlaygroundProperty("rect1","width","min","10","max","50","name","Rectangle 1 Width"),new PlaygroundProperty("rect1","height","min","10","max","50","name","Rectangle 1 Height"),new PlaygroundProperty("rect1","arcWidth","min","0","max","50","name","Rectangle 1 Arc Width"),new PlaygroundProperty("rect1","arcHeight","min","0","max","50","name","Rectangle 1 Arc Height"),new PlaygroundProperty("rect2","stroke","name","Rectangle 2 Stroke"),new PlaygroundProperty("rect2","strokeWidth","min","1","max","5","name","Rectangle 2 Stroke Width"),new PlaygroundProperty("rect2","width","min","10","max","50","name","Rectangle 2 Width"),new PlaygroundProperty("rect2","height","min","10","max","50","name","Rectangle 2 Height"),new PlaygroundProperty("rect2","arcWidth","min","0","max","50","name","Rectangle 2 Arc Width"),new PlaygroundProperty("rect2","arcHeight","min","0","max","50","name","Rectangle 2 Arc Height"),},new ConditionalFeature[]{});
-    private static final SampleInfo SAMPLE_95 = new SampleInfo("3D Cubes","A sample that demonstrates an animated rotation of 3D cubes. When the application runs in standalone mode, the scene must be constructed with the depthBuffer argument set to true, and the root node must have depthTest set to true. ","/Graphics 3d/3D Cubes","/ensemble/samples/graphics3d/cube","ensemble.samples.graphics3d.cube.CubeApp","/ensemble/samples/graphics3d/cube/preview.png",new String[]{"/ensemble/samples/graphics3d/cube/Cube.java","/ensemble/samples/graphics3d/cube/CubeApp.java","/ensemble/samples/graphics3d/cube/CubeApp.java.orig","/ensemble/samples/graphics3d/cube/CubeApp.java.save",},new String[]{"javafx.scene.transform.Rotate","javafx.scene.paint.Color","javafx.scene.shape.RectangleBuilder",},new String[]{},new String[]{},"/ensemble/samples/graphics3d/cube/CubeApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_95 = new SampleInfo("3D Cubes","A sample that demonstrates an animated rotation of 3D cubes. When the application runs in standalone mode, the scene must be constructed with the depthBuffer argument set to true, and the root node must have depthTest set to true. ","/Graphics 3d/3D Cubes","/ensemble/samples/graphics3d/cube","ensemble.samples.graphics3d.cube.CubeApp","/ensemble/samples/graphics3d/cube/preview.png",new String[]{"/ensemble/samples/graphics3d/cube/Cube.java","/ensemble/samples/graphics3d/cube/CubeApp.java",},new String[]{"javafx.scene.transform.Rotate","javafx.scene.paint.Color","javafx.scene.shape.RectangleBuilder",},new String[]{},new String[]{},"/ensemble/samples/graphics3d/cube/CubeApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_96 = new SampleInfo("3D Cube System","A sample that demonstrates an animated rotation of 3D cubes. When the application runs in standalone mode, the scene must be constructed with the depthBuffer argument set to true, and the root node must have depthTest set to true. ","/Graphics 3d/3D Cube System","/ensemble/samples/graphics3d/cubesystem","ensemble.samples.graphics3d.cubesystem.CubeSystemApp","/ensemble/samples/graphics3d/cubesystem/preview.png",new String[]{"/ensemble/samples/graphics3d/cubesystem/Cube.java","/ensemble/samples/graphics3d/cubesystem/CubeSystemApp.java","/ensemble/samples/graphics3d/cubesystem/Xform.java",},new String[]{"javafx.scene.transform.Rotate","javafx.scene.paint.Color","javafx.scene.shape.RectangleBuilder",},new String[]{},new String[]{},"/ensemble/samples/graphics3d/cubesystem/CubeSystemApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_97 = new SampleInfo("3D Box","A sample that shows a 3D box and uses a perspective camera for rendering the scene. ","/Graphics 3d/3D Box","/ensemble/samples/graphics3d/simple3dbox","ensemble.samples.graphics3d.simple3dbox.Simple3DBoxApp","/ensemble/samples/graphics3d/simple3dbox/preview.png",new String[]{"/ensemble/samples/graphics3d/simple3dbox/Simple3DBoxApp.java",},new String[]{"javafx.scene.paint.Color","javafx.scene.transform.Rotate","javafx.scene.transform.Translate",},new String[]{},new String[]{},"/ensemble/samples/graphics3d/simple3dbox/Simple3DBoxApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_98 = new SampleInfo("Xylophone","A sample that demonstrates a xylophone made of 3D cubes. When the application runs in standalone mode, the scene must be constructed with the depthBuffer argument set to true, and the root node must have depthTest set to true. ","/Graphics 3d/Xylophone","/ensemble/samples/graphics3d/xylophone","ensemble.samples.graphics3d.xylophone.XylophoneApp","/ensemble/samples/graphics3d/xylophone/preview.png",new String[]{"/ensemble/samples/graphics3d/xylophone/Cube.java","/ensemble/samples/graphics3d/xylophone/Xform.java","/ensemble/samples/shared-resources/Note1.wav","/ensemble/samples/shared-resources/Note2.wav","/ensemble/samples/shared-resources/Note3.wav","/ensemble/samples/shared-resources/Note4.wav","/ensemble/samples/shared-resources/Note5.wav","/ensemble/samples/shared-resources/Note6.wav","/ensemble/samples/shared-resources/Note7.wav","/ensemble/samples/shared-resources/Note8.wav","/ensemble/samples/graphics3d/xylophone/XylophoneApp.java",},new String[]{"javafx.scene.transform.Rotate","javafx.scene.paint.Color","javafx.scene.shape.RectangleBuilder",},new String[]{},new String[]{},"/ensemble/samples/graphics3d/xylophone/XylophoneApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
@@ -116,16 +116,16 @@
     private static final SampleInfo SAMPLE_109 = new SampleInfo("VBox","A simple example of a VBox layout. ","/Layout/VBox","/ensemble/samples/layout/vbox","ensemble.samples.layout.vbox.VBoxApp","/ensemble/samples/layout/vbox/preview.png",new String[]{"/ensemble/samples/layout/vbox/VBoxApp.java",},new String[]{"javafx.scene.layout.VBox",},new String[]{},new String[]{},"/ensemble/samples/layout/vbox/VBoxApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_110 = new SampleInfo("Advanced Media","An advanced media player with controls for play/pause, seek, and volume. ","/Media/Advanced Media","/ensemble/samples/media/advancedmedia","ensemble.samples.media.advancedmedia.AdvancedMediaApp","/ensemble/samples/media/advancedmedia/preview.png",new String[]{"/ensemble/samples/media/advancedmedia/AdvancedMediaApp.java","/ensemble/samples/shared-resources/playbutton.png","/ensemble/samples/shared-resources/pausebutton.png","/ensemble/samples/media/advancedmedia/MediaControl.java",},new String[]{"javafx.scene.media.MediaPlayer","javafx.scene.media.Media",},new String[]{},new String[]{"/Media/Alpha Media Player","/Media/Overlay Media Player","/Media/Streaming Media Player",},"/ensemble/samples/media/advancedmedia/AdvancedMediaApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
     private static final SampleInfo SAMPLE_111 = new SampleInfo("Alpha Media Player","An alpha media player with 2 different media views and alpha channels. ","/Media/Alpha Media Player","/ensemble/samples/media/alphamediaplayer","ensemble.samples.media.alphamediaplayer.AlphaMediaPlayerApp","/ensemble/samples/media/alphamediaplayer/preview.png",new String[]{"/ensemble/samples/media/alphamediaplayer/AlphaMediaPlayerApp.java","/ensemble/samples/media/alphamediaplayer/PlanetaryPlayerPane.java","/ensemble/samples/media/alphamediaplayer/AlphaMediaPlayer.css",},new String[]{"javafx.scene.media.MediaPlayer","javafx.scene.media.Media",},new String[]{},new String[]{"/Media/Advanced Media","/Media/Overlay Media Player","/Media/Streaming Media Player",},"/ensemble/samples/media/alphamediaplayer/AlphaMediaPlayerApp.java",new PlaygroundProperty[]{new PlaygroundProperty(null,"arthPos","min","-100","max","100","name","Arth Position"),new PlaygroundProperty(null,"fierPos","min","-100","max","100","name","Fier Position"),new PlaygroundProperty(null,"arthRate","min","0.1","max","1","name","Arth Rate"),new PlaygroundProperty(null,"fierRate","min","0.1","max","1","name","Fier Rate"),},new ConditionalFeature[]{ConditionalFeature.WEB,});
-    private static final SampleInfo SAMPLE_112 = new SampleInfo("Audio Clip","A sample that demonstrates the basics of AudioClips. ","/Media/Audio Clip","/ensemble/samples/media/audioclip","ensemble.samples.media.audioclip.AudioClipApp","/ensemble/samples/media/audioclip/preview.png",new String[]{"/ensemble/samples/shared-resources/Note1.wav","/ensemble/samples/shared-resources/Note2.wav","/ensemble/samples/shared-resources/Note3.wav","/ensemble/samples/shared-resources/Note4.wav","/ensemble/samples/shared-resources/Note5.wav","/ensemble/samples/shared-resources/Note6.wav","/ensemble/samples/shared-resources/Note7.wav","/ensemble/samples/shared-resources/Note8.wav","/ensemble/samples/media/audioclip/AudioClipApp.java",},new String[]{"javafx.scene.media.AudioClip",},new String[]{},new String[]{"/Graphics3d/Xylophone",},"/ensemble/samples/media/audioclip/AudioClipApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
+    private static final SampleInfo SAMPLE_112 = new SampleInfo("Audio Clip","A sample that demonstrates the basics of AudioClips. ","/Media/Audio Clip","/ensemble/samples/media/audioclip","ensemble.samples.media.audioclip.AudioClipApp","/ensemble/samples/media/audioclip/preview.png",new String[]{"/ensemble/samples/shared-resources/Note1.wav","/ensemble/samples/shared-resources/Note2.wav","/ensemble/samples/shared-resources/Note3.wav","/ensemble/samples/shared-resources/Note4.wav","/ensemble/samples/shared-resources/Note5.wav","/ensemble/samples/shared-resources/Note6.wav","/ensemble/samples/shared-resources/Note7.wav","/ensemble/samples/shared-resources/Note8.wav","/ensemble/samples/media/audioclip/AudioClipApp.java","/ensemble/samples/media/audioclip/AudioClipApp.java.orig",},new String[]{"javafx.scene.media.AudioClip",},new String[]{},new String[]{"/Graphics3d/Xylophone",},"/ensemble/samples/media/audioclip/AudioClipApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
     private static final SampleInfo SAMPLE_113 = new SampleInfo("Overlay Media Player","A media player with controls for play, pause, stop, seek, and volume. This media player also demonstrates overlaying the player controls on top of the media. ","/Media/Overlay Media Player","/ensemble/samples/media/overlaymediaplayer","ensemble.samples.media.overlaymediaplayer.OverlayMediaPlayerApp","/ensemble/samples/media/overlaymediaplayer/preview.png",new String[]{"/ensemble/samples/media/overlaymediaplayer/OverlayMediaPlayerApp.java","/ensemble/samples/media/overlaymediaplayer/PlayerPane.java","/ensemble/samples/media/overlaymediaplayer/OverlayMediaPlayer.css",},new String[]{"javafx.scene.media.MediaPlayer","javafx.scene.media.Media",},new String[]{},new String[]{"/Media/Advanced Media","/Media/Alpha Media Player","/Media/Streaming Media Player",},"/ensemble/samples/media/overlaymediaplayer/OverlayMediaPlayerApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
     private static final SampleInfo SAMPLE_114 = new SampleInfo("Streaming Media Player","A media player with controls for play, pause, stop, seek, and volume. This media player is playing media via HTTP Live Streaming, also known as HLS. ","/Media/Streaming Media Player","/ensemble/samples/media/streamingmediaplayer","ensemble.samples.media.streamingmediaplayer.StreamingMediaPlayerApp","/ensemble/samples/media/streamingmediaplayer/preview.png",new String[]{"/ensemble/samples/media/streamingmediaplayer/PlayerPane.java","/ensemble/samples/media/streamingmediaplayer/StreamingMediaPlayerApp.java","/ensemble/samples/media/streamingmediaplayer/StreamingMediaPlayer.css",},new String[]{"javafx.scene.media.MediaPlayer","javafx.scene.media.Media",},new String[]{},new String[]{"/Media/Advanced Media","/Media/Alpha Media Player","/Media/Overlay Media Player",},"/ensemble/samples/media/streamingmediaplayer/StreamingMediaPlayerApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
-    private static final SampleInfo SAMPLE_115 = new SampleInfo("Cursor","A sample that demonstrates changing the cursor icon. ","/Scenegraph/Events/Cursor","/ensemble/samples/scenegraph/events/cursor","ensemble.samples.scenegraph.events.cursor.CursorApp","/ensemble/samples/scenegraph/events/cursor/preview.png",new String[]{"/ensemble/samples/scenegraph/events/cursor/CursorApp.java",},new String[]{"javafx.scene.Cursor",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/events/cursor/CursorApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_115 = new SampleInfo("Cursor","A sample that demonstrates changing the cursor icon. ","/Scenegraph/Events/Cursor","/ensemble/samples/scenegraph/events/cursor","ensemble.samples.scenegraph.events.cursor.CursorApp","/ensemble/samples/scenegraph/events/cursor/preview.png",new String[]{"/ensemble/samples/scenegraph/events/cursor/CursorApp.java","/ensemble/samples/scenegraph/events/cursor/CursorApp.java.orig",},new String[]{"javafx.scene.Cursor",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/events/cursor/CursorApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_116 = new SampleInfo("Gesture Event","A sample that demonstrates various gesture events and their usage. Scroll the rectangle or the background behind the rectangle to move the rectangle itself. Similarly, rotate, zoom in, or zoom out the rectangle. All events are logged to the console. ","/Scenegraph/Events/Gesture Event","/ensemble/samples/scenegraph/events/gestureevent","ensemble.samples.scenegraph.events.gestureevent.GestureEventApp","/ensemble/samples/scenegraph/events/gestureevent/preview.png",new String[]{"/ensemble/samples/scenegraph/events/gestureevent/GestureEventApp.java",},new String[]{"javafx.collections.ObservableList","javafx.scene.Cursor","javafx.scene.input.GestureEvent","javafx.scene.input.RotateEvent","javafx.scene.input.ScrollEvent","javafx.scene.input.SwipeEvent","javafx.scene.input.ZoomEvent","javafx.event.EventHandler",},new String[]{},new String[]{"/Scenegraph/Events/MouseEvent",},"/ensemble/samples/scenegraph/events/gestureevent/GestureEventApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_117 = new SampleInfo("KeyEvent","A sample that demonstrates various key events and their usage. Type in the text box to view the triggered events: key pressed, key typed and key released. Pressing the Shift, Ctrl, and Alt keys also trigger events. ","/Scenegraph/Events/KeyEvent","/ensemble/samples/scenegraph/events/keyevent","ensemble.samples.scenegraph.events.keyevent.KeyEventApp","/ensemble/samples/scenegraph/events/keyevent/preview.png",new String[]{"/ensemble/samples/scenegraph/events/keyevent/KeyEventApp.java",},new String[]{"javafx.scene.input.KeyCode","javafx.scene.input.KeyEvent","javafx.event.EventHandler",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/events/keyevent/KeyEventApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_118 = new SampleInfo("Key Stroke Motion","An example of animation generated from key events. Click the grey area to give it focus and try typing letters. ","/Scenegraph/Events/Key Stroke Motion","/ensemble/samples/scenegraph/events/keystrokemotion","ensemble.samples.scenegraph.events.keystrokemotion.KeyStrokeMotionApp","/ensemble/samples/scenegraph/events/keystrokemotion/preview.png",new String[]{"/ensemble/samples/scenegraph/events/keystrokemotion/KeyStrokeMotionApp.java","/ensemble/samples/scenegraph/events/keystrokemotion/LettersPane.java",},new String[]{"javafx.scene.input.KeyEvent","javafx.animation.Interpolator",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/events/keystrokemotion/KeyStrokeMotionApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_119 = new SampleInfo("MouseEvent","A sample that demonstrates various mouse and scroll events and their usage. Click the circles and drag them across the screen. Scroll the whole screen. All events are logged to the console. ","/Scenegraph/Events/MouseEvent","/ensemble/samples/scenegraph/events/mouseevent","ensemble.samples.scenegraph.events.mouseevent.MouseEventApp","/ensemble/samples/scenegraph/events/mouseevent/preview.png",new String[]{"/ensemble/samples/scenegraph/events/mouseevent/MouseEventApp.java",},new String[]{"javafx.scene.Cursor","javafx.scene.input.MouseEvent","javafx.event.EventHandler",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/events/mouseevent/MouseEventApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_120 = new SampleInfo("Multi-Touch","A sample that demonstrates multi-touch support. You can zoom in and out of the images and also rotate the images with multi-touch. ","/Scenegraph/Events/Multi-Touch","/ensemble/samples/scenegraph/events/multitouch","ensemble.samples.scenegraph.events.multitouch.MultiTouchApp","/ensemble/samples/scenegraph/events/multitouch/preview.png",new String[]{"/ensemble/samples/scenegraph/events/multitouch/MultiTouchApp.java","/ensemble/samples/scenegraph/events/multitouch/MultiTouchImageView.java","/ensemble/samples/shared-resources/warning.png","/ensemble/samples/shared-resources/Animal1.jpg","/ensemble/samples/shared-resources/Animal2.jpg","/ensemble/samples/shared-resources/Animal3.jpg","/ensemble/samples/scenegraph/events/multitouch/MultiTouchPane.java",},new String[]{"javafx.scene.input.MouseEvent","javafx.event.EventHandler","javafx.scene.input.RotateEvent","javafx.scene.input.ZoomEvent",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/events/multitouch/MultiTouchApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.INPUT_MULTITOUCH,});
-    private static final SampleInfo SAMPLE_121 = new SampleInfo("Custom Node","A sample that demonstrates how to create a custom node by extending the Parent class. ","/Scenegraph/Node/Custom Node","/ensemble/samples/scenegraph/node/customnode","ensemble.samples.scenegraph.node.customnode.CustomNodeApp","/ensemble/samples/scenegraph/node/customnode/preview.png",new String[]{"/ensemble/samples/scenegraph/node/customnode/CustomNodeApp.java","/ensemble/samples/scenegraph/node/customnode/MyNode.java",},new String[]{"javafx.scene.Parent","javafx.scene.Node",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/node/customnode/CustomNodeApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
+    private static final SampleInfo SAMPLE_121 = new SampleInfo("Custom Node","A sample that demonstrates how to create a custom node by extending the Parent class. ","/Scenegraph/Node/Custom Node","/ensemble/samples/scenegraph/node/customnode","ensemble.samples.scenegraph.node.customnode.CustomNodeApp","/ensemble/samples/scenegraph/node/customnode/preview.png",new String[]{"/ensemble/samples/scenegraph/node/customnode/CustomNodeApp.java","/ensemble/samples/scenegraph/node/customnode/CustomNodeApp.java.orig","/ensemble/samples/scenegraph/node/customnode/MyNode.java",},new String[]{"javafx.scene.Parent","javafx.scene.Node",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/node/customnode/CustomNodeApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_122 = new SampleInfo("Node Properties","A sample that demonstrates some properties of nodes. Use the radio buttons to send any of the rectangles to the front or back. Use the controls to change opacity or horizontal position. ","/Scenegraph/Node/Node Properties","/ensemble/samples/scenegraph/node/nodeproperties","ensemble.samples.scenegraph.node.nodeproperties.NodePropertiesApp","/ensemble/samples/scenegraph/node/nodeproperties/preview.png",new String[]{"/ensemble/samples/scenegraph/node/nodeproperties/NodePropertiesApp.java",},new String[]{"javafx.scene.Node",},new String[]{},new String[]{},"/ensemble/samples/scenegraph/node/nodeproperties/NodePropertiesApp.java",new PlaygroundProperty[]{new PlaygroundProperty("rectA","translateX","min","0","max","50","name","Rectangle A translate X"),new PlaygroundProperty("rectB","translateX","min","0","max","50","name","Rectangle B translate X"),new PlaygroundProperty("rectC","translateX","min","0","max","50","name","Rectangle C translate X"),new PlaygroundProperty("rectA","opacity","min","0","max","1","name","Rectangle A Opacity"),new PlaygroundProperty("rectB","opacity","min","0","max","1","name","Rectangle B Opacity"),new PlaygroundProperty("rectC","opacity","min","0","max","1","name","Rectangle C Opacity"),},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_123 = new SampleInfo("Advanced Stage","A sample with a control that creates a transparent stage that is centered on your desktop. You can drag the stage with your mouse or use the scene controls to minimize or close it. With a transparent stage, you must add your own event handlers to perform these actions. ","/Scenegraph/Stage/Advanced Stage","/ensemble/samples/scenegraph/stage/advancedstage","ensemble.samples.scenegraph.stage.advancedstage.AdvancedStageApp","/ensemble/samples/scenegraph/stage/advancedstage/preview.png",new String[]{"/ensemble/samples/scenegraph/stage/advancedstage/AdvancedStageApp.java",},new String[]{"javafx.stage.Stage","javafx.scene.Scene","javafx.stage.StageStyle","javafx.application.Platform",},new String[]{},new String[]{"/Scenegraph/Stage/Stage",},"/ensemble/samples/scenegraph/stage/advancedstage/AdvancedStageApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
     private static final SampleInfo SAMPLE_124 = new SampleInfo("Stage","A sample with a control that creates a decorated stage that is centered on your desktop. ","/Scenegraph/Stage/Stage","/ensemble/samples/scenegraph/stage/stage","ensemble.samples.scenegraph.stage.stage.StageApp","/ensemble/samples/scenegraph/stage/stage/preview.png",new String[]{"/ensemble/samples/scenegraph/stage/stage/StageApp.java",},new String[]{"javafx.stage.Stage","javafx.scene.Scene",},new String[]{},new String[]{"/Scenegraph/Stage/Advanced Stage",},"/ensemble/samples/scenegraph/stage/stage/StageApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{});
@@ -134,18 +134,16 @@
     private static final SampleInfo SAMPLE_127 = new SampleInfo("WebView","A sample that demonstrates a WebView object accessing a web page. ","/Web/WebView","/ensemble/samples/web/webview","ensemble.samples.web.webview.WebViewApp","/ensemble/samples/web/webview/preview.png",new String[]{"/ensemble/samples/web/webview/WebViewApp.java",},new String[]{"javafx.scene.web.WebView","javafx.scene.web.WebEngine",},new String[]{},new String[]{},"/ensemble/samples/web/webview/WebViewApp.java",new PlaygroundProperty[]{},new ConditionalFeature[]{ConditionalFeature.WEB,});
     public static final SampleCategory ROOT = new SampleCategory("ROOT",null,null,new SampleCategory[]{new SampleCategory("Animation",new SampleInfo[]{SAMPLE_0,},new SampleInfo[]{SAMPLE_0,SAMPLE_1,SAMPLE_2,SAMPLE_3,SAMPLE_4,SAMPLE_5,SAMPLE_6,SAMPLE_7,SAMPLE_8,SAMPLE_9,SAMPLE_10,SAMPLE_11,SAMPLE_12,},new SampleCategory[]{new SampleCategory("Timeline",new SampleInfo[]{SAMPLE_1,SAMPLE_2,},null,null),new SampleCategory("Transitions",new SampleInfo[]{SAMPLE_3,SAMPLE_4,SAMPLE_5,SAMPLE_6,SAMPLE_7,SAMPLE_8,SAMPLE_9,SAMPLE_10,SAMPLE_11,SAMPLE_12,},null,null),}),new SampleCategory("Canvas",new SampleInfo[]{SAMPLE_13,},new SampleInfo[]{SAMPLE_13,},null),new SampleCategory("Charts",null,new SampleInfo[]{SAMPLE_14,SAMPLE_15,SAMPLE_16,SAMPLE_17,SAMPLE_18,SAMPLE_19,SAMPLE_20,SAMPLE_21,SAMPLE_22,SAMPLE_23,SAMPLE_24,SAMPLE_25,SAMPLE_26,SAMPLE_27,SAMPLE_28,SAMPLE_29,SAMPLE_30,SAMPLE_31,},new SampleCategory[]{new SampleCategory("Area",new SampleInfo[]{SAMPLE_14,SAMPLE_15,SAMPLE_16,SAMPLE_17,},null,null),new SampleCategory("Bar",new SampleInfo[]{SAMPLE_18,SAMPLE_19,SAMPLE_20,SAMPLE_21,SAMPLE_22,},null,null),new SampleCategory("Bubble",new SampleInfo[]{SAMPLE_23,},null,null),new SampleCategory("Custom",new SampleInfo[]{SAMPLE_24,},null,null),new SampleCategory("Line",new SampleInfo[]{SAMPLE_25,SAMPLE_26,SAMPLE_27,},null,null),new SampleCategory("Pie",new SampleInfo[]{SAMPLE_28,SAMPLE_29,},null,null),new SampleCategory("Scatter",new SampleInfo[]{SAMPLE_30,SAMPLE_31,},null,null),}),new SampleCategory("Concurrency",new SampleInfo[]{SAMPLE_32,SAMPLE_33,},new SampleInfo[]{SAMPLE_32,SAMPLE_33,},null),new SampleCategory("Controls",new SampleInfo[]{SAMPLE_34,SAMPLE_35,SAMPLE_36,SAMPLE_37,SAMPLE_38,SAMPLE_39,SAMPLE_40,SAMPLE_41,SAMPLE_42,SAMPLE_43,SAMPLE_44,SAMPLE_45,SAMPLE_46,},new SampleInfo[]{SAMPLE_34,SAMPLE_47,SAMPLE_48,SAMPLE_49,SAMPLE_35,SAMPLE_36,SAMPLE_37,SAMPLE_38,SAMPLE_50,SAMPLE_51,SAMPLE_52,SAMPLE_39,SAMPLE_40,SAMPLE_41,SAMPLE_42,SAMPLE_43,SAMPLE_44,SAMPLE_53,SAMPLE_54,SAMPLE_55,SAMPLE_56,SAMPLE_57,SAMPLE_58,SAMPLE_59,SAMPLE_60,SAMPLE_61,SAMPLE_62,SAMPLE_45,SAMPLE_63,SAMPLE_64,SAMPLE_46,},new SampleCategory[]{new SampleCategory("Button",new SampleInfo[]{SAMPLE_47,SAMPLE_48,SAMPLE_49,},null,null),new SampleCategory("Listview",new SampleInfo[]{SAMPLE_50,SAMPLE_51,SAMPLE_52,},null,null),new SampleCategory("Splitpane",new SampleInfo[]{SAMPLE_53,},null,null),new SampleCategory("Tab",new SampleInfo[]{SAMPLE_54,},null,null),new SampleCategory("Table",new SampleInfo[]{SAMPLE_55,SAMPLE_56,},null,null),new SampleCategory("Text",new SampleInfo[]{SAMPLE_57,SAMPLE_58,SAMPLE_59,SAMPLE_60,SAMPLE_61,SAMPLE_62,},null,null),new SampleCategory("Toolbar",new SampleInfo[]{SAMPLE_63,SAMPLE_64,},null,null),}),new SampleCategory("Fxml",new SampleInfo[]{SAMPLE_65,},new SampleInfo[]{SAMPLE_65,},null),new SampleCategory("Graphics",new SampleInfo[]{SAMPLE_66,SAMPLE_67,SAMPLE_68,SAMPLE_69,SAMPLE_70,SAMPLE_71,SAMPLE_72,SAMPLE_73,},new SampleInfo[]{SAMPLE_66,SAMPLE_67,SAMPLE_68,SAMPLE_69,SAMPLE_70,SAMPLE_71,SAMPLE_74,SAMPLE_75,SAMPLE_76,SAMPLE_77,SAMPLE_78,SAMPLE_79,SAMPLE_80,SAMPLE_81,SAMPLE_82,SAMPLE_83,SAMPLE_84,SAMPLE_72,SAMPLE_85,SAMPLE_86,SAMPLE_87,SAMPLE_88,SAMPLE_89,SAMPLE_90,SAMPLE_91,SAMPLE_92,SAMPLE_93,SAMPLE_94,SAMPLE_73,},new SampleCategory[]{new SampleCategory("Effects",new SampleInfo[]{SAMPLE_74,SAMPLE_75,SAMPLE_76,SAMPLE_77,SAMPLE_78,},null,null),new SampleCategory("Images",new SampleInfo[]{SAMPLE_79,SAMPLE_80,SAMPLE_81,},null,null),new SampleCategory("Paints",new SampleInfo[]{SAMPLE_82,SAMPLE_83,SAMPLE_84,},null,null),new SampleCategory("Shapes",new SampleInfo[]{SAMPLE_85,SAMPLE_86,SAMPLE_87,SAMPLE_88,SAMPLE_89,SAMPLE_90,SAMPLE_91,SAMPLE_92,SAMPLE_93,SAMPLE_94,},null,null),}),new SampleCategory("Graphics 3d",new SampleInfo[]{SAMPLE_95,SAMPLE_96,SAMPLE_97,SAMPLE_98,},new SampleInfo[]{SAMPLE_95,SAMPLE_96,SAMPLE_97,SAMPLE_98,},null),new SampleCategory("Language",null,new SampleInfo[]{SAMPLE_99,SAMPLE_100,SAMPLE_101,},new SampleCategory[]{new SampleCategory("Beans",new SampleInfo[]{SAMPLE_99,SAMPLE_100,},null,null),new SampleCategory("Collections",new SampleInfo[]{SAMPLE_101,},null,null),}),new SampleCategory("Layout",new SampleInfo[]{SAMPLE_102,SAMPLE_103,SAMPLE_104,SAMPLE_105,SAMPLE_106,SAMPLE_107,SAMPLE_108,SAMPLE_109,},new SampleInfo[]{SAMPLE_102,SAMPLE_103,SAMPLE_104,SAMPLE_105,SAMPLE_106,SAMPLE_107,SAMPLE_108,SAMPLE_109,},null),new SampleCategory("Media",new SampleInfo[]{SAMPLE_110,SAMPLE_111,SAMPLE_112,SAMPLE_113,SAMPLE_114,},new SampleInfo[]{SAMPLE_110,SAMPLE_111,SAMPLE_112,SAMPLE_113,SAMPLE_114,},null),new SampleCategory("Scenegraph",null,new SampleInfo[]{SAMPLE_115,SAMPLE_116,SAMPLE_117,SAMPLE_118,SAMPLE_119,SAMPLE_120,SAMPLE_121,SAMPLE_122,SAMPLE_123,SAMPLE_124,},new SampleCategory[]{new SampleCategory("Events",new SampleInfo[]{SAMPLE_115,SAMPLE_116,SAMPLE_117,SAMPLE_118,SAMPLE_119,SAMPLE_120,},null,null),new SampleCategory("Node",new SampleInfo[]{SAMPLE_121,SAMPLE_122,},null,null),new SampleCategory("Stage",new SampleInfo[]{SAMPLE_123,SAMPLE_124,},null,null),}),new SampleCategory("Swing",new SampleInfo[]{SAMPLE_125,},new SampleInfo[]{SAMPLE_125,},null),new SampleCategory("Web",new SampleInfo[]{SAMPLE_126,SAMPLE_127,},new SampleInfo[]{SAMPLE_126,SAMPLE_127,},null),});
     public static final SampleInfo[] HIGHLIGHTS = new SampleInfo[]{SAMPLE_24,SAMPLE_112,};
-    private static final HashMap<String,SampleInfo[]> DOCS_URL_TO_SAMPLE = new HashMap<String,SampleInfo[]>(177);
+    private static final HashMap<String,SampleInfo[]> DOCS_URL_TO_SAMPLE = new HashMap<String,SampleInfo[]>(168);
     static {
         DOCS_URL_TO_SAMPLE.put("javafx.animation.PauseTransition",new SampleInfo[]{SAMPLE_7,});
         DOCS_URL_TO_SAMPLE.put("java.io.InputStream",new SampleInfo[]{SAMPLE_65,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.layout.GridPane",new SampleInfo[]{SAMPLE_105,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.ScaleTransitionBuilder",new SampleInfo[]{SAMPLE_9,});
         DOCS_URL_TO_SAMPLE.put("javafx.beans.InvalidationListener",new SampleInfo[]{SAMPLE_99,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.paint.RadialGradient",new SampleInfo[]{SAMPLE_84,SAMPLE_66,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.PauseTransitionBuilder",new SampleInfo[]{SAMPLE_7,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.ClosePath",new SampleInfo[]{SAMPLE_90,});
+        DOCS_URL_TO_SAMPLE.put("javafx.scene.control.RadioButton",new SampleInfo[]{SAMPLE_43,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.Scene",new SampleInfo[]{SAMPLE_124,SAMPLE_125,SAMPLE_123,SAMPLE_68,SAMPLE_66,});
-        DOCS_URL_TO_SAMPLE.put("javafx.scene.control.RadioButton",new SampleInfo[]{SAMPLE_43,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.CubicCurve",new SampleInfo[]{SAMPLE_87,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.effect.Lighting",new SampleInfo[]{SAMPLE_73,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.effect.Glow",new SampleInfo[]{SAMPLE_70,});
@@ -156,14 +154,13 @@
         DOCS_URL_TO_SAMPLE.put("javafx.geometry.Rectangle2D",new SampleInfo[]{SAMPLE_67,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.paint.Color",new SampleInfo[]{SAMPLE_90,SAMPLE_91,SAMPLE_92,SAMPLE_93,SAMPLE_82,SAMPLE_86,SAMPLE_98,SAMPLE_85,SAMPLE_84,SAMPLE_83,SAMPLE_95,SAMPLE_94,SAMPLE_89,SAMPLE_97,SAMPLE_88,SAMPLE_96,SAMPLE_87,SAMPLE_68,SAMPLE_66,});
         DOCS_URL_TO_SAMPLE.put("javafx.collections.FXCollections",new SampleInfo[]{SAMPLE_101,SAMPLE_32,SAMPLE_33,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.TranslateTransitionBuilder",new SampleInfo[]{SAMPLE_12,});
         DOCS_URL_TO_SAMPLE.put("javafx.application.Platform",new SampleInfo[]{SAMPLE_123,SAMPLE_67,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.TabPane",new SampleInfo[]{SAMPLE_54,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.ToolBar",new SampleInfo[]{SAMPLE_63,SAMPLE_64,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.media.MediaPlayer",new SampleInfo[]{SAMPLE_114,SAMPLE_113,SAMPLE_111,SAMPLE_18,SAMPLE_110,SAMPLE_14,});
         DOCS_URL_TO_SAMPLE.put("javafx.collections.ObservableList",new SampleInfo[]{SAMPLE_101,SAMPLE_67,SAMPLE_102,SAMPLE_116,});
+        DOCS_URL_TO_SAMPLE.put("javafx.scene.control.ProgressIndicator",new SampleInfo[]{SAMPLE_42,SAMPLE_32,SAMPLE_33,});
         DOCS_URL_TO_SAMPLE.put("java.util.List",new SampleInfo[]{SAMPLE_66,});
-        DOCS_URL_TO_SAMPLE.put("javafx.scene.control.ProgressIndicator",new SampleInfo[]{SAMPLE_42,SAMPLE_32,SAMPLE_33,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.effect.GaussianBlur",new SampleInfo[]{SAMPLE_73,SAMPLE_75,});
         DOCS_URL_TO_SAMPLE.put("javafx.fxml.Initializable",new SampleInfo[]{SAMPLE_65,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.LineTo",new SampleInfo[]{SAMPLE_90,});
@@ -172,11 +169,10 @@
         DOCS_URL_TO_SAMPLE.put("javafx.concurrent.Task",new SampleInfo[]{SAMPLE_32,SAMPLE_33,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.transform.Translate",new SampleInfo[]{SAMPLE_97,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.layout.StackPane",new SampleInfo[]{SAMPLE_107,});
+        DOCS_URL_TO_SAMPLE.put("javafx.scene.chart.PieChart",new SampleInfo[]{SAMPLE_29,SAMPLE_28,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.chart.NumberAxis",new SampleInfo[]{SAMPLE_22,SAMPLE_125,SAMPLE_21,SAMPLE_24,SAMPLE_23,SAMPLE_20,SAMPLE_19,SAMPLE_18,SAMPLE_26,SAMPLE_17,SAMPLE_16,SAMPLE_25,SAMPLE_15,SAMPLE_27,SAMPLE_14,SAMPLE_30,SAMPLE_31,});
-        DOCS_URL_TO_SAMPLE.put("javafx.scene.chart.PieChart",new SampleInfo[]{SAMPLE_29,SAMPLE_28,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.TreeView",new SampleInfo[]{SAMPLE_46,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.MenuBar",new SampleInfo[]{SAMPLE_39,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.StrokeTransitionBuilder",new SampleInfo[]{SAMPLE_11,});
         DOCS_URL_TO_SAMPLE.put("javafx.animation.ParallelTransition",new SampleInfo[]{SAMPLE_5,});
         DOCS_URL_TO_SAMPLE.put("javafx.beans.value.ObservableValue",new SampleInfo[]{SAMPLE_99,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.transform.Shear",new SampleInfo[]{SAMPLE_70,});
@@ -216,7 +212,6 @@
         DOCS_URL_TO_SAMPLE.put("javafx.scene.effect.Reflection",new SampleInfo[]{SAMPLE_77,SAMPLE_66,SAMPLE_71,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.Pagination",new SampleInfo[]{SAMPLE_40,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.web.WebView",new SampleInfo[]{SAMPLE_125,SAMPLE_127,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.PathTransitionBuilder",new SampleInfo[]{SAMPLE_6,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.paint.Stop",new SampleInfo[]{SAMPLE_68,SAMPLE_66,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.Button",new SampleInfo[]{SAMPLE_72,SAMPLE_47,SAMPLE_48,SAMPLE_66,});
         DOCS_URL_TO_SAMPLE.put("javafx.animation.Animation.Status",new SampleInfo[]{SAMPLE_66,});
@@ -243,7 +238,6 @@
         DOCS_URL_TO_SAMPLE.put("javafx.scene.layout.HBox",new SampleInfo[]{SAMPLE_106,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.LabelBuilder",new SampleInfo[]{SAMPLE_58,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.layout.AnchorPane",new SampleInfo[]{SAMPLE_102,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.FadeTransitionBuilder",new SampleInfo[]{SAMPLE_3,});
         DOCS_URL_TO_SAMPLE.put("javafx.animation.Timeline",new SampleInfo[]{SAMPLE_13,SAMPLE_2,SAMPLE_1,SAMPLE_0,SAMPLE_69,SAMPLE_67,SAMPLE_30,SAMPLE_66,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.QuadCurve",new SampleInfo[]{SAMPLE_93,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.chart.CategoryAxis",new SampleInfo[]{SAMPLE_22,SAMPLE_125,SAMPLE_21,SAMPLE_20,SAMPLE_19,SAMPLE_18,SAMPLE_25,});
@@ -290,15 +284,12 @@
         DOCS_URL_TO_SAMPLE.put("javafx.scene.chart.AreaChart",new SampleInfo[]{SAMPLE_16,SAMPLE_15,SAMPLE_14,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.Polygon",new SampleInfo[]{SAMPLE_91,SAMPLE_70,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.Accordion",new SampleInfo[]{SAMPLE_34,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.ParallelTransitionBuilder",new SampleInfo[]{SAMPLE_5,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.VLineTo",new SampleInfo[]{SAMPLE_90,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.Circle",new SampleInfo[]{SAMPLE_86,SAMPLE_73,SAMPLE_13,SAMPLE_69,SAMPLE_66,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.RotateTransitionBuilder",new SampleInfo[]{SAMPLE_8,});
         DOCS_URL_TO_SAMPLE.put("java.util.logging.Level",new SampleInfo[]{SAMPLE_65,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.QuadCurveTo",new SampleInfo[]{SAMPLE_90,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.text.TextAlignment",new SampleInfo[]{SAMPLE_73,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.input.KeyEvent",new SampleInfo[]{SAMPLE_68,SAMPLE_118,SAMPLE_117,SAMPLE_71,});
-        DOCS_URL_TO_SAMPLE.put("javafx.animation.FillTransitionBuilder",new SampleInfo[]{SAMPLE_4,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.canvas.Canvas",new SampleInfo[]{SAMPLE_13,});
         DOCS_URL_TO_SAMPLE.put("javafx.animation.Interpolator",new SampleInfo[]{SAMPLE_0,SAMPLE_66,SAMPLE_118,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.image.ImageView",new SampleInfo[]{SAMPLE_73,SAMPLE_72,SAMPLE_79,SAMPLE_67,SAMPLE_81,SAMPLE_80,});
@@ -309,8 +300,8 @@
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.Shape",new SampleInfo[]{SAMPLE_90,SAMPLE_91,SAMPLE_92,SAMPLE_93,SAMPLE_82,SAMPLE_86,SAMPLE_85,SAMPLE_84,SAMPLE_83,SAMPLE_94,SAMPLE_89,SAMPLE_88,SAMPLE_87,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.Label",new SampleInfo[]{SAMPLE_60,SAMPLE_100,SAMPLE_57,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.SplitPane",new SampleInfo[]{SAMPLE_53,});
+        DOCS_URL_TO_SAMPLE.put("javafx.scene.control.TableColumn",new SampleInfo[]{SAMPLE_55,SAMPLE_56,SAMPLE_32,SAMPLE_33,});
         DOCS_URL_TO_SAMPLE.put("javafx.animation.KeyFrame",new SampleInfo[]{SAMPLE_2,SAMPLE_1,SAMPLE_0,SAMPLE_67,SAMPLE_66,});
-        DOCS_URL_TO_SAMPLE.put("javafx.scene.control.TableColumn",new SampleInfo[]{SAMPLE_55,SAMPLE_56,SAMPLE_32,SAMPLE_33,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.control.ToggleButton",new SampleInfo[]{SAMPLE_49,SAMPLE_45,});
         DOCS_URL_TO_SAMPLE.put("javafx.scene.shape.ArcTo",new SampleInfo[]{SAMPLE_90,});
     }
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/fadetransition/FadeTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/fadetransition/FadeTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -32,7 +32,6 @@
 package ensemble.samples.animation.transitions.fadetransition;
 
 import javafx.animation.FadeTransition;
-import javafx.animation.FadeTransitionBuilder;
 import javafx.animation.Timeline;
 import javafx.application.Application;
 import javafx.scene.Parent;
@@ -49,7 +48,6 @@
  * @sampleName Fade Transition
  * @preview preview.png
  * @see javafx.animation.FadeTransition
- * @see javafx.animation.FadeTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fill Transition
  * @related /Animation/Transitions/Parallel Transition
@@ -77,15 +75,12 @@
         rect.setFill(Color.DODGERBLUE);
         root.getChildren().add(rect);
 
-        fadeTransition = FadeTransitionBuilder.create()
-                .duration(Duration.seconds(4))
-                .node(rect)
-                .fromValue(1)
-                .toValue(0.2)
-                .cycleCount(Timeline.INDEFINITE)
-                .autoReverse(true)
-                .build();
-
+        fadeTransition = new FadeTransition(Duration.seconds(4), rect);
+        fadeTransition.setFromValue(1);
+        fadeTransition.setToValue(0.2);
+        fadeTransition.setCycleCount(Timeline.INDEFINITE);
+        fadeTransition.setAutoReverse(true);
+        
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/filltransition/FillTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/filltransition/FillTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -32,7 +32,6 @@
 package ensemble.samples.animation.transitions.filltransition;
 
 import javafx.animation.FillTransition;
-import javafx.animation.FillTransitionBuilder;
 import javafx.animation.Timeline;
 import javafx.application.Application;
 import javafx.scene.Parent;
@@ -49,7 +48,6 @@
  * @sampleName Fill Transition
  * @preview preview.png
  * @see javafx.animation.FillTransition
- * @see javafx.animation.FillTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fade Transition
  * @related /Animation/Transitions/Parallel Transition
@@ -77,14 +75,9 @@
         rect.setFill(Color.DODGERBLUE);
         root.getChildren().add(rect);
         
-        fillTransition = FillTransitionBuilder.create()
-            .duration(Duration.seconds(3))
-            .shape(rect)
-            .fromValue(Color.RED)
-            .toValue(Color.DODGERBLUE)
-            .cycleCount(Timeline.INDEFINITE)
-            .autoReverse(true)
-            .build();
+        fillTransition = new FillTransition(Duration.seconds(3), rect, Color.RED, Color.DODGERBLUE);
+        fillTransition.setCycleCount(Timeline.INDEFINITE);
+        fillTransition.setAutoReverse(true);
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/paralleltransition/ParallelTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/paralleltransition/ParallelTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -31,13 +31,12 @@
  */
 package ensemble.samples.animation.transitions.paralleltransition;
 
-import javafx.animation.FadeTransitionBuilder;
+import javafx.animation.FadeTransition;
 import javafx.animation.ParallelTransition;
-import javafx.animation.ParallelTransitionBuilder;
-import javafx.animation.RotateTransitionBuilder;
-import javafx.animation.ScaleTransitionBuilder;
+import javafx.animation.RotateTransition;
+import javafx.animation.ScaleTransition;
 import javafx.animation.Timeline;
-import javafx.animation.TranslateTransitionBuilder;
+import javafx.animation.TranslateTransition;
 import javafx.application.Application;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
@@ -53,7 +52,6 @@
  * @sampleName Parallel Transition
  * @preview preview.png
  * @see javafx.animation.ParallelTransition
- * @see javafx.animation.ParallelTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fade Transition
  * @related /Animation/Transitions/Fill Transition
@@ -71,7 +69,7 @@
 
     public Parent createContent() {
         Pane root = new Pane();
-        root.setPrefSize(245, 100);
+        root.setPrefSize(400, 200);
         root.setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
         root.setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
 
@@ -82,41 +80,34 @@
         rect.setTranslateX(50);
         rect.setTranslateY(75);
         root.getChildren().add(rect); 
-        // create parallel transition to do all 4 transitions at the same time        
-        parallelTransition = ParallelTransitionBuilder.create()
-            .node(rect)
-            .children(
-                FadeTransitionBuilder.create()
-                    .duration(Duration.seconds(3))
-                    .node(rect)
-                    .fromValue(1)
-                    .toValue(0.3)
-                    .autoReverse(true)
-                    .build(),
-                TranslateTransitionBuilder.create()
-                    .duration(Duration.seconds(2))
-                    .fromX(50)
-                    .toX(350)
-                    .cycleCount(2)
-                    .autoReverse(true)
-                    .build(),
-                RotateTransitionBuilder.create()
-                    .duration(Duration.seconds(3))
-                    .byAngle(180)
-                    .cycleCount(4)
-                    .autoReverse(true)
-                    .build(),
-                ScaleTransitionBuilder.create()
-                    .duration(Duration.seconds(2))
-                    .toX(2)
-                    .toY(2)
-                    .cycleCount(2)
-                    .autoReverse(true)
-                    .build()
-            )
-            .cycleCount(Timeline.INDEFINITE)
-            .autoReverse(true)
-            .build();
+        // create parallel transition to do all 4 transitions at the same time
+        FadeTransition fadeTrans = new FadeTransition(Duration.seconds(3), rect);
+        fadeTrans.setFromValue(1);
+        fadeTrans.setToValue(0.3);
+        fadeTrans.setAutoReverse(true);
+        
+        TranslateTransition translateTran = new TranslateTransition(Duration.seconds(2));
+        translateTran.setFromX(50);
+        translateTran.setToX(320);
+        translateTran.setCycleCount(2);
+        translateTran.setAutoReverse(true);
+        
+        RotateTransition rotateTran = new RotateTransition(Duration.seconds(3));
+        rotateTran.setByAngle(180);
+        rotateTran.setCycleCount(4);
+        rotateTran.setAutoReverse(true);
+        
+        ScaleTransition scaleTran = new ScaleTransition(Duration.seconds(2));
+        scaleTran.setToX(2);
+        scaleTran.setToY(2);
+        scaleTran.setCycleCount(2);
+        scaleTran.setAutoReverse(true);
+
+        parallelTransition = new ParallelTransition(rect, fadeTrans,
+                translateTran, rotateTran, scaleTran);
+        parallelTransition.setCycleCount(Timeline.INDEFINITE);
+        parallelTransition.setAutoReverse(true);
+        
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/pathtransition/PathTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/pathtransition/PathTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -32,7 +32,6 @@
 package ensemble.samples.animation.transitions.pathtransition;
 
 import javafx.animation.PathTransition;
-import javafx.animation.PathTransitionBuilder;
 import javafx.animation.Timeline;
 import javafx.application.Application;
 import javafx.scene.Parent;
@@ -42,10 +41,9 @@
 import javafx.scene.shape.CubicCurveTo;
 import javafx.scene.shape.MoveTo;
 import javafx.scene.shape.Path;
-import javafx.scene.shape.PathBuilder;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
-import javafx.util.Duration;
+import static javafx.util.Duration.seconds;
 
 /**
  * A sample in which a node moves along a path from end to end over a given time.
@@ -53,7 +51,6 @@
  * @sampleName Path Transition
  * @preview preview.png
  * @see javafx.animation.PathTransition
- * @see javafx.animation.PathTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fade Transition
  * @related /Animation/Transitions/Fill Transition
@@ -71,7 +68,7 @@
 
     public Parent createContent() {
         Pane root = new Pane();
-        root.setPrefSize(245, 100);
+        root.setPrefSize(280, 190);
         root.setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
         root.setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);        
 
@@ -80,24 +77,18 @@
         rect.setArcWidth(10);
         rect.setFill(Color.ORANGE);
         root.getChildren().add(rect);
-        Path path = PathBuilder.create()
-                .elements(
-                new MoveTo(20, 20),
-                new CubicCurveTo(380, 0, 220, 120, 120, 80),
-                new CubicCurveTo(0, 40, 0, 240, 220, 120))
-                .build();
+        Path path = new Path(new MoveTo(20, 20), 
+                new CubicCurveTo(380, 0, 220, 120, 120, 80), 
+                new CubicCurveTo(0, 40, 0, 240, 220, 120));
         path.setStroke(Color.DODGERBLUE);
         path.getStrokeDashArray().setAll(5d, 5d);
         root.getChildren().add(path);
 
-        pathTransition = PathTransitionBuilder.create()
-                .duration(Duration.seconds(4))
-                .path(path)
-                .node(rect)
-                .orientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT)
-                .cycleCount(Timeline.INDEFINITE)
-                .autoReverse(true)
-                .build();
+        pathTransition = new PathTransition(seconds(4), path, rect);
+        pathTransition.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
+        pathTransition.setCycleCount(Timeline.INDEFINITE);
+        pathTransition.setAutoReverse(true);
+        
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/pausetransition/PauseTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/pausetransition/PauseTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -32,10 +32,10 @@
 package ensemble.samples.animation.transitions.pausetransition;
 
 import javafx.animation.Animation;
-import javafx.animation.PauseTransitionBuilder;
-import javafx.animation.SequentialTransitionBuilder;
+import javafx.animation.PauseTransition;
+import javafx.animation.SequentialTransition;
 import javafx.animation.Timeline;
-import javafx.animation.TranslateTransitionBuilder;
+import javafx.animation.TranslateTransition;
 import javafx.application.Application;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
@@ -43,7 +43,7 @@
 import javafx.scene.paint.Color;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
-import javafx.util.Duration;
+import static javafx.util.Duration.seconds;
 
 /**
  * A sample in which a node pauses over a given time.
@@ -51,7 +51,6 @@
  * @sampleName Pause Transition
  * @preview preview.png
  * @see javafx.animation.PauseTransition
- * @see javafx.animation.PauseTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fade Transition
  * @related /Animation/Transitions/Fill Transition
@@ -81,25 +80,20 @@
         rect.setTranslateY(75);
         root.getChildren().add(rect);
 
-        animation = SequentialTransitionBuilder.create()
-                .node(rect)
-                .children(
-                TranslateTransitionBuilder.create()
-                .duration(Duration.seconds(2))
-                .fromX(50)
-                .toX(150)
-                .build(),
-                PauseTransitionBuilder.create()
-                .duration(Duration.seconds(2))
-                .build(),
-                TranslateTransitionBuilder.create()
-                .duration(Duration.seconds(2))
-                .fromX(150)
-                .toX(200)
-                .build())
-                .cycleCount(Timeline.INDEFINITE)
-                .autoReverse(true)
-                .build();
+        TranslateTransition translateTrans1 = new TranslateTransition(seconds(2));
+        translateTrans1.setFromX(50);
+        translateTrans1.setToX(150);
+        
+        PauseTransition pauseTrans = new PauseTransition(seconds(2));
+           
+        TranslateTransition translateTrans2 = new TranslateTransition(seconds(2));
+        translateTrans2.setFromX(150);
+        translateTrans2.setToX(200);
+        
+        animation = new SequentialTransition(rect, translateTrans1, pauseTrans, translateTrans2);
+        animation.setCycleCount(Timeline.INDEFINITE);
+        animation.setAutoReverse(true);
+ 
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/rotatetransition/RotateTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/rotatetransition/RotateTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -32,7 +32,6 @@
 package ensemble.samples.animation.transitions.rotatetransition;
 
 import javafx.animation.RotateTransition;
-import javafx.animation.RotateTransitionBuilder;
 import javafx.animation.Timeline;
 import javafx.application.Application;
 import javafx.scene.Parent;
@@ -49,7 +48,6 @@
  * @sampleName Rotate Transition
  * @preview preview.png
  * @see javafx.animation.RotateTransition
- * @see javafx.animation.RotateTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fade Transition
  * @related /Animation/Transitions/Fill Transition
@@ -67,7 +65,7 @@
 
     public Parent createContent() {
         Pane root = new Pane();
-        root.setPrefSize(245, 100);
+        root.setPrefSize(140, 140);
         root.setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
         root.setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
         // create rectangle
@@ -77,14 +75,12 @@
         rect.setFill(Color.ORANGE);
         root.getChildren().add(rect);
 
-        rotateTransition = RotateTransitionBuilder.create()
-                .node(rect)
-                .duration(Duration.seconds(4))
-                .fromAngle(0)
-                .toAngle(720)
-                .cycleCount(Timeline.INDEFINITE)
-                .autoReverse(true)
-                .build();
+        rotateTransition = new RotateTransition(Duration.seconds(4), rect);
+        rotateTransition.setFromAngle(0);
+        rotateTransition.setToAngle(720);
+        rotateTransition.setCycleCount(Timeline.INDEFINITE);
+        rotateTransition.setAutoReverse(true);
+        
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/scaletransition/ScaleTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/scaletransition/ScaleTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -32,7 +32,6 @@
 package ensemble.samples.animation.transitions.scaletransition;
 
 import javafx.animation.ScaleTransition;
-import javafx.animation.ScaleTransitionBuilder;
 import javafx.animation.Timeline;
 import javafx.application.Application;
 import javafx.scene.Parent;
@@ -49,10 +48,9 @@
  * @sampleName Scale Transition
  * @preview preview.png
  * @see javafx.animation.ScaleTransition
- * @see javafx.animation.ScaleTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fade Transition
- * @related /Aimation/Transitions/Fill Transition
+ * @related /Animation/Transitions/Fill Transition
  * @related /Animation/Transitions/Parallel Transition
  * @related /Animation/Transitions/Path Transition
  * @related /Animation/Transitions/Pause Transition
@@ -67,7 +65,7 @@
 
     public Parent createContent() {
         Pane root = new Pane();
-        root.setPrefSize(245, 100);
+        root.setPrefSize(180, 180);
         root.setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
         root.setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
         
@@ -76,14 +74,12 @@
         rect.setArcWidth(15);
         rect.setFill(Color.ORANGE);
         root.getChildren().add(rect);
-        scaleTransition = ScaleTransitionBuilder.create()
-                .node(rect)
-                .duration(Duration.seconds(4))
-                .toX(3)
-                .toY(3)
-                .cycleCount(Timeline.INDEFINITE)
-                .autoReverse(true)
-                .build();
+        scaleTransition = new ScaleTransition(Duration.seconds(4), rect);
+        scaleTransition.setToX(3);
+        scaleTransition.setToY(3);
+        scaleTransition.setCycleCount(Timeline.INDEFINITE);
+        scaleTransition.setAutoReverse(true);
+        
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/stroketransition/StrokeTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/stroketransition/StrokeTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -32,7 +32,6 @@
 package ensemble.samples.animation.transitions.stroketransition;
 
 import javafx.animation.StrokeTransition;
-import javafx.animation.StrokeTransitionBuilder;
 import javafx.animation.Timeline;
 import javafx.application.Application;
 import javafx.scene.Parent;
@@ -49,7 +48,6 @@
  * @sampleName Stroke Transition
  * @preview preview.png
  * @see javafx.animation.StrokeTransition
- * @see javafx.animation.StrokeTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fade Transition
  * @related /Animation/Transitions/Fill Transition
@@ -67,7 +65,7 @@
 
     public Parent createContent() {
         Pane root = new Pane();
-        root.setPrefSize(245, 100);
+        root.setPrefSize(200, 200);
         root.setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
         root.setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);       
         
@@ -79,14 +77,10 @@
         rect.setStrokeWidth(10);
         root.getChildren().add(rect);
 
-        strokeTransition = StrokeTransitionBuilder.create()
-                .duration(Duration.seconds(3))
-                .shape(rect)
-                .fromValue(Color.RED)
-                .toValue(Color.DODGERBLUE)
-                .cycleCount(Timeline.INDEFINITE)
-                .autoReverse(true)
-                .build();
+        strokeTransition = new StrokeTransition(Duration.seconds(3), rect, Color.RED, Color.DODGERBLUE);
+        strokeTransition.setCycleCount(Timeline.INDEFINITE);
+        strokeTransition.setAutoReverse(true);
+
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/translatetransition/TranslateTransitionApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/transitions/translatetransition/TranslateTransitionApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -33,7 +33,6 @@
 
 import javafx.animation.Timeline;
 import javafx.animation.TranslateTransition;
-import javafx.animation.TranslateTransitionBuilder;
 import javafx.application.Application;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
@@ -50,7 +49,6 @@
  * @sampleName Translate Transition
  * @preview preview.png
  * @see javafx.animation.TranslateTransition
- * @see javafx.animation.TranslateTransitionBuilder
  * @see javafx.animation.Transition
  * @related /Animation/Transitions/Fade Transition
  * @related /Animation/Transitions/Fill Transition
@@ -76,14 +74,12 @@
         circle.setTranslateX(20);
         circle.setTranslateY(20);
         root.getChildren().add(circle);
-        translateTransition = TranslateTransitionBuilder.create()
-                .duration(Duration.seconds(4))
-                .node(circle)
-                .fromX(20)
-                .toX(220)
-                .cycleCount(Timeline.INDEFINITE)
-                .autoReverse(true)
-                .build();
+        translateTransition = new TranslateTransition(Duration.seconds(4), circle);
+        translateTransition.setFromX(20);
+        translateTransition.setToX(220);
+        translateTransition.setCycleCount(Timeline.INDEFINITE);
+        translateTransition.setAutoReverse(true);
+ 
         return root;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/menu/MenuApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/menu/MenuApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -119,7 +119,7 @@
         if (os != null && os.startsWith("Mac")) {
             Menu systemMenuBarMenu = new Menu("MenuBar Options");
 
-            final CheckMenuItem useSystemMenuBarCB = new CheckMenuItem("Use System Menu Bar");
+            final CheckMenuItem useSystemMenuBarCB = new CheckMenuItem("Use System Menu Bar (works only when MenuApp is run outside of Ensemble)");
             useSystemMenuBarCB.setSelected(true);
             menuBar.useSystemMenuBarProperty().bind(useSystemMenuBarCB.selectedProperty());
             systemMenuBarMenu.getItems().add(useSystemMenuBarCB);
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/progressindicator/ProgressIndicatorApp.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/controls/progressindicator/ProgressIndicatorApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -31,13 +31,19 @@
  */
 package ensemble.samples.controls.progressindicator;
 
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
 import javafx.application.Application;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
 import javafx.geometry.Pos;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
 import javafx.scene.control.ProgressIndicator;
 import javafx.scene.layout.GridPane;
 import javafx.stage.Stage;
+import javafx.util.Duration;
 
 /**
  * A sample that demonstrates the Progress Indicator control in various modes.
@@ -48,7 +54,8 @@
  * @related /Controls/Progress Bar
  */
 public class ProgressIndicatorApp extends Application {
-
+    final Timeline timeline = new Timeline();
+    
     public Parent createContent() {
         GridPane g = new GridPane();
 
@@ -66,22 +73,54 @@
         ProgressIndicator p4 = new ProgressIndicator();
         p4.setPrefSize(50, 50);
         p4.setProgress(1.0F);
+        
+        // styled ProgressIndicator
+        final ProgressIndicator p5 = new ProgressIndicator();
+        p5.setPrefSize(100, 100);
+        p5.progressProperty().addListener(new ChangeListener<Number>() {
+            @Override
+            public void changed(ObservableValue ov, Number oldVal, Number newVal) {
+                if (p5.getProgress() < 0.25) {
+                    p5.setStyle("-fx-progress-color: red;");
+                } else if (p5.getProgress() < 0.5) {
+                    p5.setStyle("-fx-progress-color: orange;");
+                } else {
+                    p5.setStyle("-fx-progress-color: green;");
+                }
+            }
+        });
+        // animate the styled ProgressIndicator
+        timeline.setCycleCount(Timeline.INDEFINITE);
+        timeline.setAutoReverse(true);
+        final KeyValue kv = new KeyValue(p5.progressProperty(), 1);
+        final KeyFrame kf1 = new KeyFrame(Duration.millis(3000), kv);
+        timeline.getKeyFrames().add(kf1);
 
         g.add(p1, 1, 0);
         g.add(p2, 0, 1);
         g.add(p3, 1, 1);
         g.add(p4, 2, 1);
+        g.add(p5, 1, 2);
 
-        g.setHgap(40);
-        g.setVgap(40);
+        g.setHgap(20);
+        g.setVgap(20);
         g.setAlignment(Pos.CENTER);
         return g;
     }
 
+    public void play() {
+        timeline.play();
+    }
+    @Override
+    public void stop() {
+        timeline.stop();
+    }
+    
     @Override
     public void start(Stage primaryStage) throws Exception {
         primaryStage.setScene(new Scene(createContent()));
         primaryStage.show();
+        play();
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/SpecularColorTestApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,115 @@
+/*
+ * 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 fx83dfeatures;
+
+import javafx.application.Application;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.Group;
+import javafx.scene.PerspectiveCamera;
+import javafx.scene.Scene;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.ScrollBar;
+import javafx.scene.image.Image;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.PhongMaterial;
+import javafx.scene.shape.Sphere;
+import javafx.stage.Stage;
+
+public class SpecularColorTestApp extends Application {
+
+    private ScrollBar specularPowerScroll;
+    private ColorPicker specularColorPicker;
+    private CheckBox specularMapCheckBox;
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        final Image diffuseMap = new Image("resources/cup_diffuseMap_1024.png");
+        final PhongMaterial material = new PhongMaterial(Color.ANTIQUEWHITE);
+
+        final Sphere s = new Sphere();
+        s.setScaleX(100);
+        s.setScaleY(100);
+        s.setScaleZ(100);
+        s.setMaterial(material);
+        s.setTranslateX(150);
+        s.setTranslateY(250);
+
+        final Sphere s1 = new Sphere(2);
+        s1.setScaleX(100);
+        s1.setScaleY(100);
+        s1.setScaleZ(100);
+        s1.setMaterial(material);
+        s1.setTranslateX(500);
+        s1.setTranslateY(250);
+
+        Group root1 = new Group(s, s1);
+        specularPowerScroll = new ScrollBar();
+        specularPowerScroll.setValue(material.getSpecularPower());
+        specularPowerScroll.setMin(0);
+        specularPowerScroll.setMax(1);
+        specularPowerScroll.valueProperty().addListener(new ChangeListener<Number>() {
+            @Override
+            public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
+                material.setSpecularPower(t1.doubleValue());
+                System.out.println("power changed " + t1.doubleValue());
+            }
+        });
+
+        specularColorPicker = new ColorPicker(material.getSpecularColor());
+        specularColorPicker.valueProperty().addListener(new ChangeListener<Color>() {
+            @Override
+            public void changed(ObservableValue<? extends Color> ov, Color t, Color t1) {
+                material.setSpecularColor(t1);
+                System.out.println("color changed " + t1);
+            }
+        });
+
+        specularMapCheckBox = new CheckBox("Specular Map");
+        specularMapCheckBox.setSelected(false);
+        specularMapCheckBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
+
+            @Override
+            public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
+                material.setSpecularMap(t1 ? diffuseMap : null);
+            }
+        });
+        VBox controls = new VBox(15);
+        controls.getChildren().addAll(specularColorPicker, specularPowerScroll, specularMapCheckBox);
+
+        Group root = new Group(root1, controls);
+        Scene scene = new Scene(root, 800, 500, true);
+
+        scene.setCamera(new PerspectiveCamera());
+        stage.setScene(scene);
+        stage.show();
+    }
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/WritableMapTestApp.java	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,208 @@
+/*
+ * 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 fx83dfeatures;
+
+import javafx.application.Application;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.Group;
+import javafx.scene.PerspectiveCamera;
+import javafx.scene.Scene;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.image.PixelReader;
+import javafx.scene.image.PixelWriter;
+import javafx.scene.image.WritableImage;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.PhongMaterial;
+import javafx.scene.shape.Sphere;
+import javafx.stage.Stage;
+
+public class WritableMapTestApp extends Application {
+
+    private ColorPicker diffuseMapPicker;
+    private CheckBox diffuseMapCheckBox;
+    private ColorPicker specularMapPicker;
+    private CheckBox specularMapCheckBox;
+    private ColorPicker selfIllumMapPicker;
+    private CheckBox selfIllumMapCheckBox;
+    
+
+    private Image generateMap(WritableImage writableImage, Image map) {
+        PixelReader pixelReader = map.getPixelReader();
+        
+        //Copy from source to destination pixel by pixel
+        PixelWriter pixelWriter = writableImage.getPixelWriter();
+
+        for (int y = 0; y < writableImage.getHeight(); y++) {
+            for (int x = 0; x < writableImage.getWidth(); x++) {
+                Color color = pixelReader.getColor(x, y);
+                pixelWriter.setColor(x, y, color);
+            }
+        }
+        return writableImage;
+    }
+
+    private Image generateMap(WritableImage writableImage, Color color) {
+        //Copy from source to destination pixel by pixel
+        PixelWriter pixelWriter = writableImage.getPixelWriter();
+
+        for (int y = 0; y < writableImage.getHeight(); y++) {
+            for (int x = 0; x < writableImage.getWidth(); x++) {
+                pixelWriter.setColor(x, y, color);
+            }
+        }
+        return writableImage;
+    }
+    
+    @Override
+    public void start(Stage stage) throws Exception {
+
+        int width = 100;
+        int height = 100;
+        final WritableImage diffuseMap = new WritableImage(width, height);
+        final WritableImage specularMap = new WritableImage(width, height);
+        final WritableImage selfIllumMap = new WritableImage(width, height);
+        generateMap(diffuseMap, Color.RED);
+        generateMap(specularMap, Color.ANTIQUEWHITE);
+
+        final PhongMaterial sharedMaterial = new PhongMaterial();
+        final PhongMaterial sharedMapMaterial = new PhongMaterial();
+        sharedMapMaterial.setDiffuseMap(diffuseMap);
+        sharedMapMaterial.setSpecularMap(specularMap);
+
+        final Sphere sharedMatSphere = new Sphere();
+        sharedMatSphere.setScaleX(100);
+        sharedMatSphere.setScaleY(100);
+        sharedMatSphere.setScaleZ(100);
+        sharedMatSphere.setMaterial(sharedMaterial);
+        sharedMatSphere.setTranslateX(150);
+        sharedMatSphere.setTranslateY(400);
+
+        final Sphere sharedMatSphere1 = new Sphere();
+        sharedMatSphere1.setScaleX(100);
+        sharedMatSphere1.setScaleY(100);
+        sharedMatSphere1.setScaleZ(100);
+        sharedMatSphere1.setMaterial(sharedMaterial);
+        sharedMatSphere1.setTranslateX(400);
+        sharedMatSphere1.setTranslateY(400);
+
+        final Sphere sharedMapSphere = new Sphere(2);
+        sharedMapSphere.setScaleX(100);
+        sharedMapSphere.setScaleY(100);
+        sharedMapSphere.setScaleZ(100);
+        sharedMapSphere.setMaterial(sharedMapMaterial);
+        sharedMapSphere.setTranslateX(750);
+        sharedMapSphere.setTranslateY(400);
+        
+        Group root1 = new Group(sharedMatSphere, sharedMatSphere1, sharedMapSphere);
+        
+        diffuseMapPicker = new ColorPicker(Color.RED);
+        diffuseMapPicker.valueProperty().addListener(new ChangeListener<Color>() {
+            @Override
+            public void changed(ObservableValue<? extends Color> ov, Color t, Color t1) {
+                generateMap(diffuseMap, t1);
+            }
+        });
+
+        diffuseMapCheckBox = new CheckBox("Set Diffuse Map for left two spheres");
+        diffuseMapCheckBox.setSelected(false);
+        diffuseMapCheckBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
+
+            @Override
+            public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
+                sharedMaterial.setDiffuseMap(t1 ? diffuseMap : null);
+            }
+        });
+
+        specularMapPicker = new ColorPicker(Color.ANTIQUEWHITE);
+        specularMapPicker.valueProperty().addListener(new ChangeListener<Color>() {
+            @Override
+            public void changed(ObservableValue<? extends Color> ov, Color t, Color t1) {
+                generateMap(specularMap, t1);
+            }
+        });
+
+        specularMapCheckBox = new CheckBox("Set Specular Map for left two spheres");
+        specularMapCheckBox.setSelected(false);
+        specularMapCheckBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
+
+            @Override
+            public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
+                sharedMaterial.setSpecularMap(t1 ? specularMap : null);
+            }
+        });
+
+        selfIllumMapPicker = new ColorPicker();
+        selfIllumMapPicker.valueProperty().addListener(new ChangeListener<Color>() {
+            @Override
+            public void changed(ObservableValue<? extends Color> ov, Color t, Color t1) {
+                generateMap(selfIllumMap, t1);
+            }
+        });
+
+        selfIllumMapCheckBox = new CheckBox("Set SelfIllumination Map for left two spheres");
+        selfIllumMapCheckBox.setSelected(false);
+        selfIllumMapCheckBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
+
+            @Override
+            public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
+                sharedMapMaterial.setSelfIlluminationMap(selfIllumMap);
+                sharedMaterial.setSelfIlluminationMap(t1 ? selfIllumMap : null);
+            }
+        });
+
+        HBox labelBox = new HBox(20);
+        labelBox.getChildren().add(new Label("NOTE: Writable image will be generated based on selected color. In other words, Texture Map is used instead of Color."));
+
+        HBox diffuseBox = new HBox(20);
+        diffuseBox.getChildren().addAll(diffuseMapPicker, diffuseMapCheckBox);
+        
+        HBox specularBox = new HBox(20);
+        specularBox.getChildren().addAll(specularMapPicker, specularMapCheckBox);
+        
+        HBox selfIllumBox = new HBox(20);
+        selfIllumBox.getChildren().addAll(selfIllumMapPicker, selfIllumMapCheckBox);
+        
+        VBox controls = new VBox(20);
+        controls.getChildren().addAll(labelBox, diffuseBox, specularBox, selfIllumBox);
+        
+        Group root = new Group(root1, controls);
+        Scene scene = new Scene(root, 1000, 650, true);
+
+        scene.setCamera(new PerspectiveCamera());
+        stage.setScene(scene);
+        stage.show();
+    }
+    
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
Binary file apps/toys/FX8-3DFeatures/src/resources/cup_diffuseMap_1024.png has changed
--- a/build.gradle	Tue Aug 20 08:59:55 2013 -0400
+++ b/build.gradle	Tue Aug 20 09:38:00 2013 -0700
@@ -691,9 +691,15 @@
     def nativeTask = project.task("native$capitalName", group: "Build") {
         description = "Generates JNI headers, compiles, and builds native dynamic library for $name for all compile targets"
     }
+    def cleanTask = project.task("cleanNative$capitalName", type: Delete, group: "Build") {
+        description = "Clean native objects for $name"
+    }
+    if (project.hasProperty("nativeAllTask")) project.nativeAllTask.dependsOn nativeTask
     if (!optional) {
         project.assemble.dependsOn(nativeTask)
     }
+    if (project.hasProperty("cleanNativeAllTask")) project.cleanNativeAllTask.dependsOn cleanTask
+    
     // Each of the different compile targets will be placed in a sub directory
     // of these root dirs, with the name of the dir being the name of the target
     def headerRootDir = project.file("$project.buildDir/generated-src/headers/$name")
@@ -731,28 +737,33 @@
         variants.each { variant ->
             def variantProperties = variant == "" ? properties : properties.get(variant)
             def capitalVariant = variant.capitalize()
+            def ccOutput = variant == "" ? nativeDir : file("$nativeDir/$variant")
             def ccTask = project.task("cc${t.capital}$capitalName$capitalVariant", type: CCTask, dependsOn: javahTask, group: "Build") {
                 description = "Compiles native sources for ${name} for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
                 matches = ".*\\.c|.*\\.cpp|.*\\.m|.*\\.cc"
                 headers = headerDir
-                output(variant == "" ? nativeDir : file("$nativeDir/$variant"))
+                output(ccOutput)
                 params.addAll(variantProperties.ccFlags)
                 compiler = variantProperties.compiler
                 source(variantProperties.nativeSource)
+                cleanTask.delete ccOutput
             }
             def linkTask = project.task("link${t.capital}$capitalName$capitalVariant", type: LinkTask, dependsOn: ccTask, group: "Build") {
                 description = "Creates native dynamic library for $name for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
-                objectDir = variant == "" ? nativeDir : file("$nativeDir/$variant")
+                objectDir = ccOutput
                 linkParams.addAll(variantProperties.linkFlags)
                 lib = file("$libRootDir/${t.name}/${variant == '' ? library(properties.lib) : library(variantProperties.lib)}")
                 linker = variantProperties.linker
+                cleanTask.delete "$libRootDir/${t.name}"
             }
             nativeTask.dependsOn(linkTask)
             if (IS_WINDOWS && t.name == "win") {
                 def rcTask = project.task("rc$capitalName$capitalVariant", type: CompileResourceTask, dependsOn: javahTask, group: "Build") {
                     description = "Compiles native sources for $name"
                     matches = ".*\\.rc|.*\\.cur"
-                    output(file("$nativeRootDir/win"))
+                    def rcOutput = file("$nativeRootDir/win")
+                    output(rcOutput)
+                    cleanTask.delete rcOutput
                 }
                 linkTask.dependsOn rcTask;
             }
@@ -1042,6 +1053,10 @@
         antlr3 group: "org.antlr", name: "antlr-runtime",  version: "3.1.3"
         antlr3 group: "org.antlr", name: "stringtemplate", version: "3.2"
     }
+    
+    // Create a single "native" task which will depend on all the individual native tasks for graphics
+    project.ext.nativeAllTask = task("native", group: "Build", description: "Compiles and Builds all native libraries for Graphics");
+    project.ext.cleanNativeAllTask = task("cleanNative", group: "Build", description: "Clean all native libraries and objects for Graphics");
 
     // Add tasks for native compilation
     addNative(project, "glass");
@@ -1185,7 +1200,12 @@
         output = file("$buildDir/generated-src/headers/jsl-decora")
     }
 
-    task nativeDecora(dependsOn: compileDecoraHLSLShaders);
+    task nativeDecora(dependsOn: compileDecoraHLSLShaders, group: "Build") {
+        description = "Generates JNI headers, compiles, and builds native dynamic library for Decora"
+    }
+    task cleanNativeDecora(type: Delete, group: "Build") {
+        description = "Clean native objects for Decora"
+    }
 
     def headerDir = file("$buildDir/generated-src/headers/jsl-decora")
     def nativeRootDir = project.file("$project.buildDir/native/jsl-decora")
@@ -1207,6 +1227,7 @@
             params.addAll(properties.decora.ccFlags)
             output(file("$nativeRootDir/$target"))
             compiler = properties.decora.compiler
+            cleanNativeDecora.delete file("$nativeRootDir/$target")
         }
 
         def linkTask = task("linkDecoraNativeShaders$capitalTarget", type: LinkTask, dependsOn: ccTask) {
@@ -1215,6 +1236,7 @@
             linkParams.addAll(properties.decora.linkFlags)
             lib = file("$libRootDir/$t.name/${library(properties.decora.lib)}")
             linker = properties.decora.linker
+            cleanNativeDecora.delete "$libRootDir/$t.name/"
         }
 
         nativeDecora.dependsOn(linkTask)
@@ -1240,11 +1262,8 @@
     classes.dependsOn compilePrismJavaShaders;
     nativePrism.dependsOn compilePrismHLSLShaders;
 
-    // Create a single "native" task which will depend on all the individual native tasks for graphics
-    task("native", dependsOn: [nativeGlass, nativePrism, nativePrismSW, nativeDecora]) {
-        group = "Build"
-        description = "Compiles and Builds all native libraries for Graphics"
-    }
+    project.nativeAllTask.dependsOn nativeDecora
+    project.cleanNativeAllTask.dependsOn cleanNativeDecora
     assemble.dependsOn nativeDecora
     processResources.dependsOn processDecoraShaders, processPrismShaders
 
@@ -1365,8 +1384,10 @@
 project(":builders") {
     sourceCompatibility = 1.7
 
-    if (!COMPILE_SWING) sourceSets.main.java.exclude ("**/swing/**")
-    if (!COMPILE_SWT)   sourceSets.main.java.exclude ("**/swt/**")
+    if (!COMPILE_SWING)  sourceSets.main.java.exclude ("**/swing/**")
+    if (!COMPILE_SWT)    sourceSets.main.java.exclude ("**/swt/**")
+    if (!COMPILE_WEBKIT) sourceSets.main.java.exclude ("**/web/**")
+    if (!BUILD_CLOSED)   sourceSets.main.java.exclude ("**/media/**")
 
     dependencies {
         compile BUILD_SRC, project(":base"), project(":graphics"),
@@ -2019,6 +2040,7 @@
     }
     dependencies {
         compile project(":base"), project(":graphics"), project(":controls")
+        testCompile files("../../../artifacts/sdk/rt/lib/ext/jfxrt.jar")
     }
     
     compileJava.enabled = COMPILE_WEBKIT
@@ -2029,15 +2051,6 @@
                 "$jfxTopDir/media/jfxmedia/dist/jfxmedia.jar")
     }
     
-    test {
-        classpath += files("../../../artifacts/sdk/rt/lib/ext/jfxrt.jar")
-        doFirst {
-            classpath.each { p ->
-                print "Test CLASSPATH: ${p.getPath()}\n"
-            }
-        }
-    }
-    
     task generateHeaders(dependsOn: compileJava) {
         doLast {
             def classpath = files("$buildDir/classes/main",
@@ -2109,8 +2122,7 @@
                 commandLine("perl", "Tools/Scripts/set-webkit-configuration", "--$CONF")
                 environment(["WEBKITOUTPUTDIR" : webkitOutputDir])
             }
-            ant.unzip(src:  configurations.webkit.files.iterator().next(),
-                      dest: "src/main/native/WebKitBuild")
+
             exec {
                 workingDir("$projectDir/src/main/native")
                 if (t.name == "win") {
@@ -2190,13 +2202,6 @@
             classpath = files(project(":graphics").sourceSets.main.output) // for JSObject
             source gensrcDir
             destinationDir = file("$buildDir/classes/main")
-            doLast {
-                copy {
-                    from gensrcDir
-                    into "$buildDir/resources/main"
-                    exclude "**/*.java"
-                }
-            }
         }
 
         compileGenerated.dependsOn compileGeneratedTask
--- a/buildSrc/.classpath	Tue Aug 20 08:59:55 2013 -0400
+++ b/buildSrc/.classpath	Tue Aug 20 09:38:00 2013 -0700
@@ -6,7 +6,6 @@
   <classpathentry kind="lib" exported="true" path="../build/libs/ant-1.8.2.jar"/>
   <classpathentry kind="lib" exported="true" path="../build/libs/antlr-3.1.3.jar"/>
   <classpathentry kind="lib" exported="true" path="../build/libs/antlr-runtime-3.1.3.jar"/>
-  <classpathentry kind="lib" exported="true" path="../build/libs/plugin.jar"/>
   <classpathentry kind="lib" exported="true" path="../build/libs/stringtemplate-3.2.jar"/>
   <classpathentry kind="lib" exported="true" path="../build/libs/swt-debug.jar"/>
   <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
--- a/buildSrc/android.gradle	Tue Aug 20 08:59:55 2013 -0400
+++ b/buildSrc/android.gradle	Tue Aug 20 09:38:00 2013 -0700
@@ -345,6 +345,7 @@
 android.egl.depthSize=16
 android.prism.lcdtext=false
 android.embedded=eglfb
+android.prism.allowhidpi=false
 android.prism.maxTextureSize=2048
 android.prism.dirtyopts=true
 android.prism.vsync=false
@@ -392,7 +393,8 @@
 
 ANDROID.surface = [:]
 ANDROID.surface.javahInclude = [
-    "com/sun/glass/events/*"
+    "com/sun/glass/events/*",
+    "com/sun/glass/ui/android/*"
 ]
 ANDROID.surface.nativeSource = [
     file("modules/graphics/src/main/native-glass/lens/android")
@@ -441,6 +443,7 @@
 ANDROID.glass.javahInclude = [
     "com/sun/glass/events/**",
     "com/sun/glass/ui/*",
+    "com/sun/glass/ui/android/*",
     "com/sun/glass/ui/lens/*"]
 
 ANDROID.glass.eglfb = [:]
--- a/buildSrc/armv6hf.gradle	Tue Aug 20 08:59:55 2013 -0400
+++ b/buildSrc/armv6hf.gradle	Tue Aug 20 09:38:00 2013 -0700
@@ -193,6 +193,7 @@
 eglfb.com.sun.javafx.isEmbedded=true
 eglfb.doNativeComposite=true
 eglfb.com.sun.javafx.scene.control.skin.FXVK.cache=true
+eglfb.prism.glDepthSize=0
 fb.glass.platform=Lens
 fb.glass.lens=fb
 fb.prism.order=sw
@@ -210,6 +211,7 @@
 eglx11.embedded=eglx11
 eglx11.com.sun.javafx.isEmbedded=true
 eglx11.com.sun.javafx.scene.control.skin.FXVK.cache=true
+eglx11.prism.glDepthSize=0
 gtk.glass.platform=gtk
 gtk.prism.order=sw
 gtk.com.sun.javafx.isEmbedded=true
@@ -244,7 +246,7 @@
 def linker = file("$compilerHome/bin/arm-linux-gnueabihf-g++").getAbsolutePath()
 
 ARMV6HF.glass = [:]
-ARMV6HF.glass.variants = ["eglfb", "directfb", "fb", "eglx11", "gtk"]
+ARMV6HF.glass.variants = ["eglfb", "directfb", "fb", "eglx11", "gtk", "lensport" ]
 ARMV6HF.glass.javahInclude = [
     "com/sun/glass/events/**",
     "com/sun/glass/ui/*",
@@ -253,6 +255,16 @@
     "com/sun/glass/ui/accessible/gtk/*"]
 ARMV6HF.glass.lib = "glass"
 
+ARMV6HF.glass.lensport = [:]
+ARMV6HF.glass.lensport.nativeSource = [
+    file("modules/graphics/src/main/native-glass/lens/platform-util") ]
+ARMV6HF.glass.lensport.compiler = compiler
+ARMV6HF.glass.lensport.ccFlags = ["-ffast-math", extraCFlags, "-DLINUX", "-DISEGLFB",
+    "-DLENSPORT", "-I", file("modules/graphics/src/main/native-glass/lens/") ].flatten()
+ARMV6HF.glass.lensport.linker = linker
+ARMV6HF.glass.lensport.linkFlags = [lensLFlags].flatten()
+ARMV6HF.glass.lensport.lib = "lens_porting"
+
 ARMV6HF.glass.eglfb = [:]
 // TODO when building headless, use lens/cursor/nullcursor/
 // otherwise we use lens/cursor/fbCursor/ and lens/input/udev
@@ -266,7 +278,8 @@
     file("modules/graphics/src/main/native-glass/lens/wm"),
     file("modules/graphics/src/main/native-glass/lens/cursor/fbCursor"),
     file("modules/graphics/src/main/native-glass/lens/input/udev"),
-    file("modules/graphics/src/main/native-glass/lens/wm/screen/fbdevScreen.c")]
+    file("modules/graphics/src/main/native-glass/lens/wm/screen/fbdevScreen.c"),
+    file("modules/graphics/src/main/native-glass/lens/platform-util") ]
     //file("modules/graphics/src/main/native-glass/lens/wm/screen")]
 ARMV6HF.glass.eglfb.compiler = compiler
 ARMV6HF.glass.eglfb.ccFlags = ["-ffast-math", extraCFlags, "-DLINUX", "-DISEGLFB"].flatten()
--- a/buildSrc/armv6sf.gradle	Tue Aug 20 08:59:55 2013 -0400
+++ b/buildSrc/armv6sf.gradle	Tue Aug 20 09:38:00 2013 -0700
@@ -212,6 +212,7 @@
 eglfb.embedded=eglfb
 eglfb.com.sun.javafx.isEmbedded=true
 eglfb.com.sun.javafx.scene.control.skin.FXVK.cache=true
+eglfb.prism.glDepthSize=0
 fb.glass.platform=Lens
 fb.glass.lens=fb
 fb.prism.order=sw
@@ -229,6 +230,7 @@
 eglx11.embedded=eglx11
 eglx11.com.sun.javafx.isEmbedded=true
 eglx11.com.sun.javafx.scene.control.skin.FXVK.cache=true
+eglx11.prism.glDepthSize=0
 gtk.glass.platform=gtk
 gtk.prism.order=sw
 gtk.com.sun.javafx.isEmbedded=true
@@ -263,7 +265,7 @@
 def linker = file("$compilerHome/bin/arm-linux-gnueabi-g++").getAbsolutePath()
 
 ARMV6SF.glass = [:]
-ARMV6SF.glass.variants = ["eglfb", "directfb", "fb", "eglx11", "gtk"]
+ARMV6SF.glass.variants = ["eglfb", "directfb", "fb", "eglx11", "gtk", "lensport" ]
 ARMV6SF.glass.javahInclude = [
     "com/sun/glass/events/**",
     "com/sun/glass/ui/*",
@@ -272,6 +274,16 @@
     "com/sun/glass/ui/accessible/gtk/*"]
 ARMV6SF.glass.lib = "glass"
 
+ARMV6SF.glass.lensport = [:]
+ARMV6SF.glass.lensport.nativeSource = [
+    file("modules/graphics/src/main/native-glass/lens/platform-util") ]
+ARMV6SF.glass.lensport.compiler = compiler
+ARMV6SF.glass.lensport.ccFlags = ["-ffast-math", extraCFlags, "-DLINUX", "-DISEGLFB",
+    "-DLENSPORT", "-I", file("modules/graphics/src/main/native-glass/lens/")].flatten()
+ARMV6SF.glass.lensport.linker = linker
+ARMV6SF.glass.lensport.linkFlags = [lensLFlags].flatten()
+ARMV6SF.glass.lensport.lib = "lens_porting"
+
 ARMV6SF.glass.eglfb = [:]
 // TODO when building headless, use lens/cursor/nullcursor/
 // otherwise we use lens/cursor/fbCursor/ and lens/input/udev
@@ -285,6 +297,7 @@
     file("modules/graphics/src/main/native-glass/lens/wm"),
     file("modules/graphics/src/main/native-glass/lens/cursor/fbCursor"),
     file("modules/graphics/src/main/native-glass/lens/input/udev"),
+    file("modules/graphics/src/main/native-glass/lens/platform-util"),
     file("modules/graphics/src/main/native-glass/lens/wm/screen/fbdevScreen.c")]
 ARMV6SF.glass.eglfb.compiler = compiler
 ARMV6SF.glass.eglfb.ccFlags = ["-ffast-math", extraCFlags, "-DLINUX", "-DISEGLFB"].flatten()
@@ -298,6 +311,7 @@
     file("modules/graphics/src/main/native-glass/lens/wm"),
     file("modules/graphics/src/main/native-glass/lens/cursor/fbCursor"),
     file("modules/graphics/src/main/native-glass/lens/input/udev"),
+    file("modules/graphics/src/main/native-glass/lens/platform-util"),
     file("modules/graphics/src/main/native-glass/lens/wm/screen/dfbScreen.c")]
 ARMV6SF.glass.directfb.compiler = compiler
 ARMV6SF.glass.directfb.ccFlags = ["-ffast-math", extraCFlags, "-I$sdk/usr/include/directfb", "-DLINUX"].flatten()
--- a/buildSrc/ios.gradle	Tue Aug 20 08:59:55 2013 -0400
+++ b/buildSrc/ios.gradle	Tue Aug 20 09:38:00 2013 -0700
@@ -302,7 +302,7 @@
 IOS.webview.variants = ["arm", "x86"];
 
 IOS.webview.arm = [:]
-IOS.webview.arm.nativeSource = file("$closedDir/javafx-ios-webnode/native")
+IOS.webview.arm.nativeSource = file("modules/web/src/ios/native")
 IOS.webview.arm.compiler = compiler
 IOS.webview.arm.ccFlags = [ccFlags, "-arch", archArm, "-isysroot", sdkPath(iPhoneOS)].flatten()
 IOS.webview.arm.linker = linker
@@ -318,61 +318,63 @@
 IOS.webview.x86.lib = "javafx_ios_webnode_${archX86}"
 
 project(":web") {
-    if (BUILD_CLOSED) {
-        apply plugin: 'java'
+    apply plugin: 'java'
 
-        compileJava {
-            enabled = false
+    compileJava {
+        enabled = false
+    }
+
+    afterEvaluate {
+        def compileWebJavaIos = task("compileWebJavaIos",
+            type: JavaCompile, group: "Build") {
+
+            dependsOn(project(":graphics").classes, project(":base").classes)
+            description = "Task compiles web component for iOS."
+            classpath = files(
+                project(":controls").sourceSets.main.output.classesDir,
+                project(":graphics").sourceSets.main.output.classesDir,
+                project(":base").sourceSets.main.output.classesDir
+            )
+            destinationDir = file("modules/web/build/classes/ios")
+            dependencyCacheDir = file("modules/web/build/dependency-cache")
+            source file("modules/web/src/ios/java")
+            doLast {
+                copy {
+                    from "modules/web/src/ios/resources"
+                    into "modules/web/build/resources/ios"
+                }
+            }
         }
 
-        afterEvaluate {
-            def compileWebJavaIos = task("compileWebJavaIos",
-                type: JavaCompile, group: "Build") {
+        def jarWebJavaIos = task("jarWebJavaIos",
+            type: Jar, group: "Build") {
+            description = "Creates web.jar for iOS."
+            dependsOn(compileWebJavaIos)
+            archiveName = "web.jar"
+            includeEmptyDirs = false
+            destinationDir = project.file("build/libs/ios")
+            from("build/classes/ios")
+        }
 
-                dependsOn(project(":graphics").classes, project(":base").classes)
-                description = "Task compiles web component for iOS."
-                classpath = files(
-                    project(":controls").sourceSets.main.output.classesDir,
-                    project(":graphics").sourceSets.main.output.classesDir,
-                    project(":base").sourceSets.main.output.classesDir
-                )
-                destinationDir = file("modules/web/build/classes/ios")
-                dependencyCacheDir = file("modules/web/build/dependency-cache")
-                source file("$closedDir/javafx-ios-webnode/src")
-                doLast {
-                    copy {
-                        from source
-                        into "modules/web/build/classes/ios"
-                        exclude "**/*.java"
+        addNative(project, "webview")
+        javahIosWebview.dependsOn(compileWebJavaIos)
+
+        jfxrtIos {
+            from ("modules/web/build/classes/ios", "modules/web/build/resources/main");
+            exclude("com/sun/webkit", "com/sun/javafx/webkit");
+        }
+
+        sdkIos  {
+            dependsOn(jarWebJavaIos)
+            doLast {
+                def props = project.ext["IOS"]
+                copy {
+                    if (props.useLipo) {
+                        from ("modules/web/build/libs/webview/ios/${props.library(props.webview.lib)}")
+                    } else {
+                        from ("modules/web/build/libs/webview/ios")
                     }
-                }
-            }
-
-            def jarWebJavaIos = task("jarWebJavaIos",
-                type: Jar, group: "Build") {
-                description = "Creates web.jar for iOS."
-                dependsOn(compileWebJavaIos)
-                archiveName = "web.jar"
-                includeEmptyDirs = false
-                destinationDir = project.file("build/libs/ios")
-                from("build/classes/ios")
-            }
-
-            addNative(project, "webview")
-            javahIosWebview.dependsOn(compileWebJavaIos)
-
-            jfxrtIos {
-                from "modules/web/build/classes/ios"
-            }
-
-            sdkIos  {
-                dependsOn(jarWebJavaIos)
-                doLast {
-                    def props = project.ext["IOS"]
-                    copy {
-                        from ("modules/web/build/libs/webview/ios/${props.library(props.webview.lib)}")
-                        into ("build/ios-sdk/rt/${props.libDest}")
-                    }
+                    into ("build/ios-sdk/rt/${props.libDest}")
                 }
             }
         }
--- a/buildSrc/x86egl.gradle	Tue Aug 20 08:59:55 2013 -0400
+++ b/buildSrc/x86egl.gradle	Tue Aug 20 09:38:00 2013 -0700
@@ -212,7 +212,7 @@
 def linker = "g++"
 
 X86EGL.glass = [:]
-X86EGL.glass.variants = ["eglfb", "directfb", "fb", "eglx11", "gtk"]
+X86EGL.glass.variants = ["eglfb", "directfb", "fb", "eglx11", "gtk", "lensport"]
 X86EGL.glass.javahInclude = [
     "com/sun/glass/events/**",
     "com/sun/glass/ui/*",
@@ -221,6 +221,16 @@
     "com/sun/glass/ui/accessible/gtk/*"]
 X86EGL.glass.lib = "glass"
 
+X86EGL.glass.lensport = [:]
+X86EGL.glass.lensport.nativeSource = [
+    file("modules/graphics/src/main/native-glass/lens/platform-util") ]
+X86EGL.glass.lensport.compiler = compiler
+X86EGL.glass.lensport.ccFlags = ["-ffast-math", extraCFlags, "-DLINUX", "-DISEGLFB",
+    "-DLENSPORT", "-I", file("modules/graphics/src/main/native-glass/lens/") ].flatten()
+X86EGL.glass.lensport.linker = linker
+X86EGL.glass.lensport.linkFlags = [lensLFlags].flatten()
+X86EGL.glass.lensport.lib = "lens_porting"
+
 X86EGL.glass.eglfb = [:]
 // TODO when building headless, use lens/cursor/nullcursor/
 // otherwise we use lens/cursor/fbCursor/ and lens/input/udev
@@ -233,7 +243,8 @@
     file("modules/graphics/src/main/native-glass/lens/wm"),
     file("modules/graphics/src/main/native-glass/lens/cursor/fbCursor"),
     file("modules/graphics/src/main/native-glass/lens/input/udev"),
-    file("modules/graphics/src/main/native-glass/lens/wm/screen/x11ContainerScreen.c")]
+    file("modules/graphics/src/main/native-glass/lens/wm/screen/x11ContainerScreen.c"),
+    file("modules/graphics/src/main/native-glass/lens/platform-util") ]
     //file("modules/graphics/src/main/native-glass/lens/wm/screen")]
 X86EGL.glass.eglfb.compiler = compiler
 X86EGL.glass.eglfb.ccFlags = ["-ffast-math", extraCFlags, "-DLINUX"].flatten()
@@ -247,7 +258,8 @@
     file("modules/graphics/src/main/native-glass/lens/wm"),
     file("modules/graphics/src/main/native-glass/lens/cursor/fbCursor"),
     file("modules/graphics/src/main/native-glass/lens/input/udev"),
-    file("modules/graphics/src/main/native-glass/lens/wm/screen/dfbScreen.c")]
+    file("modules/graphics/src/main/native-glass/lens/wm/screen/dfbScreen.c"),
+    file("modules/graphics/src/main/native-glass/lens/platform-util") ]
     //file("modules/graphics/src/main/native-glass/lens/wm/screen")]
 X86EGL.glass.directfb.compiler = compiler
 X86EGL.glass.directfb.ccFlags = ["-ffast-math", extraCFlags, "-I/usr/include/directfb", "-DLINUX"].flatten()
--- a/modules/base/src/main/java/javafx/collections/ListChangeBuilder.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/base/src/main/java/javafx/collections/ListChangeBuilder.java	Tue Aug 20 09:38:00 2013 -0700
@@ -151,7 +151,7 @@
 
     private int compress(List<SubChange<E>> list) {
         int removed = 0;
-        
+
         SubChange<E> prev = list.get(0);
         for (int i = 1, sz = list.size(); i < sz; ++i) {
             SubChange<E> cur = list.get(i);
@@ -170,7 +170,7 @@
             }
         }
         return removed;
-        
+
     }
 
     private static class SubChange<E> {
@@ -196,7 +196,7 @@
     public void nextRemove(int idx, E removed) {
         checkState();
         checkAddRemoveList();
-        
+
         final SubChange<E> last = addRemoveChanges.isEmpty() ? null
                 : addRemoveChanges.get(addRemoveChanges.size() - 1);
 
@@ -228,12 +228,12 @@
                 updateChanges.get(i).to--;
             }
         }
-        
+
     }
 
     public void nextRemove(int idx, List<? extends E> removed) {
         checkState();
-        
+
         for (int i = 0; i < removed.size(); ++i) {
             nextRemove(idx, removed.get(i));
         }
@@ -270,7 +270,7 @@
                 updateChanges.get(i).to += numberOfAdded;
             }
         }
-        
+
     }
 
     public void nextPermutation(int from, int to, int[] perm) {
@@ -497,7 +497,7 @@
                     int removed = compress(addRemoveChanges);
                     totalSize -= removed;
                 }
-                
+
                 SubChange<E>[] array = new SubChange[totalSize];
                 int ptr = 0;
                 if (permutationChange != null) {
--- a/modules/base/src/main/java/javafx/collections/transformation/SortedList.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/base/src/main/java/javafx/collections/transformation/SortedList.java	Tue Aug 20 09:38:00 2013 -0700
@@ -310,12 +310,12 @@
             return pos;
         }
         int tmp = pos;
-        while (sorted[--tmp].index != idx && compare(sorted[tmp].e, e) == 0);
+        while (tmp != 0 && sorted[--tmp].index != idx && compare(sorted[tmp].e, e) == 0);
         if (sorted[tmp].index == idx) {
             return tmp;
         }
         tmp = pos;
-        while (sorted[++tmp].index != idx && compare(sorted[tmp].e, e) == 0);
+        while (tmp != (size - 1) && sorted[++tmp].index != idx && compare(sorted[tmp].e, e) == 0);
         if (sorted[tmp].index == idx) {
             return tmp;
         }
--- a/modules/base/src/test/java/javafx/collections/SortedListTest.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/base/src/test/java/javafx/collections/SortedListTest.java	Tue Aug 20 09:38:00 2013 -0700
@@ -336,6 +336,20 @@
         FXCollections.sort(list);
 
         assertEquals(sorted, list);
-        
+
+    }
+
+    @Test
+    public void testRemoveFromDuplicates() {
+        String toRemove = new String("A");
+        String other = new String("A");
+        list = FXCollections.observableArrayList(other, toRemove);
+        Comparator<String> c = Comparator.naturalOrder();
+        SortedList<String> sorted = list.sorted(c);
+
+        list.remove(1);
+
+        assertEquals(1, sorted.size());
+        assertTrue(sorted.get(0) == other);
     }
 }
--- a/modules/fxml/src/main/java/com/sun/javafx/fxml/builder/TriangleMeshBuilder.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/fxml/src/main/java/com/sun/javafx/fxml/builder/TriangleMeshBuilder.java	Tue Aug 20 09:38:00 2013 -0700
@@ -44,9 +44,15 @@
     @Override
     public TriangleMesh build() {
         TriangleMesh mesh = new TriangleMesh();
-        mesh.getPoints().setAll(points);
-        mesh.getTexCoords().setAll(texCoords);
-        mesh.getFaces().setAll(faces);
+        if (points != null) {
+            mesh.getPoints().setAll(points);
+        }
+        if (texCoords != null) {
+            mesh.getTexCoords().setAll(texCoords);
+        }
+        if (faces != null) {
+            mesh.getFaces().setAll(faces);
+        }
         if (faceSmoothingGroups != null) {
             mesh.getFaceSmoothingGroups().setAll(faceSmoothingGroups);
         }
--- a/modules/graphics/src/android/java/com/oracle/dalvik/VMLauncher.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/android/java/com/oracle/dalvik/VMLauncher.java	Tue Aug 20 09:38:00 2013 -0700
@@ -60,7 +60,12 @@
     }
 
     private static void loadNativeLibraries() {
-        System.load(sJavaHome + "/lib/" + getJvmArch() + "/client/libjvm.so");
+        try {
+            System.load(sJavaHome + "/lib/" + getJvmArch() + "/minimal/libjvm.so");
+        } catch(UnsatisfiedLinkError e) {
+            //try vm in debug mode
+            System.load(sJavaHome + "/lib/" + getJvmArch() + "/client/libjvm.so");
+        }
         System.load(sJavaHome + "/lib/" + getJvmArch() + "/jli/libjli.so");
     }
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/android/Activity.java	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * 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.sun.glass.ui.android;
+
+public class Activity {
+
+    public static void shutdown() {
+        _shutdown();
+    };
+    
+    private static native void _shutdown();
+}
--- a/modules/graphics/src/main/java/com/sun/glass/ui/android/SoftwareKeyboard.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/android/SoftwareKeyboard.java	Tue Aug 20 09:38:00 2013 -0700
@@ -27,7 +27,15 @@
 
 public class SoftwareKeyboard {
 
-	public static native void show();
+	public static void show() {
+        _show();
+    }
 	
-	public static native void hide();
+	public static void hide() {
+        _hide();
+    }
+    
+    private static native void _show();
+    
+    private static native void _hide();
 }
--- a/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensApplication.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensApplication.java	Tue Aug 20 09:38:00 2013 -0700
@@ -501,6 +501,41 @@
         }
     }
 
+    private static class LensMultiTouchEvent extends Event {
+
+        private LensView view;
+        private int[] states;
+        private long[] ids;
+        private int[] xs;
+        private int[] ys;
+        private int dx;
+        private int dy;
+
+        LensMultiTouchEvent(LensView view, int[] states, long[] ids,
+                       int[] xs, int[] ys, int dx, int dy) {
+            this.view = view;
+            this.states = states;
+            this.ids = ids;
+            this.xs = xs;
+            this.ys = ys;
+            this.dx = dx;
+            this.dy = dy;
+        }
+
+        @Override
+        void dispatch() {
+            LensTouchInputSupport.postMultiTouchEvent(
+                    view, states, ids, xs, ys, dx, dy);
+
+        }
+
+        @Override
+        public String toString() {
+            return "LensMultiTouchEvent[view=" + view
+                    + ",points=" + ids.length
+                    + "]";
+        }
+    }
 
     private static class LensViewEvent extends Event {
         private LensView target;
@@ -1325,6 +1360,35 @@
         }
     }
 
+    /**
+    * Notify multitouch event from native layer
+    *
+    * @param window the window which the view is related to
+    * @param states list of the finger states of each touch point
+    * @param ids list of the IDs of each touch point
+    * @param xs list of of the absolute X coordinates of each touch point
+    * @param ys list of of the absolute Y coordinates of each touch point
+    * @param dx value to be added to X coordinates to convert them to relative
+    * @param dy value to be added to Y coordinates to convert them to relative
+    */
+    private void notifyMultiTouchEvent(LensView view, int[] states, long[] ids,
+                                       int[] xs, int[] ys, int dx, int dy) {
+        try {
+
+            if (LensLogger.getLogger().isLoggable(Level.FINE)) {
+                LensLogger.getLogger().fine("MultiTouch event with "
+                                            + states.length + " points "
+                                            + " on " + view);
+            }
+
+            postEvent(new LensMultiTouchEvent(view, states, ids,
+                                              xs, ys, dx, dy));
+
+        } catch (Exception e) {
+            reportException(e);
+        }
+    }
+
 
 
     /**
--- a/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensTouchInputSupport.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensTouchInputSupport.java	Tue Aug 20 09:38:00 2013 -0700
@@ -71,7 +71,17 @@
         touches.notifyBeginTouchEvent(view, 0, true, 1);
         touches.notifyNextTouchEvent(view, state, id, x, y, absX, absY);
         touches.notifyEndTouchEvent(view);
+    }
 
+    static void postMultiTouchEvent(LensView view, int[] states, long[] ids,
+                                    int[] xs, int[] ys, int dx, int dy) {
+        touches.notifyBeginTouchEvent(view, 0, true, states.length);
+        for (int i = 0; i < states.length; i++) {
+            touches.notifyNextTouchEvent(view, states[i], ids[i],
+                                         xs[i] + dx, ys[i] + dy,
+                                         xs[i], ys[i]);
+        }
+        touches.notifyEndTouchEvent(view);
     }
 }
 
--- a/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacFileNSURL.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacFileNSURL.java	Tue Aug 20 09:38:00 2013 -0700
@@ -105,7 +105,7 @@
 
     // ------------- Bookmarks --------------
 
-    native private byte[] _getBookmark(long ptr);
+    native private byte[] _getBookmark(long ptr, long baseDocumentPtr);
     /**
      * Returns a byte array representing a persistent bookmark for this URL.
      * An app can store this data, and later re-create the URL with a call
@@ -116,10 +116,10 @@
     public byte[] getBookmark() {
         Application.checkEventThread();
         checkNotDisposed();
-        return _getBookmark(ptr);
+        return _getBookmark(ptr, 0L);
     }
 
-    native private static MacFileNSURL _createFromBookmark(byte[] data);
+    native private static MacFileNSURL _createFromBookmark(byte[] data, long baseDocumentPtr);
     /**
      * Returns an instance of the MacFileNSURL class created from bookmark
      * data stored in the byte array passed as an argument.
@@ -137,7 +137,44 @@
         if (!MacCommonDialogs.isFileNSURLEnabled()) {
             throw new RuntimeException("The system property glass.macosx.enableFileNSURL is not 'true'");
         }
-        return _createFromBookmark(data);
+        return _createFromBookmark(data, 0L);
+    }
+
+    /**
+     * Returns a byte array representing a document-scoped bookmark
+     * for this URL relative to the {@code baseDocument} URL.
+     * An app can store this data, and later re-create the URL with a call
+     * to {@link createFromDocumentScopedBookmark}.
+     *
+     * @throws NullPointerException if baseDocument is {@code null}
+     * @return bookmark data in a form of byte[]
+     */
+    public byte[] getDocumentScopedBookmark(MacFileNSURL baseDocument) {
+        Application.checkEventThread();
+        checkNotDisposed();
+        return _getBookmark(ptr, baseDocument.ptr);
+    }
+
+    /**
+     * Returns an instance of the MacFileNSURL class created from a
+     * document-scoped bookmark data stored in the byte array passed as an
+     * argument, relative to the {@code baseDocument} URL.
+     *
+     * The glass.macosx.enableFileNSURL system property must be set to {@code
+     * true} before calling this method.
+     *
+     * @throws NullPointerException if baseDocument is {@code null}
+     * @return a new instance of MacFileNSURL
+     */
+    public static MacFileNSURL createFromDocumentScopedBookmark(byte[] data, MacFileNSURL baseDocument) {
+        Application.checkEventThread();
+        if (data == null) {
+            throw new NullPointerException("data must not be null");
+        }
+        if (!MacCommonDialogs.isFileNSURLEnabled()) {
+            throw new RuntimeException("The system property glass.macosx.enableFileNSURL is not 'true'");
+        }
+        return _createFromBookmark(data, baseDocument.ptr);
     }
 }
 
--- a/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacSystemClipboard.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/mac/MacSystemClipboard.java	Tue Aug 20 09:38:00 2013 -0700
@@ -24,10 +24,8 @@
  */
 package com.sun.glass.ui.mac;
 
-import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.net.URL;
 import java.nio.ByteBuffer;
 import java.nio.IntBuffer;
 import java.nio.file.FileSystems;
@@ -388,8 +386,8 @@
                 utm.put(uti, decodedMIME);
                 return decodedMIME;
             }
-            //Do not know who encoded it, pass-throw
-            return uti;
+            // FX would not handle an unknown mime.
+            return null;
         }
 
         private static native String _convertMIMEtoUTI(String mime);
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/Area.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/Area.java	Tue Aug 20 09:38:00 2013 -0700
@@ -25,10 +25,10 @@
 
 package com.sun.javafx.geom;
 
-import com.sun.javafx.geom.transform.BaseTransform;
-import java.util.Vector;
 import java.util.Enumeration;
 import java.util.NoSuchElementException;
+import java.util.Vector;
+import com.sun.javafx.geom.transform.BaseTransform;
 
 
 /**
@@ -542,7 +542,7 @@
         if (w < 0 || h < 0) {
             return false;
         }
-        if (!getCachedBounds().contains(x, y, w, h)) {
+        if (!getCachedBounds().contains(x, y) || !getCachedBounds().contains(x+w, y+h)) {
             return false;
         }
         Crossings c = Crossings.findCrossings(curves, x, y, x+w, y+h);
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/BaseBounds.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/BaseBounds.java	Tue Aug 20 09:38:00 2013 -0700
@@ -26,17 +26,35 @@
 package com.sun.javafx.geom;
 
 /**
- *
+ * Base class for mutable bounds objects. There are two concrete specializations,
+ * BoxBounds (3D) and RectBounds (2D). Various "derive" methods exist which are
+ * used to mutate the bounds objects, such that they can be converted between the
+ * different types as appropriate, or modified in place if possible. This allows
+ * us to churn memory as little as possible without representing everything as
+ * if it were in 3D space (there are some computational cost savings to being
+ * able to ignore the Z values).
  */
 public abstract class BaseBounds {
 
+    /**
+     * The different types of BaseBounds that are currently supported.
+     * We might support other types of bounds in the future (such as
+     * SPHERE) which are also 2D or 3D but are defined in some way
+     * other than with a bounding box. Such bounds can sometimes more
+     * accurately represent the pixels
+     */
     public static enum BoundsType {
         RECTANGLE, // A 2D axis-aligned bounding rectangle
         BOX,  // A 3D axis-aligned bounding box
     }
 
-    /*
-     * Duplicates this instance
+    // Only allow subclasses in this package
+    BaseBounds() { }
+
+    /**
+     * Duplicates this instance. This differs from deriveWithNewBounds(other)
+     * where "other" would be this, in that derive methods may return the
+     * same instance, whereas copy will always return a new instance.
      */
     public abstract BaseBounds copy();
 
@@ -130,6 +148,18 @@
 
     public abstract void roundOut();
 
+    /**
+     * Sets the given RectBounds (or creates a new instance of bounds is null) to
+     * have the minX, minY, maxX, and maxY of this BoxBounds, dropping the Z values.
+     *
+     * @param bounds The bounds to fill with values, or null. If null, a new RectBounds
+     *               is returned. If not null, the given bounds will be populated and
+     *               then returned
+     * @return a non-null reference to a RectBounds containing the minX, minY, maxX, and
+     * maxY of this BoxBounds.
+     */
+    public abstract RectBounds flattenInto(RectBounds bounds);
+
     public abstract BaseBounds makeEmpty();
 
     public abstract boolean disjoint(float x, float y, float width, float height);
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/BoxBounds.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/BoxBounds.java	Tue Aug 20 09:38:00 2013 -0700
@@ -242,6 +242,16 @@
         return this;
     }
 
+    @Override public RectBounds flattenInto(RectBounds bounds) {
+        // Create the bounds if we need to
+        if (bounds == null) bounds = new RectBounds();
+        // Make it empty if we need to
+        if (isEmpty()) return bounds.makeEmpty();
+        // Populate it with values otherwise
+        bounds.setBounds(minX, minY, maxX, maxY);
+        return bounds;
+    }
+
     /**
      * Set the bounds to match that of the BaseBounds object specified. The
      * specified bounds object must not be null.
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/DirtyRegionContainer.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/DirtyRegionContainer.java	Tue Aug 20 09:38:00 2013 -0700
@@ -151,7 +151,7 @@
             int regionCount = emptyIndex;
 
             for(int i = 0; i < regionCount; i++) {
-                //can't have overlaping regions
+                //can't have overlapping regions
                 dr = dirtyRegions[tempIndex];
                 if (region.intersects(dr)) {
                     region.unionWith(dr);
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/RectBounds.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/RectBounds.java	Tue Aug 20 09:38:00 2013 -0700
@@ -26,18 +26,17 @@
 package com.sun.javafx.geom;
 
 /**
- * A simple object which carries bounds information as floats.
- * <p>
- *
+ * A simple object which carries bounds information as floats, and
+ * has no Z components.
  */
-public class RectBounds extends BaseBounds {
-    // minimum x value of boundining box
+public final class RectBounds extends BaseBounds {
+    // minimum x value of bounding box
     private float minX;
-    // maximum x value of boundining box
+    // maximum x value of bounding box
     private float maxX;
-    // minimum y value of boundining box
+    // minimum y value of bounding box
     private float minY;
-    // maximum y value of boundining box
+    // maximum y value of bounding box
     private float maxY;
 
     /**
@@ -49,7 +48,7 @@
         maxX = maxY = -1.0f;
     }
     
-    public BaseBounds copy() {
+    @Override public BaseBounds copy() {
         return new RectBounds(minX, minY, maxX, maxY);
     }
     
@@ -75,11 +74,11 @@
                 other.x + other.width, other.y + other.height);
     }
 
-    public BoundsType getBoundsType() {
+    @Override public BoundsType getBoundsType() {
         return BoundsType.RECTANGLE;
     }
 
-    public boolean is2D() {
+    @Override public boolean is2D() {
         return true;
     }
 
@@ -87,7 +86,7 @@
      * Convenience function for getting the width of this RectBounds.
      * The dimension along the X-Axis.
      */
-    public float getWidth() {
+    @Override public float getWidth() {
         return maxX - minX;
     }
 
@@ -95,7 +94,7 @@
      * Convenience function for getting the height of this RectBounds
      * The dimension along the Y-Axis.
      */
-    public float getHeight() {
+    @Override public float getHeight() {
         return maxY - minY;
     }
 
@@ -104,11 +103,11 @@
      * The dimension along the Z-Axis, since this is a 2D bounds the return
      * value is always 0.0f.
      */
-    public float getDepth() {
+    @Override public float getDepth() {
         return 0.0f;
     }
 
-    public float getMinX() {
+    @Override public float getMinX() {
         return minX;
     }
 
@@ -116,7 +115,7 @@
         this.minX = minX;
     }
 
-    public float getMinY() {
+    @Override public float getMinY() {
         return minY;
     }
 
@@ -124,11 +123,11 @@
         this.minY = minY;
     }
 
-    public float getMinZ() {
+    @Override public float getMinZ() {
         return 0.0f;
     }
 
-    public float getMaxX() {
+    @Override public float getMaxX() {
         return maxX;
     }
 
@@ -136,7 +135,7 @@
         this.maxX = maxX;
     }
 
-    public float getMaxY() {
+    @Override public float getMaxY() {
         return maxY;
     }
 
@@ -144,11 +143,11 @@
         this.maxY = maxY;
     }
 
-    public float getMaxZ() {
+    @Override public float getMaxZ() {
         return 0.0f;
     }
 
-    public Vec2f getMin(Vec2f min) {
+    @Override public Vec2f getMin(Vec2f min) {
         if (min == null) {
             min = new Vec2f();
         }
@@ -157,7 +156,7 @@
         return min;
     }
 
-    public Vec2f getMax(Vec2f max) {
+    @Override public Vec2f getMax(Vec2f max) {
         if (max == null) {
             max = new Vec2f();
         }
@@ -166,7 +165,7 @@
         return max;
     }
 
-    public Vec3f getMin(Vec3f min) {
+    @Override public Vec3f getMin(Vec3f min) {
         if (min == null) {
             min = new Vec3f();
         }
@@ -177,7 +176,7 @@
 
     }
 
-    public Vec3f getMax(Vec3f max) {
+    @Override public Vec3f getMax(Vec3f max) {
         if (max == null) {
             max = new Vec3f();
         }
@@ -188,7 +187,7 @@
 
     }
 
-    public BaseBounds deriveWithUnion(BaseBounds other) {
+    @Override public BaseBounds deriveWithUnion(BaseBounds other) {
         if (other.getBoundsType() == BoundsType.RECTANGLE) {
             RectBounds rb = (RectBounds) other;
             unionWith(rb);
@@ -202,14 +201,14 @@
         return this;
     }
 
-    public BaseBounds deriveWithNewBounds(Rectangle other) {
+    @Override public BaseBounds deriveWithNewBounds(Rectangle other) {
         if (other.width < 0 || other.height < 0) return makeEmpty();
         setBounds(other.x, other.y,
                 other.x + other.width, other.y + other.height);
         return this;
     }
 
-    public BaseBounds deriveWithNewBounds(BaseBounds other) {
+    @Override public BaseBounds deriveWithNewBounds(BaseBounds other) {
         if (other.isEmpty()) return makeEmpty();
         if (other.getBoundsType() == BoundsType.RECTANGLE) {
             RectBounds rb = (RectBounds) other;
@@ -225,7 +224,7 @@
         return this;
     }
 
-    public BaseBounds deriveWithNewBounds(float minX, float minY, float minZ,
+    @Override public BaseBounds deriveWithNewBounds(float minX, float minY, float minZ,
             float maxX, float maxY, float maxZ) {
         if ((maxX < minX) || (maxY < minY) || (maxZ < minZ)) return makeEmpty();
         if ((minZ == 0) && (maxZ == 0)) {
@@ -238,7 +237,7 @@
         return new BoxBounds(minX, minY, minZ, maxX, maxY, maxZ);
     }
 
-    public BaseBounds deriveWithNewBoundsAndSort(float minX, float minY, float minZ,
+    @Override public BaseBounds deriveWithNewBoundsAndSort(float minX, float minY, float minZ,
            float maxX, float maxY, float maxZ) {
         if ((minZ == 0) && (maxZ == 0)) {
            setBoundsAndSort(minX, minY, minZ, maxX, maxY, maxZ);
@@ -280,7 +279,7 @@
         sortMinMax();
     }
 
-    public void setBoundsAndSort(float minX, float minY,  float minZ,
+    @Override public void setBoundsAndSort(float minX, float minY,  float minZ,
             float maxX, float maxY, float maxZ) {
         if (minZ != 0 || maxZ != 0) {
             throw new UnsupportedOperationException("Unknown BoundsType");
@@ -289,10 +288,25 @@
         sortMinMax();
     }
 
-    public void setBoundsAndSort(Point2D p1, Point2D p2) {
+    @Override public void setBoundsAndSort(Point2D p1, Point2D p2) {
         setBoundsAndSort(p1.x, p1.y, p2.x, p2.y);
     }
 
+    // Note: this implementation is exactly the same as BoxBounds. I could put a default
+    // implementation in BaseBounds which calls the getters, or I could move the minX, minY
+    // etc up to BaseBounds, or I could (maybe?) have BoxBounds extend from RectBounds or
+    // have both extend a common parent. In the end I wanted direct access to the fields
+    // but this was the only way to get it without making a more major change.
+    @Override public RectBounds flattenInto(RectBounds bounds) {
+        // Create the bounds if we need to
+        if (bounds == null) bounds = new RectBounds();
+        // Make it empty if we need to
+        if (isEmpty()) return bounds.makeEmpty();
+        // Populate it with values otherwise
+        bounds.setBounds(minX, minY, maxX, maxY);
+        return bounds;
+    }
+
     public void unionWith(RectBounds other) {
         // Short circuit union if either bounds is empty.
         if (other.isEmpty()) return;
@@ -321,7 +335,7 @@
         this.maxY = Math.max(this.maxY, maxY);
     }
 
-    public void add(float x, float y, float z) {
+    @Override public void add(float x, float y, float z) {
         if (z != 0) {
             throw new UnsupportedOperationException("Unknown BoundsType");
         }
@@ -332,11 +346,11 @@
         unionWith(x, y, x, y);
     }
 
-    public void add(Point2D p) {
+    @Override public void add(Point2D p) {
         add(p.x, p.y);
     }
 
-    public void intersectWith(BaseBounds other) {
+    @Override public void intersectWith(BaseBounds other) {
         // Short circuit intersect if either bounds is empty.
         if (this.isEmpty()) return;
         if (other.isEmpty()) {
@@ -350,7 +364,7 @@
         maxY = Math.min(maxY, other.getMaxY());
     }
 
-    public void intersectWith(Rectangle other) {
+    @Override public void intersectWith(Rectangle other) {
         float x = other.x;
         float y = other.y;
         intersectWith(x, y, x + other.width, y + other.height);
@@ -370,7 +384,7 @@
         this.maxY = Math.min(this.maxY, maxY);
     }
 
-    public void intersectWith(float minX, float minY, float minZ,
+    @Override public void intersectWith(float minX, float minY, float minZ,
             float maxX, float maxY, float maxZ) {
         // Short circuit intersect if either bounds is empty.
         if (this.isEmpty()) return;
@@ -385,22 +399,30 @@
         this.maxY = Math.min(this.maxY, maxY);
     }
 
-    public boolean contains(Point2D p) {
+    @Override public boolean contains(Point2D p) {
         if ((p == null) || isEmpty()) return false;
         return (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY);
     }
 
-    public boolean contains(float x, float y) {
+    @Override public boolean contains(float x, float y) {
         if (isEmpty()) return false;
         return (x >= minX && x <= maxX && y >= minY && y <= maxY);
     }
 
-    public boolean contains(float x, float y, float width, float height) {
-        if (isEmpty()) return false;
-        return contains(x, y) && contains(x+width, y+height);
+    /**
+     * Determines whether the given <code>other</code> RectBounds is completely
+     * contained within this RectBounds. Equivalent RectBounds will return true.
+     *
+     * @param other The other rect bounds to check against.
+     * @return Whether the other rect bounds is contained within this one, which also
+     * includes equivalence.
+     */
+    public boolean contains(RectBounds other) {
+        if (isEmpty() || other.isEmpty()) return false;
+        return minX <= other.minX && maxX >= other.maxX && minY <= other.minY && maxY >= other.maxY;
     }
 
-    public boolean intersects(float x, float y, float width, float height) {
+    @Override public boolean intersects(float x, float y, float width, float height) {
         if (isEmpty()) return false;
         return (x + width >= minX &&
                 y + height >= minY &&
@@ -420,7 +442,7 @@
                 other.getMinZ() <= getMaxZ());
     }
 
-    public boolean disjoint(float x, float y, float width, float height) {
+    @Override public boolean disjoint(float x, float y, float width, float height) {
         if (isEmpty()) return true;
         return (x + width < minX ||
                 y + height < minY ||
@@ -438,7 +460,7 @@
                 other.getMinY() > maxY);
     }
 
-    public boolean isEmpty() {
+    @Override public boolean isEmpty() {
         // NaN values will cause the comparisons to fail and return "empty"
         return !(maxX >= minX && maxY >= minY);
     }
@@ -448,7 +470,7 @@
      * such that the rounded bounding box will always full enclose the original
      * bounding box.
      */
-    public void roundOut() {
+    @Override public void roundOut() {
         minX = (float) Math.floor(minX);
         minY = (float) Math.floor(minY);
         maxX = (float) Math.ceil(maxX);
@@ -462,7 +484,7 @@
         maxY += v;
     }
 
-    public BaseBounds deriveWithPadding(float h, float v, float d) {
+    @Override public BaseBounds deriveWithPadding(float h, float v, float d) {
         if (d == 0) {
             grow(h, v);
             return this;
@@ -475,13 +497,13 @@
     // for convenience, this function returns a reference to itself, so we can
     // change from using "bounds.makeEmpty(); return bounds;" to just
     // "return bounds.makeEmpty()"
-    public RectBounds makeEmpty() {
+    @Override public RectBounds makeEmpty() {
         minX = minY = 0.0f;
         maxX = maxY = -1.0f;
         return this;
     }
 
-    protected void sortMinMax() {
+    @Override protected void sortMinMax() {
         if (minX > maxX) {
             float tmp = maxX;
             maxX = minX;
@@ -494,16 +516,14 @@
         }
     }
     
-    @Override
-    public void translate(float x, float y, float z) {
+    @Override public void translate(float x, float y, float z) {
         setMinX(getMinX() + x);
         setMinY(getMinY() + y);
         setMaxX(getMaxX() + x);
         setMaxY(getMaxY() + y);
     }
 
-    @Override
-    public boolean equals(Object obj) {
+    @Override public boolean equals(Object obj) {
         if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
 
@@ -515,8 +535,7 @@
         return true;
     }
 
-    @Override
-    public int hashCode() {
+    @Override public int hashCode() {
         int hash = 7;
         hash = 79 * hash + Float.floatToIntBits(minX);
         hash = 79 * hash + Float.floatToIntBits(minY);
@@ -525,8 +544,7 @@
         return hash;
     }
 
-    @Override
-    public String toString() {
+    @Override public String toString() {
         return "RectBounds { minX:" + minX + ", minY:" + minY + ", maxX:" + maxX + ", maxY:" + maxY + "} (w:" + (maxX-minX) + ", h:" + (maxY-minY) +")";
     }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/scene/DirtyBits.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/scene/DirtyBits.java	Tue Aug 20 09:38:00 2013 -0700
@@ -88,7 +88,6 @@
     
     // Dirty bits for Material class (non Node type)
     MATERIAL,
-    MATERIAL_PROPERTY,
 
     // Dirty bits for Mesh class (non Node type)
     MESH,
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGGroup.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGGroup.java	Tue Aug 20 09:38:00 2013 -0700
@@ -56,13 +56,13 @@
     private List<NGNode> children = new ArrayList<>(1);
     private List<NGNode> unmod = Collections.unmodifiableList(children);
     private List<NGNode> removed;
-    
+
     /**
      * This mask has all bits that mark that a region intersects this group.
      * Which means it looks like this: 00010101010101010101010101010101 (first bit for sign)
      */
     private static final int REGION_INTERSECTS_MASK = 0x15555555;
-    
+
     /***************************************************************************
      *                                                                         *
      * Implementation of the PGGroup interface                                 *
@@ -86,18 +86,13 @@
             throw new IndexOutOfBoundsException("invalid index");
         }
 
-        // We're going to do a little verification to make sure something
-        // awful hasn't happened. Really, this is pretty superfluous and
-        // a waste of processing because the FX side should be doing this
-        // work. TODO We should only do this when assertions are enabled
-        // (RT-26980)
-        NGNode child = node;
         // NOTE: We used to do checks here to make sure that a node
         // being added didn't already have another parent listed as
         // its parent. Now we just silently accept them. The FX side
         // is already doing this check, and implementing this check
         // properly would require that the "clear" implementation visit
         // all nodes and clear this flag, which is really just wasted work.
+        NGNode child = node;
 
         // When a new node is added, we need to make sure the new node has this
         // group registered as its parent. We also need to make sure I invalidate
@@ -136,10 +131,10 @@
         if (dirtyChildrenAccumulated > DIRTY_CHILDREN_ACCUMULATED_THRESHOLD) {
             return;
         }
-        
+
         removed.add(n);
         dirtyChildrenAccumulated++;
-        
+
         if (dirtyChildrenAccumulated > DIRTY_CHILDREN_ACCUMULATED_THRESHOLD) {
             removed.clear(); //no need to store anything in this case
         }
@@ -198,14 +193,14 @@
     protected void renderContent(Graphics g) {
         renderChildren(g, (NodePath<NGNode>)g.getRenderRoot());
     }
-    
+
     private void renderChildren(Graphics g, NodePath<NGNode> renderRoot) {
         if (children == null) {
             return;
         }
-        
+
         int startPos = 0;
-        if (renderRoot != null) {
+        if (renderRoot != null && !renderRoot.isEmpty()) {
             startPos = children.indexOf(renderRoot.getCurrentNode());
 
             for (int i = 0; i < startPos; ++i) {
@@ -276,7 +271,7 @@
             bot.unref();
         }
     }
-    
+
     @Override
     protected boolean hasOverlappingContents() {
         if (blendMode != Mode.SRC_OVER) {
@@ -293,7 +288,7 @@
     public boolean isEmpty() {
         return children == null || children.isEmpty();
     }
-    
+
     @Override
     protected boolean hasVisuals() {
         return false;
@@ -314,39 +309,39 @@
      *                                                                         *
      **************************************************************************/
     @Override
-    protected NodePath<NGNode> computeRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion, int cullingIndex, BaseTransform tx,
+    protected RenderRootResult computeRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion, int cullingIndex, BaseTransform tx,
                                        GeneralTransform3D pvTx) {
 
         // If the NGGroup is completely outside the culling area, then we don't have to traverse down
         // to the children yo.
         if (cullingIndex != -1) {
             final int bits = cullingBits >> (cullingIndex*2);
-            if ((bits & 0x11) == 0) {
-                return null;
+            if ((bits & DIRTY_REGION_CONTAINS_OR_INTERSECTS_NODE_BOUNDS) == 0) {
+                return RenderRootResult.NONE;
             }
-            if ((bits & 0x10) != 0) {
-                cullingIndex = -1; // Do not check culling in children, 
+            if ((bits & DIRTY_REGION_CONTAINS_NODE_BOUNDS) != 0) {
+                cullingIndex = -1; // Do not check culling in children,
                                    // as culling bits are not set for fully interior groups
             }
         }
-        
+
         if (!isVisible()) {
-            return null;
+            return RenderRootResult.NONE;
         }
 
         if (getOpacity() != 1.0 || (getEffect() != null && getEffect().reducesOpaquePixels()) || needsBlending()) {
-            return null;
+            return RenderRootResult.NONE;
         }
 
         if (getClipNode() != null) {
             final NGNode clip = (NGNode)getClipNode();
             RectBounds clipBounds = clip.computeOpaqueRegion(TEMP_RECT_BOUNDS);
             if (clipBounds == null) {
-                return null;
+                return RenderRootResult.NONE;
             }
             TEMP_TRANSFORM.deriveWithNewTransform(tx).deriveWithConcatenation(getTransform()).deriveWithConcatenation(clip.getTransform());
             if (!checkBoundsInQuad(clipBounds, dirtyRegion, TEMP_TRANSFORM, pvTx)) {
-                return null;
+                return RenderRootResult.NONE;
             }
         }
 
@@ -368,18 +363,22 @@
         double mzz = tx.getMzz();
         double mzt = tx.getMzt();
         final BaseTransform chTx = tx.deriveWithConcatenation(getTransform());
-        NodePath childPath = null;
-        for (int i=children.size()-1; i>=0; i--) {
-            final NGNode child = (NGNode) children.get(i);
-            childPath = child.computeRenderRoot(path, dirtyRegion, cullingIndex, chTx, pvTx);
-            if (childPath != null) break;
+        RenderRootResult result = RenderRootResult.NONE;
+        int resultIdx;
+        for (resultIdx=children.size()-1; resultIdx>=0; resultIdx--) {
+            final NGNode child = children.get(resultIdx);
+            result = child.computeRenderRoot(path, dirtyRegion, cullingIndex, chTx, pvTx);
+            if (result != RenderRootResult.NONE) break;
         }
         // restore previous transform state
         tx.restoreTransform(mxx, mxy, mxz, mxt, myx, myy, myz, myt, mzx, mzy, mzz, mzt);
-        if (childPath != null) {
-            childPath.add(this);
+        if (result != RenderRootResult.NONE) {
+            if (result == RenderRootResult.HAS_RENDER_ROOT || dirty != DirtyFlag.CLEAN || childDirty) {
+                path.add(this);
+                result = RenderRootResult.HAS_RENDER_ROOT;
+            }
         }
-        return childPath;
+        return result;
     }
 
     @Override
@@ -391,7 +390,7 @@
 
         //set culling bits for this group first.
         super.markCullRegions(drc, cullingRegionsBitsOfParent, tx, pvTx);
-        
+
         //cullingRegionsBits == 0 group is outside all dirty regions
         // we can cull all children otherwise check children.
         // If none of the regions intersect this group, skip pre-culling
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java	Tue Aug 20 09:38:00 2013 -0700
@@ -115,7 +115,7 @@
      * where we have multi-threaded rasterization, we might need to make
      * this per-instance instead of static.
      */
-    protected static final BaseBounds TEMP_BOUNDS = new BoxBounds();
+    protected static final BoxBounds TEMP_BOUNDS = new BoxBounds();
     protected static final RectBounds TEMP_RECT_BOUNDS = new RectBounds();
     protected static final Affine3D TEMP_TRANSFORM = new Affine3D();
 
@@ -242,6 +242,11 @@
      */
     protected int cullingBits = 0x0;
 
+    static final int DIRTY_REGION_INTERSECTS_NODE_BOUNDS = 0x1;
+    static final int DIRTY_REGION_CONTAINS_NODE_BOUNDS = 0x2;
+    static final int DIRTY_REGION_CONTAINS_OR_INTERSECTS_NODE_BOUNDS =
+            DIRTY_REGION_INTERSECTS_NODE_BOUNDS | DIRTY_REGION_CONTAINS_NODE_BOUNDS;
+
     private RectBounds opaqueRegion = null;
     private boolean opaqueRegionInvalid = true;
     private DirtyHint hint;
@@ -685,7 +690,7 @@
 
     /***************************************************************************
      *                                                                         *
-     * Dirty States and Dirty Regions                                          *
+     * Dirty States                                                            *
      *                                                                         *
      **************************************************************************/
 
@@ -725,7 +730,7 @@
     /**
      * Mark the node as DIRTY_BY_TRANSLATION. This will call special cache invalidation
      */
-    public void markDirtyByTranslation() {
+    private void markDirtyByTranslation() {
         if (dirty == DirtyFlag.CLEAN) {
             if (parent != null && parent.dirty == DirtyFlag.CLEAN && !parent.childDirty) {
                 dirty = DirtyFlag.DIRTY_BY_TRANSLATION;
@@ -850,6 +855,16 @@
         }
     }
 
+    /***************************************************************************
+     *                                                                         *
+     * Dirty Regions                                                           *
+     *
+     * Need to add documentation about dirty regions and how they work. One    *
+     * thing to be aware of is that during the dirty region accumulation phase *
+     * we use precise floating point values, but during
+     *                                                                         *
+     **************************************************************************/
+
     /**
      * Accumulates and returns the dirty regions in transformed coordinates for
      * this node. This method is designed such that a single downward traversal
@@ -925,44 +940,44 @@
 
     /**
      * Accumulates the dirty region of a node.
-     * TODO: Only made protected for the sake of testing (see javafx-sg-prism tests) (RT-23957)
+     * TODO: Only made non-final for the sake of testing (see javafx-sg-prism tests) (RT-23957)
      */
-    protected int accumulateNodeDirtyRegion(final RectBounds clip,
-                                            final RectBounds dirtyRegionTemp,
-                                            final DirtyRegionContainer dirtyRegionContainer,
-                                            final BaseTransform tx,
-                                            final GeneralTransform3D pvTx) {
+    int accumulateNodeDirtyRegion(final RectBounds clip,
+                                  final RectBounds dirtyRegionTemp,
+                                  final DirtyRegionContainer dirtyRegionContainer,
+                                  final BaseTransform tx,
+                                  final GeneralTransform3D pvTx) {
 
         // Get the dirty bounds of this specific node in scene coordinates
-        BaseBounds bb = computeDirtyRegion(dirtyRegionTemp, tx, pvTx);
+        final BaseBounds bb = computeDirtyRegion(dirtyRegionTemp, tx, pvTx);
 
         // Note: dirtyRegion is strictly a 2D operation. We simply need the largest
         // rectangular bounds of bb. Hence the Z-axis projection of bb; taking
-        // minX, minY, maxX and maxY values from this point on.
-        dirtyRegionTemp.setMinX(bb.getMinX());
-        dirtyRegionTemp.setMinY(bb.getMinY());
-        dirtyRegionTemp.setMaxX(bb.getMaxX());
-        dirtyRegionTemp.setMaxY(bb.getMaxY());
+        // minX, minY, maxX and maxY values from this point on. Also, in many cases
+        // bb == dirtyRegionTemp. In fact, the only time this won't be true is if
+        // there is (or was) a perspective transform involved on this node.
+        if (bb != dirtyRegionTemp) {
+            bb.flattenInto(dirtyRegionTemp);
+        }
 
         // If my dirty region is empty, or if it doesn't intersect with the
-        // clip, then we can simply return the passed in dirty region since
-        // this node's dirty region is not helpful
+        // clip, then we can simply return since this node's dirty region is
+        // not helpful
         if (dirtyRegionTemp.isEmpty() || clip.disjoint(dirtyRegionTemp)) {
             return DirtyRegionContainer.DTR_OK;
         }
 
-        if (dirtyRegionTemp.getMinX() <= clip.getMinX() &&
-            dirtyRegionTemp.getMinY() <= clip.getMinY() &&
-            dirtyRegionTemp.getMaxX() >= clip.getMaxX() &&
-            dirtyRegionTemp.getMaxY() >= clip.getMaxY()) {
+        // If the clip is completely contained within the dirty region (including
+        // if they are equal) then we return DTR_CONTAINS_CLIP
+        if (dirtyRegionTemp.contains(clip)) {
             return DirtyRegionContainer.DTR_CONTAINS_CLIP;
         }
 
-        dirtyRegionTemp.setMinX(Math.max(dirtyRegionTemp.getMinX(), clip.getMinX()));
-        dirtyRegionTemp.setMinY(Math.max(dirtyRegionTemp.getMinY(), clip.getMinY()));
-        dirtyRegionTemp.setMaxX(Math.min(dirtyRegionTemp.getMaxX(), clip.getMaxX()));
-        dirtyRegionTemp.setMaxY(Math.min(dirtyRegionTemp.getMaxY(), clip.getMaxY()));
+        // The only overhead in calling intersectWith, and contains (above) is the repeated checking
+        // if the isEmpty state. But the code is cleaner and less error prone.
+        dirtyRegionTemp.intersectWith(clip);
 
+        // Add the dirty region to the container
         dirtyRegionContainer.addDirtyRegion(dirtyRegionTemp);
 
         return DirtyRegionContainer.DTR_OK;
@@ -973,9 +988,9 @@
      * using polymorphism because we wanted to centralize all of the dirty region
      * management code in one place, rather than having it spread between Prism,
      * Scenario, and any other future toolkits.
-     * TODO: Only made protected for the sake of testing (see javafx-sg-prism tests) (RT-23957)
+     * TODO: Only made non-final for the sake of testing (see javafx-sg-prism tests) (RT-23957)
      */
-    protected int accumulateGroupDirtyRegion(final RectBounds clip,
+    int accumulateGroupDirtyRegion(final RectBounds clip,
                                              final RectBounds dirtyRegionTemp,
                                              DirtyRegionPool regionPool,
                                              DirtyRegionContainer dirtyRegionContainer,
@@ -1042,10 +1057,7 @@
             try {
                 myClip = new RectBounds();
                 BaseBounds myClipBaseBounds = renderTx.inverseTransform(clip, TEMP_BOUNDS);
-                myClip.setBounds(myClipBaseBounds.getMinX(),
-                                 myClipBaseBounds.getMinY(),
-                                 myClipBaseBounds.getMaxX(),
-                                 myClipBaseBounds.getMaxY());
+                myClipBaseBounds.flattenInto(myClip);
             } catch (NoninvertibleTransformException ex) {
                 return DirtyRegionContainer.DTR_OK;
             }
@@ -1059,8 +1071,7 @@
             myClip = new RectBounds();
             BaseBounds clipBounds = clipNode.getCompleteBounds(myClip, renderTx);
             pvTx.transform(clipBounds, clipBounds);
-            myClip.deriveWithNewBounds(clipBounds.getMinX(), clipBounds.getMinY(), 0,
-                                         clipBounds.getMaxX(), clipBounds.getMaxY(), 0);
+            clipBounds.flattenInto(myClip);
             myClip.intersectWith(clip);
             dirtyRegionContainer = regionPool.checkOut();
         }
@@ -1083,15 +1094,15 @@
 
         List<NGNode> children = ((NGGroup) this).getChildren();
         int num = children.size();
-            for (int i=0; i<num && status == DirtyRegionContainer.DTR_OK; i++) {
+        for (int i=0; i<num && status == DirtyRegionContainer.DTR_OK; i++) {
             NGNode child = children.get(i);
             // The child will check the dirty bits itself. If we tested it here
             // (as we used to), we are just doing the check twice. True, it might
             // mean fewer method calls, but hotspot will probably inline this all
             // anyway, and doing the check in one place is less error prone.
-                status = child.accumulateDirtyRegions(myClip, dirtyRegionTemp, regionPool,
-                                                      dirtyRegionContainer, renderTx, pvTx);
-                if (status == DirtyRegionContainer.DTR_CONTAINS_CLIP) {
+            status = child.accumulateDirtyRegions(myClip, dirtyRegionTemp, regionPool,
+                                                  dirtyRegionContainer, renderTx, pvTx);
+            if (status == DirtyRegionContainer.DTR_CONTAINS_CLIP) {
                 break;
             }
         }
@@ -1146,13 +1157,17 @@
      * @param pvTx must not be null, it's the perspective transform of the current
      *        perspective camera or identity transform if parallel camera is used.
      */
-    private BaseBounds computeDirtyRegion(BaseBounds region,
-                                          BaseTransform tx,
-                                          GeneralTransform3D pvTx)
+    private BaseBounds computeDirtyRegion(final RectBounds dirtyRegionTemp,
+                                          final BaseTransform tx,
+                                          final GeneralTransform3D pvTx)
     {
         // The passed in region is a scratch object that exists for me to use,
         // such that I don't have to create a temporary object. So I just
-        // hijack it right here giving it the dirtyBounds.
+        // hijack it right here to start with. Note that any of the calls
+        // in computeDirtyRegion might end up changing the region instance
+        // from dirtyRegionTemp (which is a RectBounds) to a BoxBounds if any
+        // of the other bounds / transforms involve a perspective transformation.
+        BaseBounds region = dirtyRegionTemp;
         if (!dirtyBounds.isEmpty()) {
             region = region.deriveWithNewBounds(dirtyBounds);
         } else {
@@ -1221,13 +1236,13 @@
      * @param region Dirty region being processed.
      * @return Bit setting encoding node position to dirty region (without the shift)
      */
-    protected int setCullBits(BaseBounds bounds, int regionIndex, RectBounds region) {
+    protected int setCullBits(RectBounds bounds, int regionIndex, RectBounds region) {
         int b = 0;
         if (region != null && !region.isEmpty()) {
             if (region.intersects(bounds)) {
-                b = 1;
-                if (region.contains(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight())) {
-                    b = 2;
+                b = DIRTY_REGION_INTERSECTS_NODE_BOUNDS;
+                if (region.contains(bounds)) {
+                    b = DIRTY_REGION_CONTAINS_NODE_BOUNDS;
                 }
                 cullingBits = cullingBits |  (b << (2 * regionIndex));
             }
@@ -1253,7 +1268,7 @@
             int cullingRegionsBitsOfParent,
             BaseTransform tx,
             GeneralTransform3D pvTx) {
-        
+
         if (tx.isIdentity()) {
             TEMP_BOUNDS.deriveWithNewBounds(transformedBounds);
         } else {
@@ -1265,12 +1280,8 @@
                 pvTx.transform(TEMP_BOUNDS, TEMP_BOUNDS);
             }
         }
-        TEMP_BOUNDS.deriveWithNewBounds(TEMP_BOUNDS.getMinX(),
-                TEMP_BOUNDS.getMinY(),
-                0,
-                TEMP_BOUNDS.getMaxX(),
-                TEMP_BOUNDS.getMaxY(),
-                0);
+
+        TEMP_BOUNDS.flattenInto(TEMP_RECT_BOUNDS);
 
         cullingBits = 0;
         RectBounds region;
@@ -1282,20 +1293,20 @@
             }
             if (cullingRegionsBitsOfParent == -1 ||
                 (cullingRegionsBitsOfParent & mask) != 0) {
-                setCullBits(TEMP_BOUNDS, i, region);
+                setCullBits(TEMP_RECT_BOUNDS, i, region);
             }
             mask = mask << 2;
         }//for
-        
+
         // If we are going to cull a node/group that's dirty,
         // make sure it's dirty flags are properly cleared.
         if (cullingBits == 0 && (dirty != DirtyFlag.CLEAN || childDirty)) {
             clearDirtyTree();
         }
-        
+
         if (debug) {
             System.out.printf("%s bits: %s bounds: %s\n",
-                this, Integer.toBinaryString(cullingBits), TEMP_BOUNDS);
+                this, Integer.toBinaryString(cullingBits), TEMP_RECT_BOUNDS);
         }
     }
 
@@ -1316,38 +1327,69 @@
                 transformedBounds.getHeight());
     }
 
+    /***************************************************************************
+     *                                                                         *
+     * Identifying render roots                                                *
+     *                                                                         *
+     **************************************************************************/
+    protected static enum RenderRootResult {
+        /**
+         * The computation to determine whether a branch of the scene graph has
+         * a render root has concluded that indeed, there is one.
+         */
+        HAS_RENDER_ROOT,
+        /**
+         * A RenderRootResult of this value means that although we discovered a
+         * render root, we also determined that there were no dirty nodes that
+         * followed the render root. Therefore, we don't actually have to render
+         * anything (the only dirty nodes are completely occluded by clean
+         * nodes).
+         */
+        EXISTS_BUT_NOT_DIRTY,
+        /**
+         * Represents the case where we did not find an opaque node that covered
+         * the dirty region, and thus we must start rendering from the actual
+         * root of the hierarchy.
+         */
+        NONE
+    }
+
     /**
      * Called <strong>after</strong> preCullingBits in order to get the node
      * from which we should begin drawing. This is our support for occlusion culling.
      * This should only be called on the root node.
      *
      * @param path node path to store the node path
-     * @return new node path (preferably == path) with first node being a child of this node. Null if renderRoot == this.
+     * @return NodePath from path parameter with the first node being a child of this node.
+     * If not render root was found, the returned NodePath will be empty.
+     * If no rendering is needed (everything dirty is occluded), null is returned.
      */
     public final NodePath<NGNode> getRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion, int cullingIndex, BaseTransform tx,
-                                      GeneralTransform3D pvTx) {
+             GeneralTransform3D pvTx) {
         // The occlusion culling support depends on dirty opts being enabled
         if (PrismSettings.occlusionCullingEnabled) {
-            NodePath<NGNode> rootPath = computeRenderRoot(path, dirtyRegion, cullingIndex, tx, pvTx);
-            if (rootPath != null) {
-                rootPath.removeRoot();
-                return rootPath.size() != 0 ? rootPath : null;
+            RenderRootResult result = computeRenderRoot(path, dirtyRegion, cullingIndex, tx, pvTx);
+            if (result == RenderRootResult.EXISTS_BUT_NOT_DIRTY) {
+                return null;
+            }
+            if (result == RenderRootResult.HAS_RENDER_ROOT) {
+                path.removeRoot();
             }
         }
-        return null;
+        return path;
     }
-    
+
     /**
      * Searches for the last node that covers all of the specified dirty region with opaque region,
      * in this node's subtree.
-     * Such node can serve as a rendering root as all nodes preceding the node will be covered by it. 
+     * Such node can serve as a rendering root as all nodes preceding the node will be covered by it.
      * @param dirtyRegion the current dirty region
      * @param cullingIndex index of culling information
      * @param tx current transform
      * @param pvTx current perspective transform
      * @return New rendering root or null if no such node exists in this subtree
      */
-    protected NodePath<NGNode> computeRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion, int cullingIndex, BaseTransform tx,
+    protected RenderRootResult computeRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion, int cullingIndex, BaseTransform tx,
                                        GeneralTransform3D pvTx) {
         return computeNodeRenderRoot(path, dirtyRegion, cullingIndex, tx, pvTx);
     }
@@ -1365,23 +1407,23 @@
         int ccw12 = ccw(x, y, rect[1], rect[2]);
         int ccw23 = ccw(x, y, rect[2], rect[3]);
         int ccw31 = ccw(x, y, rect[3], rect[0]);
-       
+
         // Possible results after this operation:
         // 0 -> 0 (0x0)
         // 1 -> 1 (0x1)
         // -1 -> Integer.MIN_VALUE (0x80000000)
-        ccw01 ^= (ccw01 >>> 1); 
-        ccw12 ^= (ccw12 >>> 1); 
-        ccw23 ^= (ccw23 >>> 1); 
-        ccw31 ^= (ccw31 >>> 1); 
-        
+        ccw01 ^= (ccw01 >>> 1);
+        ccw12 ^= (ccw12 >>> 1);
+        ccw23 ^= (ccw23 >>> 1);
+        ccw31 ^= (ccw31 >>> 1);
+
         final int union = ccw01 | ccw12 | ccw23 | ccw31;
         // This means all ccw* were either (-1 or 0) or (1 or 0), but not all of them were 0
         return union == 0x80000000 || union == 0x1;
         // Or alternatively...
 //        return (union ^ (union << 31)) < 0;
     }
-        
+
     /**
      * Check if this node can serve as rendering root for this dirty region.
      * @param dirtyRegion the current dirty region
@@ -1390,45 +1432,47 @@
      * @param pvTx current perspective transform
      * @return this node if this node's opaque region covers the specified dirty region. Null otherwise.
      */
-    protected final NodePath<NGNode> computeNodeRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion, int cullingIndex, BaseTransform tx,
+    protected final RenderRootResult computeNodeRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion, int cullingIndex, BaseTransform tx,
                                        GeneralTransform3D pvTx) {
-        
+
         // Nodes outside of the dirty region can be excluded immediately.
         // This can be used only if the culling information is provided.
         if (cullingIndex != -1) {
             final int bits = cullingBits >> (cullingIndex * 2);
-            if ((bits & 0x11) == 0x00) { // The node is neither fully interior (0x10)
-                                         // nor intersecting (0x01) the dirty region 
-                return null;
+            if ((bits & DIRTY_REGION_CONTAINS_OR_INTERSECTS_NODE_BOUNDS) == 0x00) {
+                return RenderRootResult.NONE;
             }
         }
-        
+
         if (!isVisible()) {
-            return null;
+            return RenderRootResult.NONE;
         }
 
-        // Walk down the tree to the very end. Then working our way back up to
-        // the top of the tree, look for the first node which which marked as
-        // dirty opts 01, and then return it.
+
         final RectBounds opaqueRegion = getOpaqueRegion();
-        if (opaqueRegion == null) return null;
-        
+        if (opaqueRegion == null) return RenderRootResult.NONE;
+
         final BaseTransform localToParentTx = getTransform();
 
         BaseTransform localToSceneTx = TEMP_TRANSFORM.deriveWithNewTransform(tx).deriveWithConcatenation(localToParentTx);
-        
+
         // Now check if the dirty region is fully contained in our opaque region.
         if (checkBoundsInQuad(opaqueRegion, dirtyRegion, localToSceneTx, pvTx)) {
+            // We have the potential render root, now check if it needs to be rendered
+            if (dirty != DirtyFlag.CLEAN) {
                 path.add(this);
-                return path;
+                return RenderRootResult.HAS_RENDER_ROOT;
+            } else {
+                return RenderRootResult.EXISTS_BUT_NOT_DIRTY;
+            }
         }
 
-        return null;
+        return RenderRootResult.NONE;
     }
-    
+
     protected static boolean checkBoundsInQuad(RectBounds untransformedQuad,
             RectBounds innerBounds, BaseTransform tx, GeneralTransform3D pvTx) {
-        
+
         if ((pvTx == null || pvTx.isIdentity()) && (tx.getType() & ~(BaseTransform.TYPE_TRANSLATION
                 | BaseTransform.TYPE_QUADRANT_ROTATION
                 | BaseTransform.TYPE_MASK_SCALE)) == 0) {
@@ -1440,15 +1484,9 @@
                 tx.transform(untransformedQuad, TEMP_BOUNDS);
             }
 
-            TEMP_BOUNDS.deriveWithNewBounds(TEMP_BOUNDS.getMinX(),
-                    TEMP_BOUNDS.getMinY(),
-                    0,
-                    TEMP_BOUNDS.getMaxX(),
-                    TEMP_BOUNDS.getMaxY(),
-                    0);
+            TEMP_BOUNDS.flattenInto(TEMP_RECT_BOUNDS);
 
-            return (TEMP_BOUNDS.contains(innerBounds.getMinX(), innerBounds.getMinY())
-                    && TEMP_BOUNDS.contains(innerBounds.getMaxX(), innerBounds.getMaxY()));
+            return TEMP_RECT_BOUNDS.contains(innerBounds);
         } else {
             TEMP_POINTS2D_4[0].setLocation(untransformedQuad.getMinX(), untransformedQuad.getMinY());
             TEMP_POINTS2D_4[1].setLocation(untransformedQuad.getMaxX(), untransformedQuad.getMinY());
@@ -1534,11 +1572,12 @@
         if (PrismSettings.dirtyOptsEnabled) {
             if (g.hasPreCullingBits()) {
                 //preculling bits available
-                if ((cullingBits & (0x3 << (g.getClipRectIndex() * 2))) == 0) {
+                final int bits = cullingBits >> (g.getClipRectIndex() * 2);
+                if ((bits & DIRTY_REGION_CONTAINS_OR_INTERSECTS_NODE_BOUNDS) == 0) {
                     // If no culling bits are set for this region, this group
                     // does not intersect (nor is covered by) the region
                     return;
-                } else if ((cullingBits & (0x2 << (g.getClipRectIndex() * 2))) != 0) {
+                } else if ((bits & DIRTY_REGION_CONTAINS_NODE_BOUNDS) != 0) {
                     // When this group is fully covered by the region,
                     // turn off the culling checks in the subtree, as everything
                     // gets rendered
@@ -1601,12 +1640,12 @@
         if (preCullingTurnedOff) {
             g.setHasPreCullingBits(true);
         }
-        
+
         // restore previous transform state
         g.setTransform3D(mxx, mxy, mxz, mxt,
                          myx, myy, myz, myt,
                          mzx, mzy, mzz, mzt);
-        
+
         // restore previous depth test state
         g.setDepthTest(prevDepthTest);
 
@@ -1826,7 +1865,7 @@
     private void renderOpacity(Graphics g) {
         if (getEffectFilter() != null ||
             getCacheFilter() != null ||
-            getClipNode() != null || 
+            getClipNode() != null ||
             !hasOverlappingContents())
         {
             // if the node has a non-null effect or cached==true, we don't
@@ -1957,7 +1996,7 @@
         public boolean reducesOpaquePixels() {
             return false;
         }
-        
+
         @Override
         public DirtyRegionContainer getDirtyRegions(Effect defaultInput, DirtyRegionPool regionPool) {
             return null; //Never called
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGPhongMaterial.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGPhongMaterial.java	Tue Aug 20 09:38:00 2013 -0700
@@ -48,6 +48,7 @@
     private boolean specularColorDirty = true;
     private float specularPower;
     private boolean specularPowerDirty = true;
+    private boolean hasSpecularMap = false;
     private TextureMap specularMap = new TextureMap(PhongMaterial.MapType.SPECULAR);
 
     private TextureMap bumpMap = new TextureMap(PhongMaterial.MapType.BUMP);
@@ -89,7 +90,7 @@
         }
         if (specularMap.isDirty() || specularColorDirty || specularPowerDirty) {
             Image specular = specularMap.getImage();
-            if (specular == null && specularColor != null) {
+            if (!hasSpecularMap && specularColor != null) {
                 int ia = (int) (255.0 * specularPower);
                 int ir = (int) (255.0 * specularColor.getRed());
                 int ig = (int) (255.0 * specularColor.getGreen());
@@ -98,6 +99,9 @@
 
                 if (ir != 0 || ig != 0 || ib != 0) {
                     specular = Image.fromIntArgbPreData(new int[]{pixel}, 1, 1);
+                    // NOTE: Need to manually mark specularMap dirty when it is
+                    // a color so that native texture can be updated.
+                    specularMap.setDirty(true);
                 }
             }
             specularMap.setImage(specular);
@@ -130,6 +134,7 @@
     public void setSpecularMap(Object specularMap) {
         this.specularMap.setImage((Image)specularMap);
         this.specularMap.setDirty(true);
+        hasSpecularMap = specularMap != null ? true : false;
     }
 
     public void setBumpMap(Object bumpMap) {
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGRegion.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGRegion.java	Tue Aug 20 09:38:00 2013 -0700
@@ -436,17 +436,17 @@
         return null;
     }
 
-    @Override protected NodePath<NGNode> computeRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion,
+    @Override protected RenderRootResult computeRenderRoot(NodePath<NGNode> path, RectBounds dirtyRegion,
                                                            int cullingIndex, BaseTransform tx,
                                                            GeneralTransform3D pvTx) {
 
-        NodePath<NGNode> childPath = super.computeRenderRoot(path, dirtyRegion, cullingIndex, tx, pvTx);
-        if (childPath != null) {
-            childPath.add(this);
+        RenderRootResult result = super.computeRenderRoot(path, dirtyRegion, cullingIndex, tx, pvTx);
+        if (result == RenderRootResult.HAS_RENDER_ROOT) {
+            path.add(this);
         } else {
-            childPath = computeNodeRenderRoot(path, dirtyRegion, cullingIndex, tx, pvTx);
+            result = computeNodeRenderRoot(path, dirtyRegion, cullingIndex, tx, pvTx);
         }
-        return childPath;
+        return result;
     }
 
     @Override protected boolean hasVisuals() {
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NodePath.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NodePath.java	Tue Aug 20 09:38:00 2013 -0700
@@ -30,17 +30,17 @@
 
 /**
  * Simple a reusable storage for root-to-node path.
- * 
+ *
  */
 public class NodePath<N extends NGNode> {
     private List<N> path = new ArrayList<>();
     private int position;
-    
+
     public NodePath() {
     }
-    
+
     // ITERATION methods
-    
+
     public N getCurrentNode() {
         return path.get(position);
     }
@@ -55,27 +55,27 @@
         }
         position--;
     }
-    
+
     public void reset() {
         position = path.size() - 1;
     }
-    
+
     // MODIFICATION methods
-    
+
     public void clear() {
         position = -1;
         path.clear();
     }
-    
+
     public void add(N n) {
         path.add(n);
         position = path.size() - 1;
     }
-    
+
     public int size() {
         return path.size();
     }
-    
+
     /*
      * Remove root and set to beginning.
      */
@@ -84,4 +84,8 @@
         position = path.size() - 1;
     }
 
+    boolean isEmpty() {
+        return size() == 0;
+    }
+
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/text/GlyphLayout.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/text/GlyphLayout.java	Tue Aug 20 09:38:00 2013 -0700
@@ -209,6 +209,7 @@
                 boolean spanChanged = i >= spanEnd;
                 boolean levelChanged = i >= bidiEnd;
                 boolean scriptChanged = false;
+                boolean oldComplex = complex;
                 if (checkComplex) {
                     if (Character.isHighSurrogate(ch)) {
                         /* Only merge surrogate when the pair is in the same span. */
@@ -232,7 +233,7 @@
                     if (start != i) {
                         /* Create text run */
                         run = addTextRun(layout, chars, start, i - start,
-                                         font, span, bidiLevel, complex);
+                                         font, span, bidiLevel, oldComplex);
                        if (complex) {
                            flags |= FLAGS_HAS_COMPLEX;
                            complex = false;
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java	Tue Aug 20 09:38:00 2013 -0700
@@ -54,6 +54,7 @@
 
 abstract class ViewPainter implements Runnable {
     private static final NodePath<NGNode> NODE_PATH = new NodePath<>();
+    private static final NodePath<NGNode> EMPTY_NODE_PATH = new NodePath<>();
 
     /*
      * This could be a per-scene lock but there is no guarantee that the
@@ -68,7 +69,7 @@
     protected int penHeight = -1;
     protected int viewWidth;
     protected int viewHeight;
-    
+
     protected final SceneState sceneState;
 
     protected Presentable presentable;
@@ -107,7 +108,7 @@
             dirtyRegionContainer = dirtyRegionPool.checkOut();
         }
     }
-        
+
     protected void setRoot(NGNode node) {
         root = node;
     }
@@ -188,7 +189,7 @@
 
                     // Disable occlusion culling if depth buffer is enabled for the scene.
                     if (sceneState.getScene().getDepthBuffer()) {
-                        doPaint(g, null);
+                        doPaint(g, EMPTY_NODE_PATH);
                     } else {
                         doPaint(g, root.getRenderRoot(NODE_PATH, dirtyRegion, i, tx, projTx));
                         NODE_PATH.clear();
@@ -198,7 +199,7 @@
         } else {
             g.setHasPreCullingBits(false);
             g.setClipRect(null);
-            this.doPaint(g, null);
+            this.doPaint(g, EMPTY_NODE_PATH);
         }
 
         if (PrismSettings.showDirtyRegions) {
@@ -265,8 +266,8 @@
 
     protected boolean validateStageGraphics() {
         if (!sceneState.isValid()) {
-            // indicates something happened between the scheduling of the 
-            // job and the running of this job. 
+            // indicates something happened between the scheduling of the
+            // job and the running of this job.
             return false;
         }
 
@@ -275,11 +276,17 @@
 
         return sceneState.isWindowVisible() && !sceneState.isWindowMinimized();
     }
-    
+
     private void doPaint(Graphics g, NodePath<NGNode> renderRootPath) {
         if (PrismSettings.showDirtyRegions) {
             g.setClipRect(null);
         }
+        if (renderRootPath == null) {
+            // null render path indicates that no rendering is needed.
+            // There may be occluded dirty Nodes however, so we need to clear them
+            root.clearDirtyTree();
+            return;
+        }
         long start = PULSE_LOGGING_ENABLED ? System.currentTimeMillis() : 0;
         try {
             GlassScene scene = sceneState.getScene();
@@ -307,5 +314,5 @@
             }
         }
     }
-    
+
 }
--- a/modules/graphics/src/main/java/com/sun/prism/es2/GLPixelFormat.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/com/sun/prism/es2/GLPixelFormat.java	Tue Aug 20 09:38:00 2013 -0700
@@ -43,7 +43,7 @@
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 
             public Void run() {
-               defaultDepthSize = Integer.getInteger("egl.depthSize", 24);
+               defaultDepthSize = Integer.getInteger("prism.glDepthSize", 24);
                defaultBufferSize = Integer.getInteger("prism.glBufferSize", 32);
                 return null;
             }
--- a/modules/graphics/src/main/java/javafx/scene/Scene.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/Scene.java	Tue Aug 20 09:38:00 2013 -0700
@@ -358,6 +358,7 @@
         }
 
         Toolkit.getToolkit().checkFxUserThread();
+        init();
         setRoot(root);
         init(width, height);
         setFill(fill);
@@ -1383,10 +1384,6 @@
         addSnapshotRunnable(snapshotRunnable);
     }
 
-    // lets us know when initialized so our triggers can be a bit more effective
-    boolean initialized = false;
-    // This does not push changes to peer because cursor updates are pushed on mouse events
-
     /**
      * Defines the mouse cursor for this {@code Scene}.
      */
@@ -1478,7 +1475,6 @@
             setHeight((float)height);
         }
         sizeInitialized = (widthSetByUser >= 0 && heightSetByUser >= 0);
-        init();
     }
 
     private void init() {
@@ -1488,8 +1484,6 @@
         mouseHandler = new MouseHandler();
         clickGenerator = new ClickGenerator();
 
-        initialized = true;
-
         if (PerformanceTracker.isLoggingEnabled()) {
             PerformanceTracker.logEvent("Scene.init for [" + this + "] - finished");
         }
--- a/modules/graphics/src/main/java/javafx/scene/paint/PhongMaterial.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/paint/PhongMaterial.java	Tue Aug 20 09:38:00 2013 -0700
@@ -25,8 +25,10 @@
 
 package javafx.scene.paint;
 
+import com.sun.javafx.beans.event.AbstractNotifyListener;
 import com.sun.javafx.sg.prism.NGPhongMaterial;
 import com.sun.javafx.tk.Toolkit;
+import javafx.beans.Observable;
 import javafx.beans.property.DoubleProperty;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleDoubleProperty;
@@ -159,6 +161,26 @@
         return specularPower;
     }
 
+    private final AbstractNotifyListener platformImageChangeListener = new AbstractNotifyListener() {
+        @Override
+        public void invalidated(Observable valueModel) {
+            if (oldDiffuseMap != null
+                    && valueModel == Toolkit.getImageAccessor().getImageProperty(oldDiffuseMap)) {
+                diffuseMapDirty = true;
+            } else if (oldSpecularMap != null
+                    && valueModel == Toolkit.getImageAccessor().getImageProperty(oldSpecularMap)) {
+                specularMapDirty = true;
+            } else if (oldBumpMap != null
+                    && valueModel == Toolkit.getImageAccessor().getImageProperty(oldBumpMap)) {
+                bumpMapDirty = true;
+            } else if (oldSelfIlluminationMap != null
+                    && valueModel == Toolkit.getImageAccessor().getImageProperty(oldSelfIlluminationMap)) {
+                selfIlluminationMapDirty = true;
+            }
+            setDirty(true);
+        }
+    };
+
     /**
      * The diffuse map of this {@code PhongMaterial).
      *
@@ -175,12 +197,31 @@
         return diffuseMap == null ? null : diffuseMap.get();
     }
 
+    private Image oldDiffuseMap;
     public final ObjectProperty<Image> diffuseMapProperty() {
         if (diffuseMap == null) {
             diffuseMap = new SimpleObjectProperty<Image>(PhongMaterial.this,
                     "diffuseMap") {
+
+                private boolean needsListeners = false;
+
                 @Override
                 public void invalidated() {
+                    Image _image = get();
+
+                    if (needsListeners) {
+                        Toolkit.getImageAccessor().getImageProperty(oldDiffuseMap).
+                                removeListener(platformImageChangeListener.getWeakListener());
+                    }
+
+                    needsListeners = _image != null && (Toolkit.getImageAccessor().isAnimation(_image)
+                            || _image.getProgress() < 1);
+                    
+                    if (needsListeners) {
+                        Toolkit.getImageAccessor().getImageProperty(_image).
+                                addListener(platformImageChangeListener.getWeakListener());
+                    }
+                    oldDiffuseMap = _image;
                     diffuseMapDirty = true;
                     setDirty(true);
                 }
@@ -205,12 +246,32 @@
         return specularMap == null ? null : specularMap.get();
     }
 
+    private Image oldSpecularMap;
     public final ObjectProperty<Image> specularMapProperty() {
         if (specularMap == null) {
             specularMap = new SimpleObjectProperty<Image>(PhongMaterial.this,
                     "specularMap") {
+
+                private boolean needsListeners = false;
+
                 @Override
                 public void invalidated() {
+                    Image _image = get();
+
+                    if (needsListeners) {
+                        Toolkit.getImageAccessor().getImageProperty(oldSpecularMap).
+                                removeListener(platformImageChangeListener.getWeakListener());
+                    }
+
+                    needsListeners = _image != null && (Toolkit.getImageAccessor().isAnimation(_image)
+                            || _image.getProgress() < 1);
+                    
+                    if (needsListeners) {
+                        Toolkit.getImageAccessor().getImageProperty(_image).
+                                addListener(platformImageChangeListener.getWeakListener());
+                    }
+
+                    oldSpecularMap = _image;
                     specularMapDirty = true;
                     setDirty(true);
                 }
@@ -235,12 +296,32 @@
         return bumpMap == null ? null : bumpMap.get();
     }
 
+    private Image oldBumpMap;
     public final ObjectProperty<Image> bumpMapProperty() {
         if (bumpMap == null) {
             bumpMap = new SimpleObjectProperty<Image>(PhongMaterial.this,
                     "bumpMap") {
+                        
+                private boolean needsListeners = false;
+
                 @Override
                 public void invalidated() {
+                    Image _image = get();
+
+                    if (needsListeners) {
+                        Toolkit.getImageAccessor().getImageProperty(oldBumpMap).
+                                removeListener(platformImageChangeListener.getWeakListener());
+                    }
+
+                    needsListeners = _image != null && (Toolkit.getImageAccessor().isAnimation(_image)
+                            || _image.getProgress() < 1);
+
+                    if (needsListeners) {
+                        Toolkit.getImageAccessor().getImageProperty(_image).
+                                addListener(platformImageChangeListener.getWeakListener());
+                    }
+
+                    oldBumpMap = _image;
                     bumpMapDirty = true;
                     setDirty(true);
                 }
@@ -264,13 +345,33 @@
     public final Image getSelfIlluminationMap() {
         return selfIlluminationMap == null ? null : selfIlluminationMap.get();
     }
-    
+
+    private Image oldSelfIlluminationMap;
     public final ObjectProperty<Image> selfIlluminationMapProperty() {
         if (selfIlluminationMap == null) {
             selfIlluminationMap = new SimpleObjectProperty<Image>(PhongMaterial.this,
                     "selfIlluminationMap") {
+
+                private boolean needsListeners = false;
+                
                 @Override
                 public void invalidated() {
+                    Image _image = get();
+
+                    if (needsListeners) {
+                        Toolkit.getImageAccessor().getImageProperty(oldSelfIlluminationMap).
+                                removeListener(platformImageChangeListener.getWeakListener());
+                    }
+                    
+                    needsListeners = _image != null && (Toolkit.getImageAccessor().isAnimation(_image)
+                            || _image.getProgress() < 1);
+
+                    if (needsListeners) {
+                        Toolkit.getImageAccessor().getImageProperty(_image).
+                                addListener(platformImageChangeListener.getWeakListener());
+                    }
+
+                    oldSelfIlluminationMap = _image;
                     selfIlluminationMapDirty = true;
                     setDirty(true);
                 }
--- a/modules/graphics/src/main/java/javafx/scene/shape/Shape3D.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/shape/Shape3D.java	Tue Aug 20 09:38:00 2013 -0700
@@ -100,8 +100,7 @@
     private final ChangeListener<Boolean> materialListener = new ChangeListener<Boolean>() {
         @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
             if (newValue) {
-                impl_markDirty(DirtyBits.MATERIAL_PROPERTY);
-                //impl_geomChanged();
+                impl_markDirty(DirtyBits.MATERIAL);
             }
         }
     };
@@ -216,13 +215,7 @@
     @Override
     public void impl_updatePeer() {
         super.impl_updatePeer();
-
-        // TODO: 3D - Why do we have separate dirty bits for MATERIAL
-        // and MATERIAL_PROPERTY ?
         Material material = getMaterial();
-        if (impl_isDirty(DirtyBits.MATERIAL_PROPERTY) && material != null) {
-            material.impl_updatePG();
-        }
         final NGShape3D peer = impl_getPeer();
         if (impl_isDirty(DirtyBits.MATERIAL)) {
             if (material != null) {
--- a/modules/graphics/src/main/java/javafx/scene/text/Text.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/text/Text.java	Tue Aug 20 09:38:00 2013 -0700
@@ -157,6 +157,10 @@
 
     private void checkSpan() {
         isSpan = isManaged() && getParent() instanceof TextFlow;
+        if (isSpan() && !pickOnBoundsProperty().isBound()) {
+            /* Documented behavior. See class description for TextFlow */
+            setPickOnBounds(false);
+        }
     }
 
     private void checkOrientation() {
@@ -758,23 +762,6 @@
     }
 
     /**
-     * Defines how the picking computation is done for this text node when
-     * triggered by a {@code MouseEvent} or a {@code contains} function call.
-     *
-     * If {@code pickOnBounds} is true, then picking is computed by
-     * intersecting with the bounds of this text node, else picking is computed
-     * by intersecting with the individual characters (geometric shape) of this
-     * text node.
-     * Picking based on bounds is more efficient and allows the spaces within
-     * and between characters to be picked.
-     *
-     * @defaultValue true
-     */
-    //@GenerateProperty private boolean pickOnBounds = true;
-
-    // private API to enable cursor and selection for text editing control
-
-    /**
      * @treatAsPrivate implementation detail
      * @deprecated This is an internal API that is not intended
      * for use and will be removed in the next version
@@ -1082,6 +1069,8 @@
     }
 
     private float getYRendering() {
+        if (isSpan()) return 0;
+
         /* Always logical for rendering */
         BaseBounds bounds = getLogicalBounds();
 
@@ -1230,8 +1219,24 @@
     @Deprecated
     @Override
     protected final boolean impl_computeContains(double localX, double localY) {
-        //TODO Presently only support bounds based picking.
-        return true;
+        /* Used for spans, regular text uses bounds based picking */
+        double x = localX + getSpanBounds().getMinX();
+        double y = localY + getSpanBounds().getMinY();
+        GlyphList[] runs = getRuns();
+        if (runs.length != 0) {
+            for (int i = 0; i < runs.length; i++) {
+                GlyphList run = runs[i];
+                com.sun.javafx.geom.Point2D location = run.getLocation();
+                float width = run.getWidth();
+                RectBounds lineBounds = run.getLineBounds();
+                float height = lineBounds.getHeight();
+                if (location.x <= x && x < location.x + width &&
+                    location.y <= y && y < location.y + height) {
+                        return true;
+                }
+            }
+        }
+        return false;
     }
 
     /**
--- a/modules/graphics/src/main/java/javafx/scene/text/TextFlow.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/java/javafx/scene/text/TextFlow.java	Tue Aug 20 09:38:00 2013 -0700
@@ -77,7 +77,11 @@
  * For example, the x and y properties of the {@link Text} node are ignored since
  * the location of the node is determined by the parent. Likewise, the wrapping
  * width in the {@link Text} node is ignored since the width used for wrapping
- * is the TextFlow's width.
+ * is the TextFlow's width. The value of the <code>pickOnBounds</code> property
+ * of a {@link Text} is set to <code>false</code> when it is laid out by the
+ * TextFlow. This happens because the content of a single {@link Text} node can
+ * divided and placed in the different locations on the TextFlow (usually due to
+ * line breaking and bidi reordering).
  *
  * <p>
  * The wrapping width of the layout is determined by the region's current width.
--- a/modules/graphics/src/main/native-glass/lens/LensApplication.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/LensApplication.c	Tue Aug 20 09:38:00 2013 -0700
@@ -55,6 +55,7 @@
 static jmethodID jLensApplication_notifyMouseEvent;
 static jmethodID jLensApplication_notifyScrollEvent;
 static jmethodID jLensApplication_notifyTouchEvent;
+static jmethodID jLensApplication_notifyMultiTouchEvent;
 static jmethodID jLensApplication_notifyWindowResize;
 static jmethodID jLensApplication_notifyWindowMove;
 static jmethodID jLensApplication_notifyWindowEvent;
@@ -134,6 +135,9 @@
     jLensApplication_notifyTouchEvent = (*env)->GetMethodID(
                                             env, jLensApplicationClass, "notifyTouchEvent",
                                             "(Lcom/sun/glass/ui/lens/LensView;IJIIII)V");
+    jLensApplication_notifyMultiTouchEvent = (*env)->GetMethodID(
+                                            env, jLensApplicationClass, "notifyMultiTouchEvent",
+                                            "(Lcom/sun/glass/ui/lens/LensView;[I[J[I[III)V");
     jLensApplication_notifyWindowResize =
         (*env)->GetMethodID(env, jLensApplicationClass, "notifyWindowResize",
                             "(Lcom/sun/glass/ui/lens/LensWindow;III)V");
@@ -494,42 +498,59 @@
                                         int y,
                                         int xabs,
                                         int yabs) {
+    int dx = x - xabs;
+    int dy = y - yabs;
+    glass_application_notifyMultiTouchEvent(env, window, 1, &state, &id,
+                                            &xabs, &yabs, dx, dy);
+}
 
-    int button = com_sun_glass_events_MouseEvent_BUTTON_NONE;
-    int eventType = -1;
+void glass_application_notifyMultiTouchEvent(JNIEnv *env,
+                                             NativeWindow window,
+                                             int count,
+                                             jint *states,
+                                             jlong *ids,
+                                             int *xs,
+                                             int *ys,
+                                             int dx,
+                                             int dy) {
 
     if (!pApplication) {
         return;
     }
 
-    GLASS_LOG_FINEST("JNI call notifyTouchEvent");
-
     if (window->isEnabled) {
         if (window->view == NULL || window->view->lensView == NULL) {
             GLASS_LOG_WARNING("skipping notifyTouchEvent with NULL view");
             return;
         }
         jobject jview = window->view->lensView;
-
-        button = com_sun_glass_events_MouseEvent_BUTTON_LEFT;
-
-        if (state == com_sun_glass_events_TouchEvent_TOUCH_PRESSED) {
-            eventType = com_sun_glass_events_MouseEvent_DOWN;
-        } else if (state == com_sun_glass_events_TouchEvent_TOUCH_RELEASED) {
-            eventType = com_sun_glass_events_MouseEvent_UP;
-        } else if (state == com_sun_glass_events_TouchEvent_TOUCH_MOVED) {
-            eventType = com_sun_glass_events_MouseEvent_MOVE;
+        if (count == 1) {
+            GLASS_LOG_FINEST("JNI call notifyTouchEvent");
+            (*env)->CallVoidMethod(env, pApplication,
+                                   jLensApplication_notifyTouchEvent,
+                                   jview,
+                                   states[0], ids[0], xs[0] + dx, ys[0] + dy,
+                                   xs[0], ys[0]);
         } else {
-            GLASS_LOG_SEVERE("Unexpected touch state : %d", state);
+            int i;
+            jlongArray idArray = (*env)->NewLongArray(env, count);
+            jintArray stateArray = (*env)->NewIntArray(env, count);
+            jintArray xArray = (*env)->NewIntArray(env, count);
+            jintArray yArray = (*env)->NewIntArray(env, count);
+            (*env)->SetLongArrayRegion(env, idArray, 0, count, ids);
+            (*env)->SetIntArrayRegion(env, stateArray, 0, count, states);
+            (*env)->SetIntArrayRegion(env, xArray, 0, count, xs);
+            (*env)->SetIntArrayRegion(env, yArray, 0, count, ys);
+            GLASS_LOG_FINEST("JNI call notifyMultiTouchEvent");
+            (*env)->CallVoidMethod(env, pApplication,
+                                   jLensApplication_notifyMultiTouchEvent,
+                                   jview,
+                                   stateArray, idArray, xArray, yArray, dx, dy);
+            (*env)->DeleteLocalRef(env, idArray);
+            (*env)->DeleteLocalRef(env, stateArray);
+            (*env)->DeleteLocalRef(env, xArray);
+            (*env)->DeleteLocalRef(env, yArray);
         }
-
-        glass_inputEvents_updateMouseButtonModifiers(button, eventType);
-
-
-        (*env)->CallVoidMethod(env, pApplication,
-                               jLensApplication_notifyTouchEvent,
-                               jview,
-                               state, id, x, y, xabs, yabs);
         (void)glass_application_checkReportException(env);
     } else {
         GLASS_LOG_FINE("Window %d[%p] is disabled - sending FOCUS_DISABLED event",
--- a/modules/graphics/src/main/native-glass/lens/LensCommon.h	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/LensCommon.h	Tue Aug 20 09:38:00 2013 -0700
@@ -427,6 +427,30 @@
                                         int xabs,
                                         int yabs);
 
+ /**
+ * Notify LensApplication of a multitouch event
+ *
+ * @param env
+ * @param lensApplication A reference to LenApplication object
+ * @param lensWindow A reference to LensWindow object
+ * @param states the state of the finger locations (e.g.
+ * TouchEvent.TOUCH_PRESSED)
+ * @param ids The event IDs
+ * @param xs x absolute positions
+ * @param ys y absolute positions
+ * @param dx value to be added to x values to make them relative to the window
+ * @param dy value to be added to y values to make them relative to the window
+ */
+void glass_application_notifyMultiTouchEvent(JNIEnv *env,
+                                             NativeWindow window,
+                                             int count,
+                                             jint *states,
+                                             jlong *ids,
+                                             int *xs,
+                                             int *ys,
+                                             int dx,
+                                             int dy);
+
 
 
 
@@ -1498,100 +1522,6 @@
 void glass_cursor_terminate(void);
 
 
+#include "LensLogger.h"
 
-/////////// Logging
-
-/**
- * Initialize the Glass logger
- *
- * Called from JNI_OnLoad
- */
-void glass_logger_init();
-
-/**
- * Log a message at the given logging level.
- * Not used directly. GLASS_LOG should be used instead.
- */
-void glass_logf(int level,
-                const char *func,
-                const char *file,
-                int line,
-                const char *format, ...);
-
-
-/**
- * Write a C and Java backtrace to stderr
- */
-void glass_backtrace();
-
-/**
- * The logging level.
- * Not used directly. GLASS_LOG and GLASS_IF_LOG should be used instead.
- */
-extern jint glass_log_level;
-
-/**
- * Begins a conditional statement that is only run if the current logging level
- * is less than or equal to "level".
- * For example, GLASS_IF_LOG(LOG_WARNING) { f(); } will call f() if and only if
- * the current logging settings include printing warning messages.
- * @param level The logging level to be tested against.
- */
-#define GLASS_IF_LOG(level) if (level >= glass_log_level)
-
-/**
- * Logs a message at the given logging level
- * @param level the logging level (e.g. LOG_WARNING)
- * @param ... a format string and parameters in printf format
- */
-/** Logging levels, with same meanings as in java.util.logging.Level */
-#define GLASS_LOG_LEVEL_SEVERE  1000
-#define GLASS_LOG_LEVEL_WARNING 900
-#define GLASS_LOG_LEVEL_INFO    800
-#define GLASS_LOG_LEVEL_CONFIG  700
-#define GLASS_LOG_LEVEL_FINE    500
-#define GLASS_LOG_LEVEL_FINER   400
-#define GLASS_LOG_LEVEL_FINEST  300
-
-#ifdef ANDROID_NDK
-// Can't use java logger in jvm8 on Android. Remove when this issue is fixed.
-#include <android/log.h>
-#define TAG "GLASS"
-#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, __VA_ARGS__))
-#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, __VA_ARGS__))
-#define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, __VA_ARGS__))
-#define GLASS_LOG(level,...) \
-        LOGI(TAG, __VA_ARGS__)
-#else
-#define GLASS_LOG(level,...) \
-    GLASS_IF_LOG(level) \
-    glass_logf(level, __func__, __FILE__, __LINE__, __VA_ARGS__)
-
-#define GLASS_IF_LOG_SEVERE  GLASS_IF_LOG(GLASS_LOG_LEVEL_SEVERE)
-#define GLASS_IF_LOG_WARNING GLASS_IF_LOG(GLASS_LOG_LEVEL_WARNING)
-#define GLASS_IF_LOG_INFO    GLASS_IF_LOG(GLASS_LOG_LEVEL_INFO)
-#define GLASS_IF_LOG_CONFIG  GLASS_IF_LOG(GLASS_LOG_LEVEL_CONFIG)
-#define GLASS_IF_LOG_FINE    GLASS_IF_LOG(GLASS_LOG_LEVEL_FINE)
-#define GLASS_IF_LOG_FINER   GLASS_IF_LOG(GLASS_LOG_LEVEL_FINER)
-#define GLASS_IF_LOG_FINEST  GLASS_IF_LOG(GLASS_LOG_LEVEL_FINEST)
-#endif
-
-#ifdef NO_LOGGING
-#define GLASS_LOG_SEVERE(...)  (void)0, ##__VA_ARGS__
-#define GLASS_LOG_WARNING(...) (void)0, ##__VA_ARGS__
-#define GLASS_LOG_INFO(...) (void)0, ##__VA_ARGS__
-#define GLASS_LOG_CONFIG(...) (void)0, ##__VA_ARGS__
-#define GLASS_LOG_FINE(...) (void)0, ##__VA_ARGS__
-#define GLASS_LOG_FINER(...) (void)0, ##__VA_ARGS__
-#define GLASS_LOG_FINEST(...) (void)0, ##__VA_ARGS__
-#else
-#define GLASS_LOG_SEVERE(...) GLASS_LOG(GLASS_LOG_LEVEL_SEVERE, __VA_ARGS__)
-#define GLASS_LOG_WARNING(...) GLASS_LOG(GLASS_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define GLASS_LOG_INFO(...) GLASS_LOG(GLASS_LOG_LEVEL_INFO, __VA_ARGS__)
-#define GLASS_LOG_CONFIG(...) GLASS_LOG(GLASS_LOG_LEVEL_CONFIG, __VA_ARGS__)
-#define GLASS_LOG_FINE(...) GLASS_LOG(GLASS_LOG_LEVEL_FINE, __VA_ARGS__)
-#define GLASS_LOG_FINER(...) GLASS_LOG(GLASS_LOG_LEVEL_FINER, __VA_ARGS__)
-#define GLASS_LOG_FINEST(...) GLASS_LOG(GLASS_LOG_LEVEL_FINEST, __VA_ARGS__)
-#endif
-
-#endif
+#endif // LENS_COMMON_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/LensLogger.h	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+#ifndef LENS_LOGGER_H
+#define LENS_LOGGER_H
+
+/**
+ * Initialize the Glass logger
+ *
+ * Called from JNI_OnLoad
+ */
+void glass_logger_init();
+
+/**
+ * Log a message at the given logging level.
+ * Not used directly. GLASS_LOG should be used instead.
+ */
+void glass_logf(int level,
+                const char *func,
+                const char *file,
+                int line,
+                const char *format, ...);
+
+
+/**
+ * Write a C and Java backtrace to stderr
+ */
+void glass_backtrace();
+
+/**
+ * The logging level.
+ * Not used directly. GLASS_LOG and GLASS_IF_LOG should be used instead.
+ */
+extern jint glass_log_level;
+
+/**
+ * Begins a conditional statement that is only run if the current logging level
+ * is less than or equal to "level".
+ * For example, GLASS_IF_LOG(LOG_WARNING) { f(); } will call f() if and only if
+ * the current logging settings include printing warning messages.
+ * @param level The logging level to be tested against.
+ */
+#define GLASS_IF_LOG(level) if (level >= glass_log_level)
+
+/**
+ * Logs a message at the given logging level
+ * @param level the logging level (e.g. LOG_WARNING)
+ * @param ... a format string and parameters in printf format
+ */
+/** Logging levels, with same meanings as in java.util.logging.Level */
+#define GLASS_LOG_LEVEL_SEVERE  1000
+#define GLASS_LOG_LEVEL_WARNING 900
+#define GLASS_LOG_LEVEL_INFO    800
+#define GLASS_LOG_LEVEL_CONFIG  700
+#define GLASS_LOG_LEVEL_FINE    500
+#define GLASS_LOG_LEVEL_FINER   400
+#define GLASS_LOG_LEVEL_FINEST  300
+
+#ifdef ANDROID_NDK
+// Can't use java logger in jvm8 on Android. Remove when this issue is fixed.
+#include <android/log.h>
+#define TAG "GLASS"
+#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, __VA_ARGS__))
+#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, __VA_ARGS__))
+#define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, __VA_ARGS__))
+#define GLASS_LOG(level,...) \
+        LOGI(TAG, __VA_ARGS__)
+#else
+#define GLASS_LOG(level,...) \
+    GLASS_IF_LOG(level) \
+    glass_logf(level, __func__, __FILE__, __LINE__, __VA_ARGS__)
+
+#define GLASS_IF_LOG_SEVERE  GLASS_IF_LOG(GLASS_LOG_LEVEL_SEVERE)
+#define GLASS_IF_LOG_WARNING GLASS_IF_LOG(GLASS_LOG_LEVEL_WARNING)
+#define GLASS_IF_LOG_INFO    GLASS_IF_LOG(GLASS_LOG_LEVEL_INFO)
+#define GLASS_IF_LOG_CONFIG  GLASS_IF_LOG(GLASS_LOG_LEVEL_CONFIG)
+#define GLASS_IF_LOG_FINE    GLASS_IF_LOG(GLASS_LOG_LEVEL_FINE)
+#define GLASS_IF_LOG_FINER   GLASS_IF_LOG(GLASS_LOG_LEVEL_FINER)
+#define GLASS_IF_LOG_FINEST  GLASS_IF_LOG(GLASS_LOG_LEVEL_FINEST)
+#endif
+
+#ifdef NO_LOGGING
+#define GLASS_LOG_SEVERE(...)  (void)0, ##__VA_ARGS__
+#define GLASS_LOG_WARNING(...) (void)0, ##__VA_ARGS__
+#define GLASS_LOG_INFO(...) (void)0, ##__VA_ARGS__
+#define GLASS_LOG_CONFIG(...) (void)0, ##__VA_ARGS__
+#define GLASS_LOG_FINE(...) (void)0, ##__VA_ARGS__
+#define GLASS_LOG_FINER(...) (void)0, ##__VA_ARGS__
+#define GLASS_LOG_FINEST(...) (void)0, ##__VA_ARGS__
+#else
+#define GLASS_LOG_SEVERE(...) GLASS_LOG(GLASS_LOG_LEVEL_SEVERE, __VA_ARGS__)
+#define GLASS_LOG_WARNING(...) GLASS_LOG(GLASS_LOG_LEVEL_WARNING, __VA_ARGS__)
+#define GLASS_LOG_INFO(...) GLASS_LOG(GLASS_LOG_LEVEL_INFO, __VA_ARGS__)
+#define GLASS_LOG_CONFIG(...) GLASS_LOG(GLASS_LOG_LEVEL_CONFIG, __VA_ARGS__)
+#define GLASS_LOG_FINE(...) GLASS_LOG(GLASS_LOG_LEVEL_FINE, __VA_ARGS__)
+#define GLASS_LOG_FINER(...) GLASS_LOG(GLASS_LOG_LEVEL_FINER, __VA_ARGS__)
+#define GLASS_LOG_FINEST(...) GLASS_LOG(GLASS_LOG_LEVEL_FINEST, __VA_ARGS__)
+#endif
+
+#endif // LENS_LOGGER_H
--- a/modules/graphics/src/main/native-glass/lens/cursor/fbCursor/fbCursor.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/cursor/fbCursor/fbCursor.c	Tue Aug 20 09:38:00 2013 -0700
@@ -25,16 +25,6 @@
  
 #include "input/LensInput.h"
 
-#define FB_CURSOR_DECLARE //cause the fbPlatform variables to be declared here.
-#include "fbCursor.h"
-
-typedef struct {
-    int width;
-    int height;
-    int bpp;
-    jbyte *buffer;
-} FBCursorImage;
-
 #if defined(OMAP3)
 
 #include <fcntl.h>
@@ -44,97 +34,20 @@
 #include <linux/omapfb.h>
 #include <sys/ioctl.h>
 
-#define FB_CURSOR_DEVICE "/dev/fb1"
-#define LENSFB_CURSOR_COLOR_KEY 0xABABABAB
-
-typedef struct {
-    int fd;
-    struct omapfb_plane_info plane;
-    int width;
-    int height;
-    int screenWidth;
-    int screenHeight;
-    jlong currentCursor;
-    jboolean isVisible;
-} FBCursor;
-
-static FBCursor cursor = { .fd = -1, .width = 0, .height = 0, .currentCursor = 0, .isVisible = 0};
+#include "platform-util/platformUtil.h"
 
 static void fbCreateCursor(jbyte *cursorImage, int width, int height, int bpp) {
-
-    struct fb_var_screeninfo screenInfo;
-    cursor.width = width;
-    cursor.height = height;
-
-    GLASS_LOG_FINE("open(%s, O_RDWR)", FB_CURSOR_DEVICE);
-    cursor.fd = open(FB_CURSOR_DEVICE, O_RDWR);
-    if (cursor.fd < 0) {
-        GLASS_LOG_SEVERE("Cannot open frame buffer device for cursor");
-        return;
-    }
-    if (ioctl(cursor.fd, FBIOGET_VSCREENINFO, &screenInfo)) {
-        GLASS_LOG_SEVERE("Cannot query screen info");
-        fbCursorClose();
-        return;
-    }
-    screenInfo.xoffset = 0;
-    screenInfo.yoffset = 0;
-    screenInfo.xres = screenInfo.xres_virtual = cursor.width;
-    screenInfo.yres = screenInfo.yres_virtual = cursor.height;
-
-    if (ioctl(cursor.fd, FBIOPUT_VSCREENINFO, &screenInfo)) {
-        GLASS_LOG_SEVERE("Cannot set screen info");
-        fbCursorClose();
-        return;
-    }
-    cursor.plane.enabled = 1;
-    cursor.plane.out_width = cursor.width;
-    cursor.plane.out_height = cursor.height;
-    if (ioctl(cursor.fd, OMAPFB_SETUP_PLANE, &cursor.plane)) {
-        GLASS_LOG_SEVERE("Cannot set plane info");
-        fbCursorClose();
-        return;
-    }
-
-    if (ioctl(cursor.fd, OMAPFB_QUERY_PLANE, &cursor.plane)) {
-        GLASS_LOG_SEVERE("Cannot query plane info");
-        fbCursorClose();
-        return;
-    }
-
-    // Set up the color key
-    struct omapfb_color_key color_key;
-    if (ioctl(cursor.fd, OMAPFB_GET_COLOR_KEY, &color_key)) {
-        GLASS_LOG_SEVERE("Cannot set color key");
-        return;
-    }
-
-    color_key.key_type = OMAPFB_COLOR_KEY_VID_SRC;
-    color_key.trans_key = LENSFB_CURSOR_COLOR_KEY;
-    if (ioctl(cursor.fd, OMAPFB_SET_COLOR_KEY, &color_key)) {
-        GLASS_LOG_SEVERE("OMAPFB_SET_COLOR_KEY");
-        return;
-    }
-
-    int cursorSize = cursor.width * cursor.height * bpp;
-    if (write(cursor.fd, cursorImage, cursorSize) < cursorSize) {
-        GLASS_LOG_SEVERE("Cannot write cursor plane");
-        return;
-    }
-
+    if (fbPlatformCreateCursor) {
+        (*fbPlatformCreateCursor)(cursorImage, width, height, bpp);
+    } 
+    else {fprintf(stderr, "missing native fbPlatformCreateCursor"); }
 }
 
-void fbCursorInitialize() {
-    NativeScreen screen = glass_screen_getMainScreen();
-
-    check_dispman_cursor();
-
+void fbCursorInitialize(int screenWidth, int screenHeight) {
     if (fbPlatformCursorInitialize) {
-        (*fbPlatformCursorInitialize)(screen->width, screen->height);
-    } else {
-        cursor.screenWidth = screen->width;
-        cursor.screenHeight = screen->height;
+        (*fbPlatformCursorInitialize)(screenWidth, screenHeight);
     }
+    else {fprintf(stderr, "missing native fbPlatformCursorInitialize"); }
 }
 
 void fbCursorSetPosition(int x, int y) {
@@ -142,134 +55,46 @@
     if (fbPlatformCursorSetPosition) {
         return (*fbPlatformCursorSetPosition)(x, y);
     }
-
-    if (x < 0) {
-        x = 0;
-    }
-    if (y < 0) {
-        y = 0;
-    }
-    if (x > cursor.screenWidth - cursor.width) {
-        x = cursor.screenWidth - cursor.width;
-    }
-    if (y > cursor.screenHeight - cursor.height) {
-        y = cursor.screenHeight - cursor.height;
-    }
-    cursor.plane.enabled = 1;
-    cursor.plane.pos_x = x;
-    cursor.plane.pos_y = y;
-    if (cursor.fd >= 0) {
-        if (ioctl(cursor.fd, OMAPFB_SETUP_PLANE, &cursor.plane)) {
-            GLASS_LOG_SEVERE("Cannot set plane info to show cursor at %i,%i", x, y);
-        }
-    }
+    else {fprintf(stderr, "missing native fbPlatformCursorSetPosition"); }
 }
 
 
 void fbCursorClose() {
     if (fbPlatformCursorClose) {
-        return (*fbPlatformCursorClose)();
+        (*fbPlatformCursorClose)();
     }
-
-    if (cursor.fd >= 0) {
-        cursor.plane.enabled = 0;
-        if (ioctl(cursor.fd, OMAPFB_SETUP_PLANE, &cursor.plane)) {
-            GLASS_LOG_SEVERE("Failed to disable cursor plane");
-        }
-        close(cursor.fd);
-        cursor.fd = -1;
-    }
+    else {fprintf(stderr, "missing native fbPlatformCursorClose"); }
 }
 
 void glass_cursor_setVisible(jboolean isVisible) {
-
     if (fbPlatformSetVisible) {
-        return (*fbPlatformSetVisible)(isVisible);
+        (*fbPlatformSetVisible)(isVisible);
     }
-
-    if (isVisible) {
-        if (!cursor.isVisible && cursor.currentCursor != 0) {
-            FBCursorImage *cursorImage = (FBCursorImage *)jlong_to_ptr(cursor.currentCursor);
-            fbCreateCursor(cursorImage->buffer, cursorImage->width, cursorImage->height, cursorImage->bpp);
-        } 
-    } else {
-        fbCursorClose();
-    }
-
-    cursor.isVisible = isVisible;
+    else {fprintf(stderr, "missing native fbPlatformSetVisible"); }
 }
 
 void glass_cursor_setNativeCursor(jlong nativeCursorPointer) {
-
-    FBCursorImage *cursorImage = (FBCursorImage *)jlong_to_ptr(nativeCursorPointer);
-
     if (fbPlatformSetNativeCursor) {
-        return (*fbPlatformSetNativeCursor)(nativeCursorPointer);
+        (*fbPlatformSetNativeCursor)(nativeCursorPointer);
     }
-
-    if (cursor.currentCursor == nativeCursorPointer) {
-        return;
-    }
-
-    cursor.currentCursor = nativeCursorPointer;
-
-    if (cursor.isVisible) {
-        fbCursorClose();
-        fbCreateCursor(cursorImage->buffer, cursorImage->width, cursorImage->height, cursorImage->bpp);
-    }
+    else {fprintf(stderr, "missing native fbPlatformSetNativeCursor"); }
 }
 
 void glass_cursor_releaseNativeCursor(jlong nativeCursorPointer) {
-
     if (fbPlatformReleaseNativeCursor) {
-        return (*fbPlatformReleaseNativeCursor)(nativeCursorPointer);
+         (*fbPlatformReleaseNativeCursor)(nativeCursorPointer);
     }
-
-    if (nativeCursorPointer != 0) {
-        FBCursorImage *cursorImage = (FBCursorImage *)jlong_to_ptr(nativeCursorPointer);
-        free(cursorImage);
-    }
-
-    if (cursor.currentCursor == nativeCursorPointer) {
-        fbCursorClose();
-        cursor.currentCursor = 0;
-    }
+    else {fprintf(stderr, "missing native fbPlatformReleaseNativeCursor"); }
 }
 
 
-jlong glass_cursor_createNativeCursor(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height) {
-    FBCursorImage *cursorImage;
-    int imageSize = width * height * 4;
-
+jlong glass_cursor_createNativeCursor(JNIEnv *env, jint x, jint y, jbyte *srcArray, jint width, jint height) {
     if (fbPlatformCreateNativeCursor) {
         return (*fbPlatformCreateNativeCursor)(env, x, y, srcArray, width, height);
-    }
-
-    cursorImage = (FBCursorImage *)malloc(sizeof(FBCursorImage) + imageSize);
-
-    cursorImage->width = width;
-    cursorImage->height = height;
-    cursorImage->bpp = 4;
-    cursorImage->buffer = (jbyte *)(cursorImage + 1);
-
-    {
-        int i;
-        for (i = 0; (i + 3) < imageSize; i += 4) {
-            if (srcArray[i + 3] != 0) {
-                cursorImage->buffer[i] = srcArray[i];
-                cursorImage->buffer[i + 1] = srcArray[i + 1];
-                cursorImage->buffer[i + 2] = srcArray[i + 2];
-                cursorImage->buffer[i + 3] = srcArray[i + 3];
-            } else {
-                // 171 == 0xAB of the color key.
-                cursorImage->buffer[i] = 171;
-                cursorImage->buffer[i + 1] = 171;
-                cursorImage->buffer[i + 2] = 171;
-                cursorImage->buffer[i + 3] = 171;
-            }
-        }
-    }
-    return ptr_to_jlong(cursorImage);
+    } else {
+       fprintf(stderr, "missing native fbPlatformCreateNativeCursor"); 
+        return 0;
+    } 
 }
 
 
@@ -285,7 +110,7 @@
 
 #else /* !defined(OMAP3) */
 
-void fbCursorInitialize() { }
+void fbCursorInitialize(int screenWidth, int screenHeight) { }
 void fbCursorSetPosition(int x, int y) { }
 void fbCursorClose() { }
 
@@ -293,7 +118,7 @@
 void glass_cursor_setVisible(jboolean isVisible) {}
 void glass_cursor_setNativeCursor(jlong nativeCursorPointer) {}
 void glass_cursor_releaseNativeCursor(jlong nativeCursorPointer) {}
-jlong glass_cursor_createNativeCursor(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height) {
+jlong glass_cursor_createNativeCursor(JNIEnv *env, jint x, jint y, jbyte *srcArray, jint width, jint height) {
     return 0;
 }
 jboolean glass_cursor_supportsTranslucency() {
--- a/modules/graphics/src/main/native-glass/lens/cursor/fbCursor/fbCursor.h	Tue Aug 20 08:59:55 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef FB_CURSOR_DECLARE
-#define FB_CURSOR_DECLARE extern
-#endif
-
-FB_CURSOR_DECLARE void (*fbPlatformSetNativeCursor)(jlong nativeCursorPointer);
-FB_CURSOR_DECLARE void (*fbPlatformCursorInitialize)(int screenWidth, int screenHeight);
-FB_CURSOR_DECLARE void (*fbPlatformCursorSetPosition)(int x, int y);
-FB_CURSOR_DECLARE void (*fbPlatformCursorClose)();
-FB_CURSOR_DECLARE jlong (*fbPlatformCreateNativeCursor)(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height);
-FB_CURSOR_DECLARE void (*fbPlatformReleaseNativeCursor)(jlong nativeCursorPointer);
-FB_CURSOR_DECLARE void (*fbPlatformSetVisible)(jboolean isVisible);
-FB_CURSOR_DECLARE jboolean fbPlatformCursorTranslucency;
-
-extern jboolean check_dispman_cursor();
--- a/modules/graphics/src/main/native-glass/lens/cursor/fbCursor/fbDispman.c	Tue Aug 20 08:59:55 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,525 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
- 
-#include <stdio.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <unistd.h>
-#include <jni.h>
-#ifdef USE_DISPMAN
-#include <bcm_host.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <linux/fb.h>
-#include <sys/ioctl.h>
-#include <stdlib.h>
-#include <string.h>
-#include "LensCommon.h"
-
-#define FB_DEVICE "/dev/fb0"
-
-#include "fbCursor.h"
-
-typedef struct {
-    DISPMANX_ELEMENT_HANDLE_T element;
-    int screenWidth, screenHeight;
-    pthread_t thread;
-    pthread_mutex_t mutex;
-    sem_t semaphore;
-    int x, y;
-    int cursorWidth, cursorHeight;
-    jlong currentCursor;
-    jboolean isVisible;
-} DispManCursor;
-
-
-typedef struct {
-    jint width;
-    jint height;
-    jint x;
-    jint y;
-    DISPMANX_RESOURCE_HANDLE_T resource;
-} DispmanCursorImage;
-
-
-static DispManCursor cursor;
-
-static void *fbCursorUpdater(void *data);
-static void fbDispmanAddDispmanxElement(void);
-static void fbDispmanRemoveDispmanxElement(void);
-
-
-static void fbDispmanSetNativeCursor(jlong nativeCursorHandle) {
-
-    DISPMANX_UPDATE_HANDLE_T update;
-    DispmanCursorImage *cursorImage = (DispmanCursorImage *)jlong_to_ptr(nativeCursorHandle);
-
-
-    if (cursorImage != NULL && cursor.element != 0 &&
-        cursor.currentCursor != nativeCursorHandle) 
-    {
-        if (cursorImage->width != cursor.cursorWidth ||
-                cursorImage->height != cursor.cursorHeight) {
-
-            fbDispmanRemoveDispmanxElement();
-
-            cursor.cursorWidth = cursorImage->width;
-            cursor.cursorHeight = cursorImage->height;
-
-            fbDispmanAddDispmanxElement();
-        }
-
-        cursor.currentCursor = nativeCursorHandle;
-
-        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);
-        }
-    }
-}
-
-
-static void fbDispmanAddDispmanxElement(void) {
-
-    DISPMANX_DISPLAY_HANDLE_T display = 0;
-    DISPMANX_UPDATE_HANDLE_T update;
-    VC_DISPMANX_ALPHA_T alpha;
-    VC_RECT_T dst;
-    VC_RECT_T src = { 0, 0, cursor.cursorWidth << 16, cursor.cursorHeight << 16};
-    VC_RECT_T pixelRect = { 0, 0, cursor.cursorWidth, cursor.cursorHeight };
-    int rc;
-
-    display = vc_dispmanx_display_open(0 /* LCD */);
-    if (display == 0) {
-        GLASS_LOG_SEVERE("Cannot open display");
-        return;
-    }
-
-    update = vc_dispmanx_update_start(0);
-    alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE;
-    alpha.opacity = 0xff;
-    alpha.mask = (DISPMANX_RESOURCE_HANDLE_T) 0;
-    dst.x = cursor.x;
-    dst.y = cursor.y;
-    dst.width = cursor.cursorWidth;
-    dst.height = cursor.cursorHeight;
-    cursor.element = vc_dispmanx_element_add(
-                         update,
-                         display,
-                         0 /*layer*/,
-                         &dst,
-                         0 /*resource*/,
-                         &src,
-                         DISPMANX_PROTECTION_NONE,
-                         &alpha,
-                         0 /*clamp*/,
-                         0 /*transform*/);
-
-    vc_dispmanx_update_submit_sync(update);
-
-}
-
-
-static void fbDispmanRemoveDispmanxElement(void) {
-
-    if (cursor.element) {
-        DISPMANX_UPDATE_HANDLE_T update;
-        update = vc_dispmanx_update_start(0);
-        vc_dispmanx_element_remove(update, cursor.element);
-        vc_dispmanx_update_submit_sync(update);
-
-        cursor.element = 0;
-    }
-}
-
-static void fbDispmanCursorInitialize(int screenWidth, int screenHeight) {
-
-    // Init cursor fields
-    cursor.element = 0;
-    cursor.cursorWidth = 16;
-    cursor.cursorHeight = 16;
-    cursor.x = 0;
-    cursor.y = 0;
-    cursor.currentCursor = 0;
-    cursor.isVisible = 0;
-
-    cursor.screenWidth = screenWidth;
-    cursor.screenHeight = screenHeight;
-
-    fbDispmanAddDispmanxElement();
-
-    sem_init(&cursor.semaphore, 0, 0);
-    pthread_mutex_init(&cursor.mutex, NULL);
-    pthread_create(&cursor.thread, NULL, fbCursorUpdater, NULL);
-
-}
-
-
-static jlong fbDispmanCreateNativeCursor(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height) {
-
-    VC_RECT_T pixelRect;
-    int rc;
-    uint32_t imagePtr;
-    jbyte *allocatedBuffer = NULL;
-    DispmanCursorImage *cursorImage = (DispmanCursorImage *)malloc(sizeof(DispmanCursorImage));
-
-    //Width should be aligned to 16 pixels
-    if (width % 16 != 0) {
-        int newWidth = width + 16 - (width % 16);
-        allocatedBuffer = (jbyte *)malloc(newWidth * height * 4);
-        int i;
-        int offset = 0;
-        for (i = 0; i < height; ++i) {
-            memcpy(allocatedBuffer + offset, srcArray, width * 4);
-            memset(allocatedBuffer + offset + (width * 4), 0, (newWidth - width) * 4);
-            offset += newWidth * 4;
-            srcArray += width * 4;
-        }
-
-        width = newWidth;
-        srcArray = allocatedBuffer;
-    }
-
-    pixelRect.x = 0;
-    pixelRect.y = 0;
-    pixelRect.width = width;
-    pixelRect.height = height;
-
-    cursorImage->x = x;
-    cursorImage->y = y;
-    cursorImage->width = width;
-    cursorImage->height = height;
-    cursorImage->resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888,
-                            width,
-                            height,
-                            &imagePtr);
-    if (cursorImage->resource == 0) {
-        GLASS_LOG_SEVERE("Cannot create resource");
-        if (allocatedBuffer != NULL) {
-            free(allocatedBuffer);
-            allocatedBuffer = NULL;
-        }
-        free(cursorImage);
-        return 0;
-    }
-
-    rc = vc_dispmanx_resource_write_data(cursorImage->resource,
-                                         VC_IMAGE_ARGB8888,
-                                         width * 4,
-                                         srcArray,
-                                         &pixelRect);
-
-    if (allocatedBuffer != NULL) {
-        free(allocatedBuffer);
-        allocatedBuffer = NULL;
-    }
-
-    if (rc != 0) {
-        GLASS_LOG_SEVERE("Cannot write pixels");
-        free(cursorImage);
-        return 0;
-    }
-
-    return ptr_to_jlong(cursorImage);
-}
-
-
-
-
-static void fbDispmanReleaseNativeCursor(jlong nativeCursorHandle) {
-
-    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;
-    }
-}
-
-
-static void fbDispmanSetVisible(jboolean isVisible) {
-
-    if (isVisible) {
-        if (!cursor.isVisible && cursor.currentCursor != 0) {
-
-            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 /* resource*/);
-        vc_dispmanx_update_submit_sync(update);
-    }
-
-    cursor.isVisible = isVisible;
-}
-
-
-
-static void *fbCursorUpdater(void *data) {
-    while (1) {
-        DISPMANX_UPDATE_HANDLE_T update;
-        VC_RECT_T dst;
-        sem_wait(&cursor.semaphore);
-        pthread_mutex_lock(&cursor.mutex);
-        dst.x = cursor.x;
-        dst.y = cursor.y;
-        dst.width = cursor.cursorWidth;
-        dst.height = cursor.cursorHeight;
-        pthread_mutex_unlock(&cursor.mutex);
-        update = vc_dispmanx_update_start(0);
-        vc_dispmanx_element_change_attributes(update,
-                                              cursor.element,
-                                              0x4 /* change dest rect */,
-                                              0 /* layer */, 0, /*opacity */
-                                              &dst,
-                                              0 /* source */,
-                                              0 /* mask */, 0 /* transform */);
-        vc_dispmanx_update_submit_sync(update);
-        usleep(16666); /* sleep a sixtieth of a second before moving again */
-    }
-    return NULL;
-}
-
-static void fbDispmanCursorSetPosition(int x, int y) {
-
-    if (cursor.element) {
-        int posted;
-        pthread_mutex_lock(&cursor.mutex);
-        cursor.x = x;
-        cursor.y = y;
-        sem_getvalue(&cursor.semaphore, &posted);
-        pthread_mutex_unlock(&cursor.mutex);
-        if (posted == 0) {
-            sem_post(&cursor.semaphore);
-        }
-    } else {
-        cursor.x = x;
-        cursor.y = y;
-    }
-}
-
-void fbDispmanCursorClose() {
-
-    fbDispmanRemoveDispmanxElement();
-    cursor.isVisible = 0;
-}
-
-jboolean dispman_glass_robot_screen_capture(jint x, jint y,
-                                            jint width, jint height,
-                                            jint *pixels) {
-    FILE *fb;
-    unsigned int *pixelBuffer = NULL;
-    unsigned char *pixelBufferPtr = NULL;
-    unsigned char *dst = (unsigned char *) pixels;
-    int i = 0;
-    int fbFileHandle;
-    struct fb_var_screeninfo screenInfo;
-    unsigned int dstByteStride = width * 4;
-    VC_IMAGE_TRANSFORM_T transform = 0;
-    DISPMANX_RESOURCE_HANDLE_T resource = 0;
-    DISPMANX_DISPLAY_HANDLE_T display = 0;
-    DISPMANX_RESOURCE_HANDLE_T screenResource = 0;
-    uint32_t imagePtr;
-    int rc;
-
-    GLASS_LOG_FINE("Capture %i,%i+%ix%i", x, y, width, height);
-
-    if (width < 1 || height < 1) {
-        GLASS_LOG_SEVERE("Failed. width/height values must be at least = 1");
-        return JNI_FALSE;
-    }
-
-    GLASS_LOG_FINE("open(%s, O_RDONLY)", FB_DEVICE);
-    fbFileHandle = open(FB_DEVICE, O_RDONLY);
-    if (fbFileHandle < 0) {
-        GLASS_LOG_SEVERE("Cannot open framebuffer");
-        return JNI_FALSE;
-    }
-
-    GLASS_LOG_FINE("ioctl(%s, FBIOGET_VSCREENINFO)", FB_DEVICE);
-    if (ioctl(fbFileHandle, FBIOGET_VSCREENINFO, &screenInfo)) {
-        GLASS_LOG_SEVERE("Cannot get screen info");
-        GLASS_LOG_FINE("close(%s)", FB_DEVICE);
-        close(fbFileHandle);
-        return JNI_FALSE;
-    }
-    GLASS_LOG_FINE("Read screen info: res=%ix%i, offset=%ix%i",
-                   screenInfo.xres, screenInfo.yres,
-                   screenInfo.xoffset, screenInfo.yoffset);
-    GLASS_LOG_FINE("close(%s)", FB_DEVICE);
-    close(fbFileHandle);
-
-    VC_RECT_T pixelRect = { 0, 0, screenInfo.xres, screenInfo.yres };
-
-    int pixelBufferLength = screenInfo.xres * screenInfo.yres * 4;
-    pixelBuffer = (unsigned int *) malloc(pixelBufferLength);
-    pixelBufferPtr = (unsigned char *) pixelBuffer;
-
-    if (pixelBuffer == NULL) {
-        printf("Failed to allocate temporary pixel buffer\n");
-        return JNI_FALSE;
-    }
-
-    GLASS_LOG_FINE("fopen(%s, \"r\") to read %ix%i pixels at bit depth %i\n",
-                   FB_DEVICE, width, height, screenInfo.bits_per_pixel);
-
-    display = vc_dispmanx_display_open(0 /* LCD */);
-    if (display == 0) {
-        fprintf(stderr, "fbRobotScreenCapture: Dispman: Cannot open display\n");
-        free(pixelBuffer);
-        return JNI_FALSE;
-    }
-
-    // create the resource for the snapshot
-    screenResource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, screenInfo.xres, screenInfo.yres, &imagePtr);
-    if (!screenResource) {
-        fprintf(stderr, "fbRobotScreenCapture: Cannot create resource\n");
-        vc_dispmanx_display_close(display);
-        free(pixelBuffer);
-        return JNI_FALSE;
-    }
-
-    rc = vc_dispmanx_snapshot(display, screenResource, transform);
-    if (rc) {
-        fprintf(stderr, "fbRobotScreenCapture: snapshot failed\n");
-        vc_dispmanx_display_close(display);
-        free(pixelBuffer);
-        return JNI_FALSE;
-    }
-
-    rc = vc_dispmanx_resource_read_data(screenResource, &pixelRect, pixelBuffer, screenInfo.xres * 4);
-    if (rc) {
-        fprintf(stderr, "fbRobotScreenCapture: Cannot read pixels %d\n", rc);
-        vc_dispmanx_display_close(display);
-        free(pixelBuffer);
-        return JNI_FALSE;
-    }
-
-    rc = vc_dispmanx_resource_delete(screenResource);
-    if (rc) {
-        fprintf(stderr, "fbRobotScreenCapture: failed to free buffer %d\n", rc);
-        vc_dispmanx_display_close(display);
-        free(pixelBuffer);
-        return JNI_FALSE;
-    }
-    screenResource = 0;
-
-    if (x < 0) {
-        pixelBuffer += -x;
-        width += x;
-        x = 0;
-    }
-    if (y < 0) {
-        pixelBuffer += -y * (int)screenInfo.xres;
-        height += y;
-        y = 0;
-    }
-
-    int widthLimit = width;
-    int heightLimit = height;
-
-    // Required height is larger than screen's height
-    if ((int) screenInfo.yres < height) {
-        heightLimit = (int) screenInfo.yres;
-    }
-    // Required width is larger than screen's width
-    if ((int) screenInfo.xres < width) {
-        widthLimit = (int) screenInfo.xres;
-    }
-    // Required height is out of range
-    if (((int) screenInfo.yres - y) < height) {
-        heightLimit = (int) screenInfo.yres - y;
-    }
-    // Required width is out of range
-    if (((int) screenInfo.xres - x) < width) {
-        widthLimit = (int) screenInfo.xres - x;
-    }
-
-    if (widthLimit > 0 && heightLimit > 0) {
-        // copy the relevant portion of the screen to the supplied pixel array
-        int offset = y * screenInfo.xres * 4 + x * 4;
-        for (i = 0; i < heightLimit; i++) {
-            memcpy(dst + i * dstByteStride, pixelBufferPtr + offset, widthLimit * 4);
-            offset += screenInfo.xres * 4;
-        }
-    } else {
-        GLASS_LOG_SEVERE("Failed to take a snapshot, some of parameters are illegal");
-        free(pixelBuffer);
-        return JNI_FALSE;
-    }
-
-    vc_dispmanx_display_close(display);
-    free(pixelBuffer);
-    return JNI_TRUE;
-}
-
-extern int useDispman;
-extern void load_bcm_symbols();
-
-jboolean check_dispman_cursor() {
-    load_bcm_symbols();
-
-    if (useDispman) {
-        fbPlatformSetNativeCursor = fbDispmanSetNativeCursor;
-        fbPlatformCursorInitialize = fbDispmanCursorInitialize;
-        fbPlatformCursorSetPosition = fbDispmanCursorSetPosition;
-        fbPlatformCursorClose = fbDispmanCursorClose;
-        fbPlatformCreateNativeCursor = fbDispmanCreateNativeCursor;
-        fbPlatformReleaseNativeCursor = fbDispmanReleaseNativeCursor;
-        fbPlatformSetVisible = fbDispmanSetVisible;
-        fbPlatformCursorTranslucency = JNI_TRUE;
-        return JNI_TRUE;
-    }
-    return JNI_FALSE;
-}
-
-#else /* ! USE_DISPMAN */
-
-jboolean check_dispman_cursor() {
-    return JNI_FALSE;
-}
-
-#endif /* USE_DISPMAN */
--- a/modules/graphics/src/main/native-glass/lens/cursor/fbCursor/wrapped_bcm.c	Tue Aug 20 08:59:55 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-#include <stdio.h>
-#include <dlfcn.h>
-
-#ifdef USE_DISPMAN
-int useDispman = 1;
-
-void load_bcm_symbols();
-
-/*************************************** BROADCOM ******************************************/
-
-#ifndef BCM_HOST_H
-#include <bcm_host.h>
-#endif
-
-#if !defined(_VC_DISPMANX_H_)
-/* for Debian 6.0 libraries */
-typedef enum {
-   VC_IMAGE_ARGB8888 = 43,  /* 32bpp with 8bit alpha at MS byte, with R, G, B (LS byte) */
-} VC_IMAGE_TYPE_T;
-#endif
-
-void (*_bcm_host_init)(void);
-
-static int VCHPOST_ (*_vc_dispmanx_display_close)(DISPMANX_DISPLAY_HANDLE_T display);
-static int VCHPOST_ (*_vc_dispmanx_display_get_info)(DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_MODEINFO_T *pinfo);
-static DISPMANX_DISPLAY_HANDLE_T VCHPOST_ (*_vc_dispmanx_display_open) (uint32_t device);
-static DISPMANX_ELEMENT_HANDLE_T VCHPOST_ (*_vc_dispmanx_element_add) (DISPMANX_UPDATE_HANDLE_T update,
-        DISPMANX_DISPLAY_HANDLE_T display,
-        int32_t layer, const VC_RECT_T *dest_rect, DISPMANX_RESOURCE_HANDLE_T src,
-        const VC_RECT_T *src_rect, DISPMANX_PROTECTION_T protection,
-        VC_DISPMANX_ALPHA_T *alpha, DISPMANX_CLAMP_T *clamp, DISPMANX_TRANSFORM_T transform);
-static DISPMANX_UPDATE_HANDLE_T VCHPOST_ (*_vc_dispmanx_update_start)( int32_t priority);
-static int VCHPOST_ (*_vc_dispmanx_update_submit_sync)(DISPMANX_UPDATE_HANDLE_T update);
-static int VCHPOST_ (*_vc_dispmanx_resource_read_data)(DISPMANX_RESOURCE_HANDLE_T handle,
-                                                      const VC_RECT_T *p_rect, void *dst_address, uint32_t dst_pitch);
-static int VCHPOST_ (*_vc_dispmanx_resource_write_data)(DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type,
-                     int src_pitch, void *src_address, const VC_RECT_T *rect);
-static int VCHPOST_ (*_vc_dispmanx_element_remove)(DISPMANX_UPDATE_HANDLE_T update,
-                                                   DISPMANX_ELEMENT_HANDLE_T element);
-static int VCHPOST_ (*_vc_dispmanx_element_change_attributes)(DISPMANX_UPDATE_HANDLE_T update,
-                                                             DISPMANX_ELEMENT_HANDLE_T element,
-                                                             uint32_t change_flags,
-                                                             int32_t layer, uint8_t opacity,
-                                                             const VC_RECT_T *dest_rect,
-                                                             const VC_RECT_T *src_rect,
-                                                             DISPMANX_RESOURCE_HANDLE_T mask,
-                                                             VC_IMAGE_TRANSFORM_T transform);
-static DISPMANX_RESOURCE_HANDLE_T VCHPOST_ (*_vc_dispmanx_resource_create)(VC_IMAGE_TYPE_T type,
-                                                                          uint32_t width, uint32_t height,
-                                                                          uint32_t *native_image_handle);
-static int VCHPOST_ (*_vc_dispmanx_resource_delete)( DISPMANX_RESOURCE_HANDLE_T res );
-static int VCHPOST_ (*_vc_dispmanx_snapshot)(DISPMANX_DISPLAY_HANDLE_T display,
-                                             DISPMANX_RESOURCE_HANDLE_T snapshot_resource,
-                                             VC_IMAGE_TRANSFORM_T transform );
-
-static int VCHPOST_ (*_vc_dispmanx_element_change_source)( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element,
-                                                        DISPMANX_RESOURCE_HANDLE_T src );
-
-
-
-
-void bcm_host_init(void) {
-    if (!_bcm_host_init) {
-        load_bcm_symbols();
-    }
-    return (*_bcm_host_init)();
-}
-
-int VCHPOST_ vc_dispmanx_display_close(DISPMANX_DISPLAY_HANDLE_T display) {
-    return (*_vc_dispmanx_display_close)(display);
-}
-
-int VCHPOST_ vc_dispmanx_display_get_info(DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_MODEINFO_T *pinfo) {
-    return (*_vc_dispmanx_display_get_info)(display, pinfo);
-}
-
-DISPMANX_DISPLAY_HANDLE_T VCHPOST_ vc_dispmanx_display_open(uint32_t device) {
-    return (*_vc_dispmanx_display_open)(device);
-}
-
-DISPMANX_ELEMENT_HANDLE_T VCHPOST_ vc_dispmanx_element_add (DISPMANX_UPDATE_HANDLE_T update,
-                                                            DISPMANX_DISPLAY_HANDLE_T display,
-                                                            int32_t layer, const VC_RECT_T *dest_rect,
-                                                            DISPMANX_RESOURCE_HANDLE_T src,
-                                                            const VC_RECT_T *src_rect,
-                                                            DISPMANX_PROTECTION_T protection,
-                                                            VC_DISPMANX_ALPHA_T *alpha,
-                                                            DISPMANX_CLAMP_T *clamp,
-                                                            DISPMANX_TRANSFORM_T transform) {
-
-    return (*_vc_dispmanx_element_add) (update, display, layer, dest_rect, src, src_rect, 
-        protection, alpha, clamp, transform);
-}
-
-DISPMANX_UPDATE_HANDLE_T VCHPOST_ vc_dispmanx_update_start( int32_t priority) {
-    return (*_vc_dispmanx_update_start)(priority);
-}
-
-int VCHPOST_ vc_dispmanx_update_submit_sync(DISPMANX_UPDATE_HANDLE_T update) {
-    return (*_vc_dispmanx_update_submit_sync)(update);
-}
-
-int VCHPOST_ vc_dispmanx_resource_write_data(DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type,
-                         int src_pitch, void *src_address, const VC_RECT_T *rect ) {
-    return (*_vc_dispmanx_resource_write_data)(res, src_type, src_pitch, src_address, rect);
-}
-
-int VCHPOST_ vc_dispmanx_resource_read_data(DISPMANX_RESOURCE_HANDLE_T handle,
-                                            const VC_RECT_T *p_rect, void *dst_address, uint32_t dst_pitch) {
-    return (*_vc_dispmanx_resource_read_data)(handle, p_rect, dst_address, dst_pitch);
-}
-
-int VCHPOST_ vc_dispmanx_element_remove(DISPMANX_UPDATE_HANDLE_T update,
-                                                    DISPMANX_ELEMENT_HANDLE_T element) {
-    return (*_vc_dispmanx_element_remove)(update, element);
-}
-
-int VCHPOST_ vc_dispmanx_element_change_attributes(DISPMANX_UPDATE_HANDLE_T update,
-                                                   DISPMANX_ELEMENT_HANDLE_T element, uint32_t change_flags,
-                                                   int32_t layer, uint8_t opacity,
-                                                   const VC_RECT_T *dest_rect,
-                                                   const VC_RECT_T *src_rect,
-                                                   DISPMANX_RESOURCE_HANDLE_T mask,
-                                                   VC_IMAGE_TRANSFORM_T transform) {
-    return (*_vc_dispmanx_element_change_attributes)(update, element, change_flags, layer, opacity, dest_rect,
-                                                     src_rect, mask, transform);
-}
-
-DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_resource_create(VC_IMAGE_TYPE_T type,
-                                                                uint32_t width, uint32_t height,
-                                                                uint32_t *native_image_handle) {
-    return (*_vc_dispmanx_resource_create)(type, width, height, native_image_handle);
-}
-
-int VCHPOST_ vc_dispmanx_resource_delete( DISPMANX_RESOURCE_HANDLE_T res ) {
-    return (*_vc_dispmanx_resource_delete)(res);
-}
-
-int VCHPOST_ vc_dispmanx_snapshot(DISPMANX_DISPLAY_HANDLE_T display,
-                                   DISPMANX_RESOURCE_HANDLE_T snapshot_resource,
-                                   VC_IMAGE_TRANSFORM_T transform) {
-    return (*_vc_dispmanx_snapshot)(display, snapshot_resource, transform);
-}
-
-int VCHPOST_ vc_dispmanx_element_change_source(DISPMANX_UPDATE_HANDLE_T update, 
-                                               DISPMANX_ELEMENT_HANDLE_T element,
-                                               DISPMANX_RESOURCE_HANDLE_T src )
-{
-   return  (*_vc_dispmanx_element_change_source)(update,element,src);
-}
-
-
-void load_bcm_symbols() {
-    int error = 0;
-    void *lib = dlopen("libbcm_host.so", RTLD_NOW); // there is a couple of choices?
-
-    if (_bcm_host_init) {
-        fprintf(stderr,"BCM symbols already loaded\n");
-        // already loaded
-        return;
-    }
-
-    if (!lib) {
-        useDispman = 0;
-        return;
-    } else {
-        useDispman = 1;
-    }
-
-    if (!(_bcm_host_init = dlsym(lib,"bcm_host_init"))) error++;
-    if (!(_vc_dispmanx_display_close = dlsym(lib,"vc_dispmanx_display_close"))) error++;
-    if (!(_vc_dispmanx_display_get_info = dlsym(lib,"vc_dispmanx_display_get_info"))) error++;
-    if (!(_vc_dispmanx_display_open = dlsym(lib,"vc_dispmanx_display_open"))) error++;
-    if (!(_vc_dispmanx_element_add = dlsym(lib,"vc_dispmanx_element_add"))) error++;
-    if (!(_vc_dispmanx_update_start = dlsym(lib,"vc_dispmanx_update_start"))) error++;
-    if (!(_vc_dispmanx_update_submit_sync = dlsym(lib,"vc_dispmanx_update_submit_sync"))) error++;
-    if (!(_vc_dispmanx_resource_write_data = dlsym(lib, "vc_dispmanx_resource_write_data"))) error++;
-    if (!(_vc_dispmanx_resource_read_data = dlsym(lib, "vc_dispmanx_resource_read_data"))) error++;
-    if (!(_vc_dispmanx_element_remove = dlsym(lib, "vc_dispmanx_element_remove"))) error++;
-    if (!(_vc_dispmanx_element_change_attributes = dlsym(lib, "vc_dispmanx_element_change_attributes"))) error++;
-    if (!(_vc_dispmanx_resource_create = dlsym(lib, "vc_dispmanx_resource_create"))) error++;
-    if (!(_vc_dispmanx_resource_delete = dlsym(lib, "vc_dispmanx_resource_delete"))) error++;
-    if (!(_vc_dispmanx_snapshot = dlsym(lib, "vc_dispmanx_snapshot"))) error++;
-    if (!(_vc_dispmanx_element_change_source = dlsym(lib, "vc_dispmanx_element_change_source"))) error++;
-
-    
-
-    if (error) {
-        // handle error conditions better ?
-        fprintf(stderr,"failed to load all bcm_host symbols %d\n",error);
-    }
-}
-#else
-int useDispman = 0;
-
-void load_bcm_symbols() {
-}
-#endif /* USE_DISPMAN */
--- a/modules/graphics/src/main/native-glass/lens/input/LensInput.h	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/input/LensInput.h	Tue Aug 20 09:38:00 2013 -0700
@@ -39,7 +39,7 @@
 void lens_wm_setPointerPosition(int x, int y);
 
 /** Sets up the framebuffer cursor */
-void fbCursorInitialize();
+void fbCursorInitialize(int screenWidth, int screenHeight);
 
 /** Changes the position of the framebuffer cursor */
 void fbCursorSetPosition(int x, int y);
--- a/modules/graphics/src/main/native-glass/lens/input/android/androidInput.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/input/android/androidInput.c	Tue Aug 20 09:38:00 2013 -0700
@@ -27,6 +27,8 @@
 #include <dlfcn.h>
 
 #include "androidInput.h"
+#include "com_sun_glass_ui_android_SoftwareKeyboard.h"
+#include "com_sun_glass_ui_android_Activity.h"
 
 static ANativeWindow* (*_ANDROID_getNativeWindow)();
 static void (*_ANDROID_showIME)();
@@ -52,7 +54,7 @@
     return (*_ANDROID_getNativeWindow)();
 }
 
-JNIEXPORT void JNICALL Java_com_sun_glass_ui_android_SoftwareKeyboard_show
+JNIEXPORT void JNICALL Java_com_sun_glass_ui_android_SoftwareKeyboard__1show
 (JNIEnv *env, jclass clazz) {
     if (!_ANDROID_showIME) {
         init_functions(env);
@@ -61,7 +63,7 @@
     (*_ANDROID_showIME)();
 }
 
-JNIEXPORT void JNICALL Java_com_sun_glass_ui_android_SoftwareKeyboard_hide
+JNIEXPORT void JNICALL Java_com_sun_glass_ui_android_SoftwareKeyboard__1hide
 (JNIEnv *env, jclass clazz) {
     if (!_ANDROID_hideIME) {
         init_functions(env);
@@ -70,7 +72,7 @@
     (*_ANDROID_hideIME)();
 }
 
-JNIEXPORT void JNICALL Java_com_sun_glass_ui_android_Activity_shutdown
+JNIEXPORT void JNICALL Java_com_sun_glass_ui_android_Activity__1shutdown
 (JNIEnv *env, jclass clazz) {
     android_shutdown();
 }
--- a/modules/graphics/src/main/native-glass/lens/input/udev/udevInput.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/input/udev/udevInput.c	Tue Aug 20 09:38:00 2013 -0700
@@ -103,9 +103,14 @@
     /* Press - crossed the tapping radius */
     TOUCH_DRAGGING,
     /* Release pending */
-    TOUCH_RELEASING
+    TOUCH_RELEASING,
+    /* Multiple current touch points */
+    TOUCH_MULTI
 } LensInputTouchActionState;
 
+// The maximum number of touch points that can be handled. If events with more
+// touch points are received, some points will be dropped.
+#define LENS_MAX_TOUCH_POINTS 20
 
 typedef struct _LensInputMouseState {
     /* device state */
@@ -115,6 +120,19 @@
     int                     abs[ABS_MAX + 1];
     int                     prevabs[ABS_MAX + 1];
 
+    /* multitouch points */
+    int                     nextTouchID; // ID used for the next new touch point
+    /* existing touch points that have already been sent up to Glass */
+    int                     touchPointCount;
+    int                     touchIDs[LENS_MAX_TOUCH_POINTS];
+    int                     touchXs[LENS_MAX_TOUCH_POINTS];
+    int                     touchYs[LENS_MAX_TOUCH_POINTS];
+    /* new touch points that have not yet been sent up to Glass */
+    int                     pendingTouchPointCount;
+    int                     pendingTouchIDs[LENS_MAX_TOUCH_POINTS];
+    int                     pendingTouchXs[LENS_MAX_TOUCH_POINTS];
+    int                     pendingTouchYs[LENS_MAX_TOUCH_POINTS];
+
     /* pending input events that have not yet been reported to the upper stack */
     struct input_event      *pendingInputEvents;
     int                     pendingInputEventCount;
@@ -1256,7 +1274,15 @@
 
     switch (event->type) {
         case EV_SYN:
-            lens_input_pointerEvents_handleSync(device);
+            if (event->code == SYN_REPORT) {
+                // this event is complete
+                lens_input_pointerEvents_handleSync(device);
+            } else {
+                // this EV_SYN event is a delimiter within the event, such as
+                // SYN_MT_REPORT
+                lens_input_pointerEvents_enqueuePendingEvent(
+                    (LensInputMouseState *)device->state, event);
+            }
             break;
         case EV_KEY:
         case EV_REL:
@@ -1307,6 +1333,14 @@
         case ABS_Y:
             newMousePosY = (int) roundf(scalar * screenHeight);
             break;
+        case ABS_MT_POSITION_X:
+            mouseState->pendingTouchXs[mouseState->pendingTouchPointCount] =
+                    (int) roundf(scalar * screenWidth);
+            break;
+        case ABS_MT_POSITION_Y:
+            mouseState->pendingTouchYs[mouseState->pendingTouchPointCount] =
+                    (int) roundf(scalar * screenHeight);
+            break;
     }
     GLASS_LOG_FINER("Pointer absolute axis 0x%02x is now %i, pointer at %i,%i",
                     axis, mouseState->abs[axis], newMousePosX, newMousePosY);
@@ -1358,6 +1392,7 @@
         //tap event
         jint eventType = (isPressed) ? com_sun_glass_events_TouchEvent_TOUCH_PRESSED
                          : com_sun_glass_events_TouchEvent_TOUCH_RELEASED;
+        jlong id = TOUCH_SCREEN_ID;
 
         GLASS_LOG_FINE("Notify touch event on screen id %i - tap %s fx event code %i at %i,%i",
                        TOUCH_SCREEN_ID,
@@ -1365,8 +1400,8 @@
                        eventType,
                        mousePosX, mousePosY);
 
-        lens_wm_notifyTouchEvent(gJNIEnv, eventType,
-                                 TOUCH_SCREEN_ID, mousePosX, mousePosY);
+        lens_wm_notifyMultiTouchEvent(gJNIEnv, 1, &eventType, &id,
+                                      &mousePosX, &mousePosY);
     }
 
     int button = lens_input_convertButtonToFXButtonCode(pointerEvent->code);
@@ -1395,6 +1430,7 @@
     LensInputMouseState *mouseState = device->state;
     int keyEventIndex = -1;
     jboolean reportMove = JNI_FALSE;
+    mouseState->pendingTouchPointCount = 0;
 
     //Pass on the events of this sync
     for (i = 0; i < mouseState->pendingInputEventCount; i++) {
@@ -1412,82 +1448,258 @@
                 lens_input_pointerEvents_handleAbsMotion(device, pointerEvent);
                 reportMove = JNI_TRUE;
                 break;
+            case EV_SYN:
+                if (pointerEvent->code == SYN_MT_REPORT) {
+                    if (mouseState->pendingTouchPointCount < LENS_MAX_TOUCH_POINTS) {
+                        mouseState->pendingTouchPointCount ++;
+                    } else {
+                        // We are past how many touch points we expect to be
+                        // reported. For n touch points, where n >
+                        // LENS_MAX_TOUCH_POINTS, drop the points from
+                        // LENS_MAX_TOUCH_POINTS to (n-1). For example, if we
+                        // get 30 touch points and can only support 20, record
+                        // only points 1-19 and point 30. This is arbitrary,
+                        // just because it is easy to code.  We could do
+                        // something different here.
+                    }
+                }
+                break;
             default:
                 // The queue should not hold other event
                 assert(0);
         }
     }
 
-
-    //Update new current position
-    mousePosX = newMousePosX;
-    mousePosY = newMousePosY;
-
-    GLASS_LOG_FINEST("device %p x %d y %d reportMove %d keyEventIndex: %d\n",
-                     device, mousePosX, mousePosY, reportMove, keyEventIndex);
-
-    if (keyEventIndex >= 0) {
-        //Press or release event
-        if (mouseState->pendingInputEvents[keyEventIndex].value == 1) {
-            // press
-            jboolean sendEvent = JNI_TRUE;
-            if (device->isTouch) {
-                if (mouseState->touchState == TOUCH_DEFAULT) {
-                    //normal first stage
-                    mouseState->touchState = TOUCH_TAPPING;
-                    mouseState->pressedX = mousePosX;
-                    mouseState->pressedY = mousePosY;
-
-                } else if (mouseState->touchState == TOUCH_RELEASING) {
-                    //cancels the release
-                    lens_input_eventLoop_triggerTimeout(device, 0, NULL);
-                    mouseState->touchState = TOUCH_TAPPING;
-                    sendEvent = JNI_FALSE;
+    if (mouseState->pendingTouchPointCount > 0) {
+        // assign IDs to touch points
+        if (mouseState->touchPointCount == 0) {
+            // no pre-existing touch points, so assign any IDs
+            mouseState->nextTouchID = 1;
+            for (i = 0; i < mouseState->pendingTouchPointCount; i++) {
+                mouseState->pendingTouchIDs[i] = mouseState->nextTouchID++;
+            }
+        } else if (mouseState->pendingTouchPointCount >= mouseState->touchPointCount) {
+            // For each existing touch point, find the closest pending touch
+            // point.
+            // mapped indices contains 0 for every unmapped pending touch point
+            // index  and 1 for every pending touch point index that has
+            // already been mapped to an existing touch point.
+            int mappedIndices[LENS_MAX_TOUCH_POINTS];
+            memset(mappedIndices, 0, sizeof(mappedIndices));
+            int mappedIndexCount = 0;
+            for (i = 0; i < mouseState->touchPointCount; i++) {
+                int x = mouseState->touchXs[i];
+                int y = mouseState->touchYs[i];
+                int j;
+                int closestDistanceSquared = INT_MAX;
+                int mappedIndex = -1;
+                for (j = 0; j < mouseState->pendingTouchPointCount; j++) {
+                    if (mappedIndices[j] == 0) {
+                        int distanceX = x - mouseState->pendingTouchXs[j];
+                        int distanceY = y - mouseState->pendingTouchYs[j];
+                        int distanceSquared = distanceX * distanceX + distanceY * distanceY;
+                        if (distanceSquared < closestDistanceSquared) {
+                            mappedIndex = j;
+                            closestDistanceSquared = distanceSquared;
+                        }
+                    }
+                }
+                assert(mappedIndex >= 0);
+                mouseState->pendingTouchIDs[mappedIndex] = mouseState->touchIDs[i];
+                mappedIndexCount ++;
+                mappedIndices[mappedIndex] = 1;
+            }
+            if (mappedIndexCount < mouseState->pendingTouchPointCount) {
+                for (i = 0; i < mouseState->pendingTouchPointCount; i++) {
+                    if (mappedIndices[i] == 0) {
+                        mouseState->pendingTouchIDs[i] = mouseState->nextTouchID++;
+                    }
                 }
             }
-
-            if (sendEvent) {
-                lens_input_pointerEvents_handleKeyEvent(device,
-                                                        &mouseState->pendingInputEvents[keyEventIndex]);
+        } else {
+            // There are more existing touch points than pending touch points.
+            // For each pending touch point, find the closest existing touch
+            // point.
+            // mappedIndices contains 0 for every unmapped pre-existing touch
+            // index and 1 for every pre-existing touch index that has already
+            // been mapped to a pending touch point
+            int mappedIndices[LENS_MAX_TOUCH_POINTS];
+            memset(mappedIndices, 0, sizeof(mappedIndices));
+            int mappedIndexCount = 0;
+            for (i = 0; i < mouseState->pendingTouchPointCount
+                    && mappedIndexCount < mouseState->touchPointCount; i++) {
+                int x = mouseState->pendingTouchXs[i];
+                int y = mouseState->pendingTouchYs[i];
+                int j;
+                int closestDistanceSquared = INT_MAX;
+                int mappedIndex = -1;
+                for (j = 0; j < mouseState->touchPointCount; j++) {
+                    if (mappedIndices[j] == 0) {
+                        int distanceX = x - mouseState->touchXs[j];
+                        int distanceY = y - mouseState->touchYs[j];
+                        int distanceSquared = distanceX * distanceX + distanceY * distanceY;
+                        if (distanceSquared < closestDistanceSquared) {
+                            mappedIndex = j;
+                            closestDistanceSquared = distanceSquared;
+                        }
+                    }
+                }
+                assert(mappedIndex >= 0);
+                mouseState->pendingTouchIDs[i] = mouseState->touchIDs[mappedIndex];
+                mappedIndexCount ++;
+                mappedIndices[mappedIndex] = 1;
             }
-
-        } else {
-            //release
-            if (!device->isTouch ||
-                    (device->isTouch && mouseState->touchState == TOUCH_DRAGGING)) {
-                mouseState->touchState = TOUCH_DEFAULT;
-                lens_input_pointerEvents_handleKeyEvent(device,
-                                                        &mouseState->pendingInputEvents[keyEventIndex]);
+        }
+        mousePosX = mouseState->pendingTouchXs[0];
+        mousePosY = mouseState->pendingTouchYs[0];
+    } else {
+        mousePosX = newMousePosX;
+        mousePosY = newMousePosY;
+    }
+
+    // Process state changes to TOUCH_MULTI from other states. The transition
+    // out of TOUCH_MULTI is done as part of touch releases.
+    if (mouseState->pendingTouchPointCount > 1) {
+        switch (mouseState->touchState) {
+            case TOUCH_DEFAULT:
+            case TOUCH_TAPPING:
+            case TOUCH_DRAGGING:
+                mouseState->touchState = TOUCH_MULTI;
+                break;
+            case TOUCH_RELEASING:
+                // cancel timeout
+                lens_input_eventLoop_triggerTimeout(device, 0, NULL);
+                mouseState->touchState = TOUCH_MULTI;
+                break;
+            case TOUCH_MULTI:
+                // no change needed
+                break;
+        }
+    }
+
+    if (mouseState->touchState == TOUCH_MULTI) {
+        jint count = 0;
+        jint states[LENS_MAX_TOUCH_POINTS];
+        jlong ids[LENS_MAX_TOUCH_POINTS];
+        int xs[LENS_MAX_TOUCH_POINTS];
+        int ys[LENS_MAX_TOUCH_POINTS];
+        // Process STATIONARY, MOVE and RELEASED TouchPoints
+        for (i = 0; i < mouseState->touchPointCount; i++) {
+            int j;
+            jlong id = mouseState->touchIDs[i];
+            jboolean matched = JNI_FALSE;
+            ids[count] = id;
+            for (j = 0; j < mouseState->pendingTouchPointCount && !matched; j++) {
+                if (mouseState->pendingTouchIDs[j] == id) {
+                    xs[count] = mouseState->pendingTouchXs[j];
+                    ys[count] = mouseState->pendingTouchYs[j];
+                    int x = mouseState->touchXs[i];
+                    int y = mouseState->touchYs[i];
+                    if (xs[count] == x && ys[count] == y) {
+                        states[count] = com_sun_glass_events_TouchEvent_TOUCH_STILL;
+                    } else {
+                        states[count] = com_sun_glass_events_TouchEvent_TOUCH_MOVED;
+                    }
+                    matched = JNI_TRUE;
+                }
             }
-
-            if (device->isTouch && mouseState->touchState == TOUCH_TAPPING) {
-                mouseState->touchState = TOUCH_RELEASING;
-                mouseState->releaseEvent = mouseState->pendingInputEvents[keyEventIndex];
-                if (gTapReleasePendingTimeout > 0) {
-                    lens_input_eventLoop_triggerTimeout(device, gTapReleasePendingTimeout, lens_input_pointerEvents_handleTimeout);
-                } else {
-                    //Calling the timeout function since it sends the recorded 
-                    //press coordinates which is needed in case we filtered few 
-                    //moves.
-                    lens_input_pointerEvents_handleTimeout(device);
+            if (!matched) {
+                states[count] = com_sun_glass_events_TouchEvent_TOUCH_RELEASED;
+                xs[count] = mouseState->touchXs[j];
+                ys[count] = mouseState->touchYs[j];
+            }
+            count ++;
+        }
+        // Process PRESSED TouchPoints
+        for (i = 0; i < mouseState->pendingTouchPointCount; i++) {
+            int j;
+            jlong id = mouseState->pendingTouchIDs[i];
+            jboolean matched = JNI_FALSE;
+            for (j = 0; j < mouseState->touchPointCount && !matched; j++) {
+                if (mouseState->touchIDs[j] == id) {
+                    matched = JNI_TRUE;
+                    break;
+                }
+            }
+            if (!matched) {
+                ids[count] = id;
+                xs[count] = mouseState->pendingTouchXs[i];
+                ys[count] = mouseState->pendingTouchYs[i];
+                states[count] = com_sun_glass_events_TouchEvent_TOUCH_PRESSED;
+                count ++;
+            }
+        }
+        lens_wm_notifyMultiTouchEvent(gJNIEnv, count, states, ids, xs, ys);
+        if (mouseState->pendingTouchPointCount == 0) {
+            mouseState->touchState = TOUCH_DEFAULT;
+        }
+    } else {
+        GLASS_LOG_FINEST("device %p x %d y %d reportMove %d keyEventIndex: %d\n",
+                         device, mousePosX, mousePosY, reportMove, keyEventIndex);
+
+        if (keyEventIndex >= 0) {
+            //Press or release event
+            if (mouseState->pendingInputEvents[keyEventIndex].value == 1) {
+                // press
+                jboolean sendEvent = JNI_TRUE;
+                if (device->isTouch) {
+                    if (mouseState->touchState == TOUCH_DEFAULT) {
+                        //normal first stage
+                        mouseState->touchState = TOUCH_TAPPING;
+                        mouseState->pressedX = mousePosX;
+                        mouseState->pressedY = mousePosY;
+
+                    } else if (mouseState->touchState == TOUCH_RELEASING) {
+                        //cancels the release
+                        lens_input_eventLoop_triggerTimeout(device, 0, NULL);
+                        mouseState->touchState = TOUCH_TAPPING;
+                        sendEvent = JNI_FALSE;
+                    }
+                }
+
+                if (sendEvent) {
+                    lens_input_pointerEvents_handleKeyEvent(device,
+                                                            &mouseState->pendingInputEvents[keyEventIndex]);
+                }
+
+            } else {
+                //release
+                if (!device->isTouch ||
+                        (device->isTouch && mouseState->touchState == TOUCH_DRAGGING)) {
+                    mouseState->touchState = TOUCH_DEFAULT;
+                    lens_input_pointerEvents_handleKeyEvent(device,
+                                                            &mouseState->pendingInputEvents[keyEventIndex]);
+                }
+
+                if (device->isTouch && mouseState->touchState == TOUCH_TAPPING) {
+                    mouseState->touchState = TOUCH_RELEASING;
+                    mouseState->releaseEvent = mouseState->pendingInputEvents[keyEventIndex];
+                    if (gTapReleasePendingTimeout > 0) {
+                        lens_input_eventLoop_triggerTimeout(device, gTapReleasePendingTimeout, lens_input_pointerEvents_handleTimeout);
+                    } else {
+                        //Calling the timeout function since it sends the recorded 
+                        //press coordinates which is needed in case we filtered few 
+                        //moves.
+                        lens_input_pointerEvents_handleTimeout(device);
+                    }
                 }
             }
         }
-    }
-
-    if (reportMove) {
-
-        if (device->isTouch && mouseState->touchState == TOUCH_TAPPING) {
-            int dX = mousePosX - mouseState->pressedX;
-            int dY = mousePosY - mouseState->pressedY;
-            if (dX * dX + dY * dY >= gTapRadius * gTapRadius) {
-                mouseState->touchState = TOUCH_DRAGGING;
+
+        if (reportMove) {
+
+            if (device->isTouch && mouseState->touchState == TOUCH_TAPPING) {
+                int dX = mousePosX - mouseState->pressedX;
+                int dY = mousePosY - mouseState->pressedY;
+                if (dX * dX + dY * dY >= gTapRadius * gTapRadius) {
+                    mouseState->touchState = TOUCH_DRAGGING;
+                }
             }
-        }
-
-        if (!device->isTouch ||
-                (device->isTouch && mouseState->touchState == TOUCH_DRAGGING)) {
-            lens_wm_notifyMotionEvent(gJNIEnv, mousePosX, mousePosY, device->isTouch, 1);
+
+            if (!device->isTouch ||
+                    (device->isTouch && mouseState->touchState == TOUCH_DRAGGING)) {
+                lens_wm_notifyMotionEvent(gJNIEnv, mousePosX, mousePosY, device->isTouch, 1);
+            }
         }
     }
 
@@ -1503,6 +1715,17 @@
 
     mouseState->pendingInputEventCount = 0;
 
+    // recording pending touch points as existing touch points
+    mouseState->touchPointCount = mouseState->pendingTouchPointCount;
+    GLASS_LOG_FINEST("%i touch points", mouseState->touchPointCount);
+    for (i = 0; i < mouseState->pendingTouchPointCount; i++) {
+        mouseState->touchIDs[i] = mouseState->pendingTouchIDs[i];
+        mouseState->touchXs[i] = mouseState->pendingTouchXs[i];
+        mouseState->touchYs[i] = mouseState->pendingTouchYs[i];
+        GLASS_LOG_FINEST("Touch point %i at %i, %i (id=%i)", i,
+                         mouseState->touchXs[i], mouseState->touchYs[i],
+                         mouseState->touchIDs[i]);
+    }
 }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/dispmanCursor.c	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+ 
+#include <stdio.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <unistd.h>
+#include <jni.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/fb.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LensCommon.h"
+#include "LensLogger.h"
+
+#ifdef USE_DISPMAN
+#include "wrapped_bcm.h"
+
+#define FB_DEVICE "/dev/fb0"
+
+#include "utilInternal.h"
+#include "platformUtil.h"
+
+typedef struct {
+    DISPMANX_ELEMENT_HANDLE_T element;
+    int screenWidth, screenHeight;
+    pthread_t thread;
+    pthread_mutex_t mutex;
+    sem_t semaphore;
+    int x, y;
+    int cursorWidth, cursorHeight;
+    jlong currentCursor;
+    jboolean isVisible;
+} DispManCursor;
+
+
+typedef struct {
+    jint width;
+    jint height;
+    jint x;
+    jint y;
+    DISPMANX_RESOURCE_HANDLE_T resource;
+} DispmanCursorImage;
+
+
+static DispManCursor cursor;
+
+static void *fbCursorUpdater(void *data);
+static void fbDispmanAddDispmanxElement(void);
+static void fbDispmanRemoveDispmanxElement(void);
+
+
+static void fbDispmanSetNativeCursor(jlong nativeCursorHandle) {
+
+    DISPMANX_UPDATE_HANDLE_T update;
+    DispmanCursorImage *cursorImage = (DispmanCursorImage *)jlong_to_ptr(nativeCursorHandle);
+
+    if (cursorImage != NULL && cursor.element != 0) {
+
+        if (cursorImage->width != cursor.cursorWidth ||
+                cursorImage->height != cursor.cursorHeight) {
+
+            fbDispmanRemoveDispmanxElement();
+
+            cursor.cursorWidth = cursorImage->width;
+            cursor.cursorHeight = cursorImage->height;
+
+            fbDispmanAddDispmanxElement();
+        }
+
+        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;
+    }
+}
+
+
+static void fbDispmanAddDispmanxElement(void) {
+
+    DISPMANX_DISPLAY_HANDLE_T display = 0;
+    DISPMANX_UPDATE_HANDLE_T update;
+    VC_DISPMANX_ALPHA_T alpha;
+    VC_RECT_T dst;
+    VC_RECT_T src = { 0, 0, cursor.cursorWidth << 16, cursor.cursorHeight << 16};
+    VC_RECT_T pixelRect = { 0, 0, cursor.cursorWidth, cursor.cursorHeight };
+    int rc;
+
+    display = vc_dispmanx_display_open(0 /* LCD */);
+    if (display == 0) {
+        GLASS_LOG_SEVERE("Cannot open display");
+        return;
+    }
+
+    update = vc_dispmanx_update_start(0);
+    alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE;
+    alpha.opacity = 0xff;
+    alpha.mask = (DISPMANX_RESOURCE_HANDLE_T) 0;
+    dst.x = cursor.x;
+    dst.y = cursor.y;
+    dst.width = cursor.cursorWidth;
+    dst.height = cursor.cursorHeight;
+    cursor.element = vc_dispmanx_element_add(
+                         update,
+                         display,
+                         2 /*layer*/,
+                         &dst,
+                         0 /*resource*/,
+                         &src,
+                         DISPMANX_PROTECTION_NONE,
+                         &alpha,
+                         0 /*clamp*/,
+                         0 /*transform*/);
+
+    vc_dispmanx_update_submit_sync(update);
+
+}
+
+
+static void fbDispmanRemoveDispmanxElement(void) {
+
+    if (cursor.element) {
+        DISPMANX_UPDATE_HANDLE_T update;
+        update = vc_dispmanx_update_start(0);
+        vc_dispmanx_element_remove(update, cursor.element);
+        vc_dispmanx_update_submit_sync(update);
+
+        cursor.element = 0;
+    }
+}
+
+static void fbDispmanCursorInitialize(int screenWidth, int screenHeight) {
+
+    // Init cursor fields
+    cursor.element = 0;
+    cursor.cursorWidth = 16;
+    cursor.cursorHeight = 16;
+    cursor.x = 0;
+    cursor.y = 0;
+    cursor.currentCursor = 0;
+    cursor.isVisible = 0;
+
+    cursor.screenWidth = screenWidth;
+    cursor.screenHeight = screenHeight;
+
+    fbDispmanAddDispmanxElement();
+
+    sem_init(&cursor.semaphore, 0, 0);
+    pthread_mutex_init(&cursor.mutex, NULL);
+    pthread_create(&cursor.thread, NULL, fbCursorUpdater, NULL);
+
+}
+
+
+static jlong fbDispmanCreateNativeCursor(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height) {
+
+    VC_RECT_T pixelRect;
+    int rc;
+    uint32_t imagePtr;
+    jbyte *allocatedBuffer = NULL;
+    DispmanCursorImage *cursorImage = (DispmanCursorImage *)malloc(sizeof(DispmanCursorImage));
+
+    //Width should be aligned to 16 pixels
+    if (width % 16 != 0) {
+        int newWidth = width + 16 - (width % 16);
+        allocatedBuffer = (jbyte *)malloc(newWidth * height * 4);
+        int i;
+        int offset = 0;
+        for (i = 0; i < height; ++i) {
+            memcpy(allocatedBuffer + offset, srcArray, width * 4);
+            memset(allocatedBuffer + offset + (width * 4), 0, (newWidth - width) * 4);
+            offset += newWidth * 4;
+            srcArray += width * 4;
+        }
+
+        width = newWidth;
+        srcArray = allocatedBuffer;
+    }
+
+    pixelRect.x = 0;
+    pixelRect.y = 0;
+    pixelRect.width = width;
+    pixelRect.height = height;
+
+    cursorImage->x = x;
+    cursorImage->y = y;
+    cursorImage->width = width;
+    cursorImage->height = height;
+    cursorImage->resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888,
+                            width,
+                            height,
+                            &imagePtr);
+    if (cursorImage->resource == 0) {
+        GLASS_LOG_SEVERE("Cannot create resource");
+        if (allocatedBuffer != NULL) {
+            free(allocatedBuffer);
+            allocatedBuffer = NULL;
+        }
+        free(cursorImage);
+        return 0;
+    }
+
+    rc = vc_dispmanx_resource_write_data(cursorImage->resource,
+                                         VC_IMAGE_ARGB8888,
+                                         width * 4,
+                                         srcArray,
+                                         &pixelRect);
+
+    if (allocatedBuffer != NULL) {
+        free(allocatedBuffer);
+        allocatedBuffer = NULL;
+    }
+
+    if (rc != 0) {
+        GLASS_LOG_SEVERE("Cannot write pixels");
+        free(cursorImage);
+        return 0;
+    }
+
+    return ptr_to_jlong(cursorImage);
+}
+
+
+
+
+static void fbDispmanReleaseNativeCursor(jlong nativeCursorHandle) {
+
+    DispmanCursorImage *cursorImage = (DispmanCursorImage *)jlong_to_ptr(nativeCursorHandle);
+
+    if (cursorImage != NULL && cursorImage->resource != 0) {
+        vc_dispmanx_resource_delete(cursorImage->resource);
+    }
+
+    free(cursorImage);
+}
+
+
+static void fbDispmanSetVisible(jboolean isVisible) {
+
+    if (isVisible) {
+        if (!cursor.isVisible && cursor.currentCursor != 0) {
+            fbDispmanSetNativeCursor(cursor.currentCursor);
+        }
+    } 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;
+    }
+}
+
+
+
+static void *fbCursorUpdater(void *data) {
+    while (1) {
+        DISPMANX_UPDATE_HANDLE_T update;
+        VC_RECT_T dst;
+        sem_wait(&cursor.semaphore);
+        pthread_mutex_lock(&cursor.mutex);
+        dst.x = cursor.x;
+        dst.y = cursor.y;
+        dst.width = cursor.cursorWidth;
+        dst.height = cursor.cursorHeight;
+        pthread_mutex_unlock(&cursor.mutex);
+        update = vc_dispmanx_update_start(0);
+        vc_dispmanx_element_change_attributes(update,
+                                              cursor.element,
+                                              0x4 ,
+                                              0 , 0, 
+                                              &dst,
+                                              0 ,
+                                              0 , 0 );
+        vc_dispmanx_update_submit_sync(update);
+        usleep(16666); /* sleep a sixtieth of a second before moving again */
+    }
+    return NULL;
+}
+
+static void fbDispmanCursorSetPosition(int x, int y) {
+
+    if (cursor.element) {
+        int posted;
+        pthread_mutex_lock(&cursor.mutex);
+        cursor.x = x;
+        cursor.y = y;
+        sem_getvalue(&cursor.semaphore, &posted);
+        pthread_mutex_unlock(&cursor.mutex);
+        if (posted == 0) {
+            sem_post(&cursor.semaphore);
+        }
+    } else {
+        cursor.x = x;
+        cursor.y = y;
+    }
+}
+
+static void _fbDispmanCursorClose() {
+
+    fbDispmanRemoveDispmanxElement();
+    cursor.isVisible = 0;
+}
+
+static jboolean fbDispmanRobotScreenCapture(jint x, jint y,
+                                            jint width, jint height,
+                                            jint *pixels) {
+    FILE *fb;
+    unsigned int *pixelBuffer = NULL;
+    unsigned char *pixelBufferPtr = NULL;
+    unsigned char *dst = (unsigned char *) pixels;
+    int i = 0;
+    int fbFileHandle;
+    struct fb_var_screeninfo screenInfo;
+    unsigned int dstByteStride = width * 4;
+    VC_IMAGE_TRANSFORM_T transform = 0;
+    DISPMANX_RESOURCE_HANDLE_T resource = 0;
+    DISPMANX_DISPLAY_HANDLE_T display = 0;
+    DISPMANX_RESOURCE_HANDLE_T screenResource = 0;
+    uint32_t imagePtr;
+    int rc;
+
+    GLASS_LOG_FINE("Capture %i,%i+%ix%i", x, y, width, height);
+
+    if (width < 1 || height < 1) {
+        GLASS_LOG_SEVERE("Failed. width/height values must be at least = 1");
+        return JNI_FALSE;
+    }
+
+    GLASS_LOG_FINE("open(%s, O_RDONLY)", FB_DEVICE);
+    fbFileHandle = open(FB_DEVICE, O_RDONLY);
+    if (fbFileHandle < 0) {
+        GLASS_LOG_SEVERE("Cannot open framebuffer");
+        return JNI_FALSE;
+    }
+
+    GLASS_LOG_FINE("ioctl(%s, FBIOGET_VSCREENINFO)", FB_DEVICE);
+    if (ioctl(fbFileHandle, FBIOGET_VSCREENINFO, &screenInfo)) {
+        GLASS_LOG_SEVERE("Cannot get screen info");
+        GLASS_LOG_FINE("close(%s)", FB_DEVICE);
+        close(fbFileHandle);
+        return JNI_FALSE;
+    }
+    GLASS_LOG_FINE("Read screen info: res=%ix%i, offset=%ix%i",
+                   screenInfo.xres, screenInfo.yres,
+                   screenInfo.xoffset, screenInfo.yoffset);
+    GLASS_LOG_FINE("close(%s)", FB_DEVICE);
+    close(fbFileHandle);
+
+    VC_RECT_T pixelRect = { 0, 0, screenInfo.xres, screenInfo.yres };
+
+    int pixelBufferLength = screenInfo.xres * screenInfo.yres * 4;
+    pixelBuffer = (unsigned int *) malloc(pixelBufferLength);
+    pixelBufferPtr = (unsigned char *) pixelBuffer;
+
+    if (pixelBuffer == NULL) {
+        printf("Failed to allocate temporary pixel buffer\n");
+        return JNI_FALSE;
+    }
+
+    GLASS_LOG_FINE("fopen(%s, \"r\") to read %ix%i pixels at bit depth %i\n",
+                   FB_DEVICE, width, height, screenInfo.bits_per_pixel);
+
+    display = vc_dispmanx_display_open(0 /* LCD */);
+    if (display == 0) {
+        fprintf(stderr, "fbRobotScreenCapture: Dispman: Cannot open display\n");
+        free(pixelBuffer);
+        return JNI_FALSE;
+    }
+
+    // create the resource for the snapshot
+    screenResource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, screenInfo.xres, screenInfo.yres, &imagePtr);
+    if (!screenResource) {
+        fprintf(stderr, "fbRobotScreenCapture: Cannot create resource\n");
+        vc_dispmanx_display_close(display);
+        free(pixelBuffer);
+        return JNI_FALSE;
+    }
+
+    rc = vc_dispmanx_snapshot(display, screenResource, transform);
+    rc = 0;
+    if (rc) {
+        fprintf(stderr, "fbRobotScreenCapture: snapshot failed\n");
+        vc_dispmanx_display_close(display);
+        free(pixelBuffer);
+        return JNI_FALSE;
+    }
+
+    rc = vc_dispmanx_resource_read_data(screenResource, &pixelRect, pixelBuffer, screenInfo.xres * 4);
+
+    if (rc) {
+        fprintf(stderr, "fbRobotScreenCapture: Cannot read pixels %d\n", rc);
+        vc_dispmanx_display_close(display);
+        free(pixelBuffer);
+        return JNI_FALSE;
+    }
+
+    rc = vc_dispmanx_resource_delete(screenResource);
+    if (rc) {
+        fprintf(stderr, "fbRobotScreenCapture: failed to free buffer %d\n", rc);
+        vc_dispmanx_display_close(display);
+        free(pixelBuffer);
+        return JNI_FALSE;
+    }
+    screenResource = 0;
+
+    if (x < 0) {
+        pixelBuffer += -x;
+        width += x;
+        x = 0;
+    }
+    if (y < 0) {
+        pixelBuffer += -y * (int)screenInfo.xres;
+        height += y;
+        y = 0;
+    }
+
+    int widthLimit = width;
+    int heightLimit = height;
+
+    // Required height is larger than screen's height
+    if ((int) screenInfo.yres < height) {
+        heightLimit = (int) screenInfo.yres;
+    }
+    // Required width is larger than screen's width
+    if ((int) screenInfo.xres < width) {
+        widthLimit = (int) screenInfo.xres;
+    }
+    // Required height is out of range
+    if (((int) screenInfo.yres - y) < height) {
+        heightLimit = (int) screenInfo.yres - y;
+    }
+    // Required width is out of range
+    if (((int) screenInfo.xres - x) < width) {
+        widthLimit = (int) screenInfo.xres - x;
+    }
+
+    if (widthLimit > 0 && heightLimit > 0) {
+        // copy the relevant portion of the screen to the supplied pixel array
+        int offset = y * screenInfo.xres * 4 + x * 4;
+        for (i = 0; i < heightLimit; i++) {
+            memcpy(dst + i * dstByteStride, pixelBufferPtr + offset, widthLimit * 4);
+            offset += screenInfo.xres * 4;
+        }
+    } else {
+        GLASS_LOG_SEVERE("Failed to take a snapshot, some of parameters are illegal");
+        free(pixelBuffer);
+        return JNI_FALSE;
+    }
+
+    vc_dispmanx_display_close(display);
+    free(pixelBuffer);
+    return JNI_TRUE;
+}
+
+void select_dispman() {
+    fbPlatformSetNativeCursor = fbDispmanSetNativeCursor;
+    fbPlatformCursorInitialize = fbDispmanCursorInitialize;
+    fbPlatformCursorSetPosition = fbDispmanCursorSetPosition;
+    fbPlatformCursorClose = _fbDispmanCursorClose;
+    fbPlatformCreateNativeCursor = fbDispmanCreateNativeCursor;
+    fbPlatformReleaseNativeCursor = fbDispmanReleaseNativeCursor;
+    fbPlatformSetVisible = fbDispmanSetVisible;
+    fbRobotScreenCapture = fbDispmanRobotScreenCapture;
+    fbPlatformCursorTranslucency = JNI_TRUE;
+}
+
+#else // !USE_DISPMAN
+void select_dispman() {}
+#endif //USE_DISPMAN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/fbRobot.c	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "utilInternal.h"
+#include "platformUtil.h"
+
+#include "LensLogger.h"
+
+#ifdef USE_FB_ROBOT
+
+jboolean fbFBRobotScreen(jint x, jint y,
+                                    jint width, jint height,
+                                    jint *pixels) {
+
+    FILE *fb;
+    unsigned char *pixelBuffer = NULL;
+    unsigned char *dst = (unsigned char *) pixels;
+    unsigned int dstByteStride = width * 4;
+    int i = 0;
+    int fbFileHandle;
+    struct fb_var_screeninfo screenInfo;
+    int depth; // pixel size in bytes
+
+    GLASS_LOG_FINE("Capture %i,%i+%ix%i", x, y, width, height);
+    jboolean result = JNI_FALSE;
+
+    if (width < 1 || height < 1) {
+        GLASS_LOG_SEVERE("Failed. width/height values must be at least = 1");
+        return JNI_FALSE;
+    }
+
+    GLASS_LOG_FINE("open(%s, O_RDONLY)", FB_DEVICE);
+    fbFileHandle = open(FB_DEVICE, O_RDONLY);
+    if (fbFileHandle < 0) {
+        GLASS_LOG_SEVERE("Cannot open framebuffer");
+        return JNI_FALSE;
+    }
+    GLASS_LOG_FINE("ioctl(%s, FBIOGET_VSCREENINFO)", FB_DEVICE);
+    if (ioctl(fbFileHandle, FBIOGET_VSCREENINFO, &screenInfo)) {
+        GLASS_LOG_SEVERE("Cannot get screen info");
+        return JNI_FALSE;
+    }
+    GLASS_LOG_FINE("Read screen info: res=%ix%i, offset=%ix%i",
+                   screenInfo.xres, screenInfo.yres,
+                   screenInfo.xoffset, screenInfo.yoffset);
+    GLASS_LOG_FINE("close(%s)", FB_DEVICE);
+    close(fbFileHandle);
+    depth = screenInfo.bits_per_pixel / 8;
+    int pixelBufferLength = screenInfo.xres * screenInfo.yres * depth;
+    pixelBuffer = (unsigned char *) malloc(pixelBufferLength);
+    if (pixelBuffer == NULL) {
+        GLASS_LOG_SEVERE("Failed to allocate temporary pixel buffer");
+        return JNI_FALSE;
+    }
+
+    GLASS_LOG_FINE("fopen(%s, \"r\") to read %ix%i pixels at bit depth %i",
+                   FB_DEVICE, width, height, screenInfo.bits_per_pixel);
+    fb = fopen(FB_DEVICE, "r");
+    if (fb == NULL) {
+        GLASS_LOG_SEVERE("FB: Cannot open framebuffer for reading");
+        free(pixelBuffer);
+        return JNI_FALSE;
+    }
+
+    fseek(fb, screenInfo.yoffset * screenInfo.xres * depth, SEEK_SET);
+    int numRead = fread(pixelBuffer, 1,
+                        pixelBufferLength,
+                        fb);
+
+    if (x < 0) {
+        dst += -x * 4;
+        width += x;
+        x = 0;
+    }
+    if (y < 0) {
+        dst += -y * dstByteStride;
+        height += y;
+        y = 0;
+    }
+
+    int widthLimit = width;
+    int heightLimit = height;
+
+    // Required height is larger than screen's height
+    if ((int) screenInfo.yres < height) {
+        heightLimit = (int) screenInfo.yres;
+    }
+    // Required width is larger than screen's width
+    if ((int) screenInfo.xres < width) {
+        widthLimit = (int) screenInfo.xres;
+    }
+    // Required height is out of range
+    if (((int) screenInfo.yres - y) < height) {
+        heightLimit = (int) screenInfo.yres - y;
+    }
+    // Required width is out of range
+    if (((int) screenInfo.xres - x) < width) {
+        widthLimit = (int) screenInfo.xres - x;
+    }
+
+    if (widthLimit > 0 && heightLimit > 0) {
+        // copy the relevant portion of the screen to the supplied pixel array
+        int offset = y * screenInfo.xres * depth + x * depth;
+        for (i = 0; i < heightLimit; i++) {
+            memcpy(dst + i * dstByteStride, pixelBuffer + offset, widthLimit * depth);
+            offset += screenInfo.xres * depth;
+        }
+    } else {
+        free(pixelBuffer);
+        fclose(fb);
+        GLASS_LOG_FINE("fclose(%s)", FB_DEVICE);
+        GLASS_LOG_SEVERE("Failed to take a snapshot, some of parameters are illegal");
+        return JNI_FALSE;
+    }
+
+    free(pixelBuffer);
+    GLASS_LOG_FINE("fclose(%s)", FB_DEVICE);
+    fclose(fb);
+    return JNI_TRUE;
+}
+
+#endif // USE_FB_ROBOT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/initPlatform.c	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+// this define causes us to define our static vars in this module
+#define FB_PLATFORM_DECLARE
+
+#include "utilInternal.h"
+#include "platformUtil.h"
+
+//this is a hack until we can figure out how to share between glass/prism/port
+int glass_log_level = 0;
+
+#ifdef USE_DISPMAN
+extern int load_bcm_symbols();
+extern void select_dispman();
+
+static jboolean try_dispman() {
+    if (load_bcm_symbols()) {
+        select_dispman();
+        return JNI_TRUE;
+    } 
+    return JNI_FALSE;
+}
+#else
+static jboolean try_dispman() { return JNI_FALSE; }
+#endif // USE_DISPMAN
+
+#ifdef OMAP3
+extern void select_omap_cursor();
+
+extern jboolean fbFBRobotScreen(jint x, jint y,
+                                    jint width, jint height,
+                                    jint *pixels); 
+
+static jboolean try_omap3() { 
+    select_omap_cursor();
+    fbRobotScreenCapture = fbFBRobotScreen;
+    return JNI_TRUE;
+}
+#else
+static jboolean try_omap3() { return JNI_FALSE; }
+#endif
+
+#ifdef ANDROID_NDK
+static jboolean try_android() { return JNI_TRUE; }
+#else
+static jboolean try_android() { return JNI_FALSE; }
+#endif
+
+#ifdef EGL_X11_FB_CONTAINER
+static jboolean try_x11_container() { return JNI_TRUE; }
+#else
+static jboolean try_x11_container() { return JNI_FALSE; }
+#endif
+
+void platform_initialize() {
+    if(try_dispman()) {
+       return;
+    }
+
+    if(try_omap3()) {
+        return;
+    }
+
+    if(try_android()) {
+        return;
+    }
+
+    if(try_x11_container()) {
+        return;
+    }
+
+    // Fatal Error
+    fprintf(stderr,"Fatal error loading native porting layer in Lens\n");
+    exit(-1);
+}
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/omapCursor.c	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+ 
+#include "input/LensInput.h"
+
+#include "utilInternal.h"
+#include "platformUtil.h"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/fb.h>
+#include <sys/ioctl.h>
+
+#if defined(OMAP3)
+
+#include <linux/omapfb.h>
+
+typedef struct {
+    int fd;
+    struct omapfb_plane_info plane;
+    int width;
+    int height;
+    int screenWidth;
+    int screenHeight;
+    jlong currentCursor;
+    jboolean isVisible;
+} FBCursor;
+
+typedef struct {
+    int width;
+    int height;
+    int bpp;
+    jbyte *buffer;
+} FBCursorImage;
+
+
+FBCursor cursor = { .fd = -1, .width = 0, .height = 0, .currentCursor = 0, .isVisible = 0};
+
+void fbOmapCursorClose() {
+    if (cursor.fd >= 0) {
+        cursor.plane.enabled = 0;
+        if (ioctl(cursor.fd, OMAPFB_SETUP_PLANE, &cursor.plane)) {
+            GLASS_LOG_SEVERE("Failed to disable cursor plane");
+        }
+        close(cursor.fd);
+        cursor.fd = -1;
+        cursor.isVisible = 0;
+    }
+}
+
+void fbOmapCreateCursor(jbyte *cursorImage, int width, int height, int bpp) {
+    struct fb_var_screeninfo screenInfo;
+    cursor.width = width;
+    cursor.height = height;
+
+    GLASS_LOG_FINE("open(%s, O_RDWR)", FB_CURSOR_DEVICE);
+    cursor.fd = open(FB_CURSOR_DEVICE, O_RDWR);
+    if (cursor.fd < 0) {
+        GLASS_LOG_SEVERE("Cannot open frame buffer device for cursor");
+        return;
+    }
+    if (ioctl(cursor.fd, FBIOGET_VSCREENINFO, &screenInfo)) {
+        GLASS_LOG_SEVERE("Cannot query screen info");
+        fbOmapCursorClose();
+        return;
+    }
+    screenInfo.xoffset = 0;
+    screenInfo.yoffset = 0;
+    screenInfo.xres = screenInfo.xres_virtual = cursor.width;
+    screenInfo.yres = screenInfo.yres_virtual = cursor.height;
+
+    if (ioctl(cursor.fd, FBIOPUT_VSCREENINFO, &screenInfo)) {
+        GLASS_LOG_SEVERE("Cannot set screen info");
+        fbOmapCursorClose();
+        return;
+    }
+    cursor.plane.enabled = 1;
+    cursor.plane.out_width = cursor.width;
+    cursor.plane.out_height = cursor.height;
+    if (ioctl(cursor.fd, OMAPFB_SETUP_PLANE, &cursor.plane)) {
+        GLASS_LOG_SEVERE("Cannot set plane info");
+        fbOmapCursorClose();
+        return;
+    }
+
+    if (ioctl(cursor.fd, OMAPFB_QUERY_PLANE, &cursor.plane)) {
+        GLASS_LOG_SEVERE("Cannot query plane info");
+        fbOmapCursorClose();
+        return;
+    }
+
+    // Set up the color key
+    struct omapfb_color_key color_key;
+    if (ioctl(cursor.fd, OMAPFB_GET_COLOR_KEY, &color_key)) {
+        GLASS_LOG_SEVERE("Cannot set color key");
+        return;
+    }
+
+    color_key.key_type = OMAPFB_COLOR_KEY_VID_SRC;
+    color_key.trans_key = LENSFB_CURSOR_COLOR_KEY;
+    if (ioctl(cursor.fd, OMAPFB_SET_COLOR_KEY, &color_key)) {
+        GLASS_LOG_SEVERE("OMAPFB_SET_COLOR_KEY");
+        return;
+    }
+
+    int cursorSize = cursor.width * cursor.height * bpp;
+    if (write(cursor.fd, cursorImage, cursorSize) < cursorSize) {
+        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) {
+    FBCursorImage *cursorImage;
+    int imageSize = width * height * 4;
+    cursorImage = (FBCursorImage *)malloc(sizeof(FBCursorImage) + imageSize);
+
+    cursorImage->width = width;
+    cursorImage->height = height;
+    cursorImage->bpp = 4;
+    cursorImage->buffer = (jbyte *)(cursorImage + 1);
+
+    {
+        int i;
+        for (i = 0; (i + 3) < imageSize; i += 4) {
+            if (srcArray[i + 3] != 0) {
+                cursorImage->buffer[i] = srcArray[i];
+                cursorImage->buffer[i + 1] = srcArray[i + 1];
+                cursorImage->buffer[i + 2] = srcArray[i + 2];
+                cursorImage->buffer[i + 3] = srcArray[i + 3];
+            } else {
+                // 171 == 0xAB of the color key.
+                cursorImage->buffer[i] = 171;
+                cursorImage->buffer[i + 1] = 171;
+                cursorImage->buffer[i + 2] = 171;
+                cursorImage->buffer[i + 3] = 171;
+            }
+        }
+    }
+    return ptr_to_jlong(cursorImage);
+}
+
+void fbOmapCursorInitialize(int screenWidth, int screenHeight) {
+    cursor.screenWidth = screenWidth;
+    cursor.screenHeight = screenHeight;
+}
+
+void fbOmapCursorSetPosition(int x, int y) {
+
+    if (x < 0) {
+        x = 0;
+    }
+    if (y < 0) {
+        y = 0;
+    }
+    if (x > cursor.screenWidth - cursor.width) {
+        x = cursor.screenWidth - cursor.width;
+    }
+    if (y > cursor.screenHeight - cursor.height) {
+        y = cursor.screenHeight - cursor.height;
+    }
+    cursor.plane.enabled = 1;
+    cursor.plane.pos_x = x;
+    cursor.plane.pos_y = y;
+    if (cursor.fd >= 0) {
+        if (ioctl(cursor.fd, OMAPFB_SETUP_PLANE, &cursor.plane)) {
+            GLASS_LOG_SEVERE("Cannot set plane info to show cursor at %i,%i", x, y);
+        }
+    }
+}
+
+void fbOmapSetNativeCursor(jlong nativeCursorPointer) {
+    FBCursorImage *cursorImage = (FBCursorImage *)jlong_to_ptr(nativeCursorPointer);
+    if (cursor.currentCursor == nativeCursorPointer) {
+        return;
+    }
+
+    cursor.currentCursor = nativeCursorPointer;
+
+    if (cursor.isVisible) {
+        fbOmapCursorClose();
+        fbOmapCreateCursor(cursorImage->buffer, cursorImage->width, cursorImage->height, cursorImage->bpp);
+    }
+}
+
+void fbOmapReleaseNativeCursor(jlong nativeCursorPointer) {
+    if (nativeCursorPointer != 0) {
+        FBCursorImage *cursorImage = (FBCursorImage *)jlong_to_ptr(nativeCursorPointer);
+        free(cursorImage);
+    }
+
+    if (cursor.currentCursor == nativeCursorPointer) {
+        fbCursorClose();
+        cursor.currentCursor = 0;
+    }
+}
+
+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);
+        }
+    } else {
+        fbOmapCursorClose();
+    }
+
+    cursor.isVisible = isVisible;
+}
+
+
+jboolean fbOmapPlatformCursorTranslucency() {
+    return JNI_FALSE;
+}
+
+void fbOmapCursorTerminate(void) {
+    fbOmapCursorClose();
+}
+
+void select_omap_cursor() {
+    fbPlatformSetNativeCursor = fbOmapSetNativeCursor;
+    fbPlatformCursorInitialize = fbOmapCursorInitialize;
+    fbPlatformCursorSetPosition = fbOmapCursorSetPosition;
+    fbPlatformCursorClose = fbOmapCursorClose;
+    fbPlatformCreateNativeCursor = fbOmapCreateNativeCursor;
+    fbPlatformReleaseNativeCursor = fbOmapReleaseNativeCursor;
+    fbPlatformSetVisible = fbOmapSetVisible;
+    fbPlatformCreateCursor = fbOmapCreateCursor;
+}
+
+#else // !OMAP3
+void select_omap_cursor() { }
+#endif // OMAP3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/platformUtil.h	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#include <jni.h>
+
+#define FB_DEVICE "/dev/fb0"
+
+#define FB_CURSOR_DEVICE "/dev/fb1"
+#define LENSFB_CURSOR_COLOR_KEY 0xABABABAB
+
+#if defined(OMAP3)
+#include <linux/omapfb.h>
+#endif
+
+#ifndef FB_PLATFORM_DECLARE
+#define FB_PLATFORM_DECLARE extern
+#endif
+
+// Called to intitialize the platform specific functions.
+// Must be called prior to other utility calls.
+extern void platform_initialize();
+
+// Cursor Specific Entries
+FB_PLATFORM_DECLARE void (*fbPlatformCreateCursor)(jbyte *cursorImage, int width, int height, int bpp);
+FB_PLATFORM_DECLARE void (*fbPlatformSetNativeCursor)(jlong nativeCursorPointer);
+FB_PLATFORM_DECLARE void (*fbPlatformCursorInitialize)(int screenWidth, int screenHeight);
+FB_PLATFORM_DECLARE void (*fbPlatformCursorSetPosition)(int x, int y);
+FB_PLATFORM_DECLARE void (*fbPlatformCursorClose)();
+FB_PLATFORM_DECLARE void (*fbPlatformCursorTerminate)();
+FB_PLATFORM_DECLARE jlong (*fbPlatformCreateNativeCursor)(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height);
+FB_PLATFORM_DECLARE void (*fbPlatformReleaseNativeCursor)(jlong nativeCursorPointer);
+FB_PLATFORM_DECLARE void (*fbPlatformSetVisible)(jboolean isVisible);
+FB_PLATFORM_DECLARE jboolean fbPlatformCursorTranslucency;
+FB_PLATFORM_DECLARE void (*fbPlatformSetNativeCursor)(jlong nativeCursorPointer);
+FB_PLATFORM_DECLARE jlong (*fbPlatformCreateNativeCursor)(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height);
+FB_PLATFORM_DECLARE void (*fbPlatformReleaseNativeCursor)(jlong nativeCursorPointer);
+FB_PLATFORM_DECLARE void (*fbPlatformSetVisible)(jboolean isVisible);
+FB_PLATFORM_DECLARE jboolean fbPlatformCursorTranslucency;
+FB_PLATFORM_DECLARE void (*fbPlatformSetNativeCursor)(jlong nativeCursorPointer);
+FB_PLATFORM_DECLARE void (*fbPlatformSetNativeCursor)(jlong nativeCursorPointer);
+
+// Robot Specific Entries
+FB_PLATFORM_DECLARE jboolean (*fbRobotScreenCapture)(jint x, jint y, jint width, jint height, jint *pixels);
+
+/*
+  todo:
+     extern void load_bcm_symbols();
+     static int loadedBcm = 0;
+     #ifdef USE_DISPMAN
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/utilInternal.h	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#ifdef OMAP3 
+# ifndef USE_FB_ROBOT
+    #define USE_FB_ROBOT
+# endif
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/wrapped_bcm.c	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+#include <stdio.h>
+#include <dlfcn.h>
+
+#define WRAPPEDAPI
+#include "wrapped_bcm.h"
+
+#ifdef USE_DISPMAN
+static int useDispman = 1;
+
+int load_bcm_symbols();
+
+/*************************************** BROADCOM ******************************************/
+void (*_bcm_host_init)(void);
+/*
+static int (*wr_vc_dispmanx_display_close)(DISPMANX_DISPLAY_HANDLE_T display);
+static DISPMANX_DISPLAY_HANDLE_T (*wr_vc_dispmanx_display_open) (uint32_t device);
+static DISPMANX_ELEMENT_HANDLE_T (*wr_vc_dispmanx_element_add) (DISPMANX_UPDATE_HANDLE_T update,
+        DISPMANX_DISPLAY_HANDLE_T display,
+        int32_t layer, const VC_RECT_T *dest_rect, DISPMANX_RESOURCE_HANDLE_T src,
+        const VC_RECT_T *src_rect, DISPMANX_PROTECTION_T protection,
+        VC_DISPMANX_ALPHA_T *alpha, DISPMANX_CLAMP_T *clamp, DISPMANX_TRANSFORM_T transform);
+static DISPMANX_UPDATE_HANDLE_T (*wr_vc_dispmanx_update_start)( int32_t priority);
+static int (*wr_vc_dispmanx_update_submit_sync)(DISPMANX_UPDATE_HANDLE_T update);
+static int (*wr_vc_dispmanx_resource_read_data)(DISPMANX_RESOURCE_HANDLE_T handle,
+                                                      const VC_RECT_T *p_rect, void *dst_address, uint32_t dst_pitch);
+static int (*wr_vc_dispmanx_resource_write_data)(DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type,
+                     int src_pitch, void *src_address, const VC_RECT_T *rect);
+static int (*wr_vc_dispmanx_element_remove)(DISPMANX_UPDATE_HANDLE_T update,
+                                                   DISPMANX_ELEMENT_HANDLE_T element);
+static int (*wr_vc_dispmanx_element_change_attributes)(DISPMANX_UPDATE_HANDLE_T update,
+                                                             DISPMANX_ELEMENT_HANDLE_T element,
+                                                             uint32_t change_flags,
+                                                             int32_t layer, uint8_t opacity,
+                                                             const VC_RECT_T *dest_rect,
+                                                             const VC_RECT_T *src_rect,
+                                                             DISPMANX_RESOURCE_HANDLE_T mask,
+                                                             VC_IMAGE_TRANSFORM_T transform);
+static DISPMANX_RESOURCE_HANDLE_T (*wr_vc_dispmanx_resource_create)(VC_IMAGE_TYPE_T type,
+                                                                          uint32_t width, uint32_t height,
+                                                                          uint32_t *native_image_handle);
+static int (*wr_vc_dispmanx_resource_delete)( DISPMANX_RESOURCE_HANDLE_T res );
+static int (*wr_vc_dispmanx_snapshot)(DISPMANX_DISPLAY_HANDLE_T display,
+                                             DISPMANX_RESOURCE_HANDLE_T snapshot_resource,
+                                             VC_IMAGE_TRANSFORM_T transform );
+
+static int (*wr_vc_dispmanx_element_change_source)( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element,
+                                                        DISPMANX_RESOURCE_HANDLE_T src );
+*/
+
+void bcm_host_init(void) {
+    if (!_bcm_host_init) {
+        load_bcm_symbols();
+    }
+    return (*_bcm_host_init)();
+}
+
+/*
+int vc_dispmanx_display_close(DISPMANX_DISPLAY_HANDLE_T display) {
+    return (*wr_vc_dispmanx_display_close)(display);
+}
+
+DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open(uint32_t device) {
+    return (*wr_vc_dispmanx_display_open)(device);
+}
+
+DISPMANX_ELEMENT_HANDLE_T vc_dispmanx_element_add (DISPMANX_UPDATE_HANDLE_T update,
+                                                            DISPMANX_DISPLAY_HANDLE_T display,
+                                                            int32_t layer, const VC_RECT_T *dest_rect,
+                                                            DISPMANX_RESOURCE_HANDLE_T src,
+                                                            const VC_RECT_T *src_rect,
+                                                            DISPMANX_PROTECTION_T protection,
+                                                            VC_DISPMANX_ALPHA_T *alpha,
+                                                            DISPMANX_CLAMP_T *clamp,
+                                                            DISPMANX_TRANSFORM_T transform) {
+
+    return (*wr_vc_dispmanx_element_add) (update, display, layer, dest_rect, src, src_rect, 
+        protection, alpha, clamp, transform);
+}
+
+DISPMANX_UPDATE_HANDLE_T vc_dispmanx_update_start( int32_t priority) {
+    return (*wr_vc_dispmanx_update_start)(priority);
+}
+
+int vc_dispmanx_update_submit_sync(DISPMANX_UPDATE_HANDLE_T update) {
+    return (*wr_vc_dispmanx_update_submit_sync)(update);
+}
+
+int vc_dispmanx_resource_write_data(DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type,
+                         int src_pitch, void *src_address, const VC_RECT_T *rect ) {
+    return (*wr_vc_dispmanx_resource_write_data)(res, src_type, src_pitch, src_address, rect);
+}
+
+int vc_dispmanx_resource_read_data(DISPMANX_RESOURCE_HANDLE_T handle,
+                                            const VC_RECT_T *p_rect, void *dst_address, uint32_t dst_pitch) {
+    return (*wr_vc_dispmanx_resource_read_data)(handle, p_rect, dst_address, dst_pitch);
+}
+
+int vc_dispmanx_element_remove(DISPMANX_UPDATE_HANDLE_T update,
+                                                    DISPMANX_ELEMENT_HANDLE_T element) {
+    return (*wr_vc_dispmanx_element_remove)(update, element);
+}
+
+int vc_dispmanx_element_change_attributes(DISPMANX_UPDATE_HANDLE_T update,
+                                                   DISPMANX_ELEMENT_HANDLE_T element, uint32_t change_flags,
+                                                   int32_t layer, uint8_t opacity,
+                                                   const VC_RECT_T *dest_rect,
+                                                   const VC_RECT_T *src_rect,
+                                                   DISPMANX_RESOURCE_HANDLE_T mask,
+                                                   VC_IMAGE_TRANSFORM_T transform) {
+    return (*wr_vc_dispmanx_element_change_attributes)(update, element, change_flags, layer, opacity, dest_rect,
+                                                     src_rect, mask, transform);
+}
+
+DISPMANX_RESOURCE_HANDLE_T vc_dispmanx_resource_create(VC_IMAGE_TYPE_T type,
+                                                                uint32_t width, uint32_t height,
+                                                                uint32_t *native_image_handle) {
+    return (*wr_vc_dispmanx_resource_create)(type, width, height, native_image_handle);
+}
+
+int vc_dispmanx_resource_delete( DISPMANX_RESOURCE_HANDLE_T res ) {
+    return (*wr_vc_dispmanx_resource_delete)(res);
+}
+
+int vc_dispmanx_snapshot(DISPMANX_DISPLAY_HANDLE_T display,
+                                   DISPMANX_RESOURCE_HANDLE_T snapshot_resource,
+                                   VC_IMAGE_TRANSFORM_T transform) {
+    return (*wr_vc_dispmanx_snapshot)(display, snapshot_resource, transform);
+}
+
+int vc_dispmanx_element_change_source(DISPMANX_UPDATE_HANDLE_T update, 
+                                               DISPMANX_ELEMENT_HANDLE_T element,
+                                               DISPMANX_RESOURCE_HANDLE_T src )
+{
+   return  (*wr_vc_dispmanx_element_change_source)(update,element,src);
+}
+*/
+
+int load_bcm_symbols() {
+    int error = 0;
+    void *lib = dlopen("libbcm_host.so", RTLD_NOW); // there is a couple of choices?
+
+    if (_bcm_host_init) {
+        fprintf(stderr,"BCM symbols already loaded\n");
+        // already loaded
+        return useDispman;
+    }
+
+    if (!lib) {
+        useDispman = 0;
+        return useDispman;
+    } else {
+        useDispman = 1;
+    }
+
+    if (!(_bcm_host_init = dlsym(lib,"bcm_host_init"))) error++;
+    if (!(wr_vc_dispmanx_display_close = dlsym(lib,"vc_dispmanx_display_close"))) error++;
+    if (!(wr_vc_dispmanx_display_open = dlsym(lib,"vc_dispmanx_display_open"))) error++;
+    if (!(wr_vc_dispmanx_element_add = dlsym(lib,"vc_dispmanx_element_add"))) error++;
+    if (!(wr_vc_dispmanx_update_start = dlsym(lib,"vc_dispmanx_update_start"))) error++;
+    if (!(wr_vc_dispmanx_update_submit_sync = dlsym(lib,"vc_dispmanx_update_submit_sync"))) error++;
+    if (!(wr_vc_dispmanx_resource_write_data = dlsym(lib, "vc_dispmanx_resource_write_data"))) error++;
+    if (!(wr_vc_dispmanx_resource_read_data = dlsym(lib, "vc_dispmanx_resource_read_data"))) error++;
+    if (!(wr_vc_dispmanx_element_remove = dlsym(lib, "vc_dispmanx_element_remove"))) error++;
+    if (!(wr_vc_dispmanx_element_change_attributes = dlsym(lib, "vc_dispmanx_element_change_attributes"))) error++;
+    if (!(wr_vc_dispmanx_resource_create = dlsym(lib, "vc_dispmanx_resource_create"))) error++;
+    if (!(wr_vc_dispmanx_resource_delete = dlsym(lib, "vc_dispmanx_resource_delete"))) error++;
+    if (!(wr_vc_dispmanx_snapshot = dlsym(lib, "vc_dispmanx_snapshot"))) error++;
+    if (!(wr_vc_dispmanx_element_change_source = dlsym(lib, "vc_dispmanx_element_change_source"))) error++;
+
+    if (error) {
+        // handle error conditions better ?
+        fprintf(stderr,"failed to load all bcm_host symbols %d\n",error);
+        useDispman = 0;
+    }
+    return useDispman;
+}
+#else
+
+int load_bcm_symbols() {
+    return 0;
+}
+#endif /* USE_DISPMAN */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/lens/platform-util/wrapped_bcm.h	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+#ifndef __WRAPPED_BCM__
+#define __WRAPPED_BCM__
+
+#ifndef WRAPPEDAPI
+#define WRAPPEDAPI extern
+#endif
+
+#ifdef USE_DISPMAN
+
+#ifndef BCM_HOST_H
+#include <bcm_host.h>
+#endif
+
+#if !defined(_VC_DISPMANX_H_)
+/* for Debian 6.0 libraries */
+typedef enum {
+   VC_IMAGE_ARGB8888 = 43,  /* 32bpp with 8bit alpha at MS byte, with R, G, B (LS byte) */
+} VC_IMAGE_TYPE_T;
+#endif
+
+#define vc_dispmanx_display_close(display) (*wr_vc_dispmanx_display_close)(display)
+
+#define vc_dispmanx_display_open(device) (*wr_vc_dispmanx_display_open)(device)
+
+#define vc_dispmanx_element_add(update, display, layer, dest_rect, src, src_rect, protection, alpha, clamp, transform) (*wr_vc_dispmanx_element_add)(update, display, layer, dest_rect, src, src_rect, protection, alpha, clamp, transform)
+
+#define vc_dispmanx_update_start(priority) (*wr_vc_dispmanx_update_start)(priority)
+
+#define vc_dispmanx_update_submit_sync(update) (*wr_vc_dispmanx_update_submit_sync)(update)
+
+#define vc_dispmanx_resource_read_data(handle, p_rect, dst_address, dst_pitch) (*wr_vc_dispmanx_resource_read_data) (handle, p_rect, dst_address, dst_pitch)
+
+#define vc_dispmanx_resource_write_data(res, src_type, src_pitch, src_address, rect) (*wr_vc_dispmanx_resource_write_data)(res, src_type,src_pitch, src_address, rect)
+
+#define vc_dispmanx_element_remove(update, element) (*wr_vc_dispmanx_element_remove) (update, element)
+
+#define vc_dispmanx_element_change_attributes(update, element, change_flags, layer, opacity, dest_rect, src_rect, mask, transform) (*wr_vc_dispmanx_element_change_attributes) (update, element, change_flags, layer, opacity, dest_rect, src_rect, mask, transform)
+
+#define vc_dispmanx_resource_create(type, width, height, native_image_handle) (*wr_vc_dispmanx_resource_create) (type, width, height, native_image_handle)
+
+#define vc_dispmanx_resource_delete(res) (*wr_vc_dispmanx_resource_delete)(res )
+
+#define vc_dispmanx_snapshot(display, snapshot_resource, transform) (*wr_vc_dispmanx_snapshot) (display, snapshot_resource, transform )
+
+#define vc_dispmanx_element_change_source(update, element, src) (*wr_vc_dispmanx_element_change_source) (update, element, src )
+
+/* wrapped method declarations */
+WRAPPEDAPI int (*wr_vc_dispmanx_display_close)(DISPMANX_DISPLAY_HANDLE_T display);
+
+WRAPPEDAPI DISPMANX_DISPLAY_HANDLE_T (*wr_vc_dispmanx_display_open)
+                                      (uint32_t device);
+
+WRAPPEDAPI DISPMANX_ELEMENT_HANDLE_T (*wr_vc_dispmanx_element_add) 
+                                      (DISPMANX_UPDATE_HANDLE_T update,
+                                       DISPMANX_DISPLAY_HANDLE_T display,
+                                       int32_t layer, const VC_RECT_T *dest_rect, 
+                                       DISPMANX_RESOURCE_HANDLE_T src,
+                                       const VC_RECT_T *src_rect, 
+                                       DISPMANX_PROTECTION_T protection,
+                                       VC_DISPMANX_ALPHA_T *alpha, 
+                                       DISPMANX_CLAMP_T *clamp, 
+                                       DISPMANX_TRANSFORM_T transform);
+
+WRAPPEDAPI DISPMANX_UPDATE_HANDLE_T (*wr_vc_dispmanx_update_start)
+                                     (int32_t priority);
+
+WRAPPEDAPI int (*wr_vc_dispmanx_update_submit_sync)
+                (DISPMANX_UPDATE_HANDLE_T update);
+
+WRAPPEDAPI int (*wr_vc_dispmanx_resource_read_data)
+                (DISPMANX_RESOURCE_HANDLE_T handle,
+                 const VC_RECT_T *p_rect, void *dst_address, uint32_t dst_pitch);
+
+WRAPPEDAPI int (*wr_vc_dispmanx_resource_write_data)
+                (DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type,
+                 int src_pitch, void *src_address, const VC_RECT_T *rect);
+
+WRAPPEDAPI int (*wr_vc_dispmanx_element_remove)
+                (DISPMANX_UPDATE_HANDLE_T update,
+                 DISPMANX_ELEMENT_HANDLE_T element);
+
+WRAPPEDAPI int (*wr_vc_dispmanx_element_change_attributes)
+                (DISPMANX_UPDATE_HANDLE_T update,
+                 DISPMANX_ELEMENT_HANDLE_T element, uint32_t change_flags,
+                 int32_t layer, uint8_t opacity, const VC_RECT_T *dest_rect,
+                 const VC_RECT_T *src_rect, DISPMANX_RESOURCE_HANDLE_T mask,
+                 VC_IMAGE_TRANSFORM_T transform);
+
+WRAPPEDAPI DISPMANX_RESOURCE_HANDLE_T (*wr_vc_dispmanx_resource_create)
+                                       (VC_IMAGE_TYPE_T type, uint32_t width, 
+                                        uint32_t height, 
+                                        uint32_t *native_image_handle);
+
+WRAPPEDAPI int (*wr_vc_dispmanx_resource_delete)
+                (DISPMANX_RESOURCE_HANDLE_T res);
+
+WRAPPEDAPI int (*wr_vc_dispmanx_snapshot) (DISPMANX_DISPLAY_HANDLE_T display, 
+                DISPMANX_RESOURCE_HANDLE_T snapshot_resource,
+                VC_IMAGE_TRANSFORM_T transform);
+
+WRAPPEDAPI int (*wr_vc_dispmanx_element_change_source)
+                (DISPMANX_UPDATE_HANDLE_T update, 
+                 DISPMANX_ELEMENT_HANDLE_T element,
+                 DISPMANX_RESOURCE_HANDLE_T src);
+
+#endif // __WRAPPED_BCM__
+#endif // USE_DISPMAN
--- a/modules/graphics/src/main/native-glass/lens/wm/LensWindowManager.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/wm/LensWindowManager.c	Tue Aug 20 09:38:00 2013 -0700
@@ -35,6 +35,8 @@
 #include <stdio.h>
 #include <pthread.h>
 
+#include "platform-util/platformUtil.h"
+
 static pthread_mutex_t renderMutex = PTHREAD_MUTEX_INITIALIZER;
 
 static int _mousePosX;
@@ -81,6 +83,7 @@
     jboolean result;
 
     GLASS_LOG_FINE("Init device");
+    platform_initialize();
     result = glass_application_initialize(env);
     if (result) {
         GLASS_LOG_FINE("Init screen");
@@ -90,7 +93,7 @@
             lens_wm_clearScreen();
 
             GLASS_LOG_FINE("Cursor init");
-            fbCursorInitialize();
+            fbCursorInitialize(mainScreen->width, mainScreen->height);
 
             lens_wm_initRFB(env);
             GLASS_LOG_FINE("Init input devices");
@@ -1043,74 +1046,73 @@
 
 // check for window grab then forward event to application.
 // check for focus changes and handle them.
-void lens_wm_notifyTouchEvent(JNIEnv *env,
-                              jint state,
-                              int id,
-                              int xabs, int yabs) {
+void lens_wm_notifyMultiTouchEvent(JNIEnv *env,
+                                   jint count,
+                                   jint *states,
+                                   jlong *ids,
+                                   int *xabs, int *yabs) {
 
-    int relX, relY;
+    int i;
+    int dx, dy;
     NativeWindow window;
+    jboolean allReleased;
 
     //cache new coordinates
-    _mousePosX = xabs;
-    _mousePosY = yabs;
+    _mousePosX = xabs[0];
+    _mousePosY = yabs[0];
 
     fbCursorSetPosition(_mousePosX, _mousePosY);
 
-    window = glass_window_findWindowAtLocation(xabs, yabs,
+    if (_dragGrabbingWindow == NULL) {
+        int relX, relY;
+        window = glass_window_findWindowAtLocation(xabs[0], yabs[0],
                           &relX, &relY);
-
-    lens_wm_setMouseWindow(window);
-
-    if (state == com_sun_glass_events_TouchEvent_TOUCH_PRESSED) {
-        _mousePressed = JNI_TRUE;
-    } else if (state == com_sun_glass_events_TouchEvent_TOUCH_RELEASED) {
-        _mousePressed = JNI_FALSE;
+        dx = relX - xabs[0];
+        dy = relY - yabs[0];
+        lens_wm_setMouseWindow(window);
     } else {
-        GLASS_LOG_SEVERE("Unexpected state %d", state);
+        window = _dragGrabbingWindow;
+        dx = -window->currentBounds.x;
+        dy = -window->currentBounds.y;
     }
 
-    if (_mousePressed && window) {
-        // Pressed on window
-        glass_application_notifyMouseEvent(env,
-                                           window,
-                                           com_sun_glass_events_MouseEvent_ENTER,
-                                           relX, relY, xabs, yabs,
-                                           com_sun_glass_events_MouseEvent_BUTTON_NONE);
-        glass_application_notifyTouchEvent(env,
-                                           window,
-                                           com_sun_glass_events_TouchEvent_TOUCH_PRESSED,
-                                           id,
-                                           relX, relY, xabs, yabs);
+    if (states[0] == com_sun_glass_events_TouchEvent_TOUCH_PRESSED && !_mousePressed) {
+        _mousePressed = JNI_TRUE;
+        if (window) {
+            // Pressed on window
+            glass_application_notifyMouseEvent(env,
+                                               window,
+                                               com_sun_glass_events_MouseEvent_ENTER,
+                                               xabs[0] + dx, yabs[0] + dy, xabs[0], yabs[0],
+                                               com_sun_glass_events_MouseEvent_BUTTON_NONE);
+        }
     }
 
-
-    if (!_mousePressed) {
-        if (!_onDraggingAction && window) {
-            //Press-release on a window without a move in between.
-            glass_application_notifyTouchEvent(env,
-                                               window,
-                                               com_sun_glass_events_TouchEvent_TOUCH_RELEASED,
-                                               id,
-                                               relX, relY, xabs, yabs);
-
-        } else if (_onDraggingAction && _dragGrabbingWindow != NULL) {
-            //Finished drag that started on actual window.
-            relX = xabs - _dragGrabbingWindow->currentBounds.x;
-            relY = yabs - _dragGrabbingWindow->currentBounds.y;
-            glass_application_notifyTouchEvent(env,
-                                               _dragGrabbingWindow,
-                                               com_sun_glass_events_TouchEvent_TOUCH_RELEASED,
-                                               id,
-                                               relX, relY, xabs, yabs);
+    allReleased = JNI_TRUE;
+    for (i = 0; i < count && allReleased; i++) {
+        if (states[i] != com_sun_glass_events_TouchEvent_TOUCH_RELEASED) {
+            allReleased = JNI_FALSE;
         }
-
+    }
+    if (allReleased) {
+        _mousePressed = JNI_FALSE;
         _onDraggingAction = JNI_FALSE;
         _dragGrabbingWindow = NULL;
-
+        glass_inputEvents_updateMouseButtonModifiers(
+            com_sun_glass_events_MouseEvent_BUTTON_LEFT,
+            com_sun_glass_events_MouseEvent_DOWN);
+    } else {
+        glass_inputEvents_updateMouseButtonModifiers(
+            com_sun_glass_events_MouseEvent_BUTTON_LEFT,
+            com_sun_glass_events_MouseEvent_UP);
     }
 
-    handleClickOrTouchEvent(env, xabs, yabs);
+    if (window != NULL) {
+        glass_application_notifyMultiTouchEvent(env, window, count,
+                                                states, ids, xabs, yabs,
+                                                dx, dy);
+    }
+    handleClickOrTouchEvent(env, xabs[0] + dx, yabs[0] + dy);
 
 }
 
--- a/modules/graphics/src/main/native-glass/lens/wm/LensWindowManager.h	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/wm/LensWindowManager.h	Tue Aug 20 09:38:00 2013 -0700
@@ -114,16 +114,18 @@
 
 
 /**
- * Check a touch event before passing it to
- * glass_application_notifyTouchEvent
- * so that grabbed window checks can be made.
+ * Process a touch or multitouch event and pass it on to
+ * glass_application_notifyTouchEvent or
+ * glass_application_notifyMultiTouchEvent, taking into account the grabbed
+ * window.
  * Note: a NULL window is appropriate as that 
  * will cause the grab window to be release.
  */
-void lens_wm_notifyTouchEvent(JNIEnv *env,
-                                         jint state, 
-                                         int id,
-                                         int xabs, int yabs) ;
+void lens_wm_notifyMultiTouchEvent(JNIEnv *env,
+                                   int count,
+                                   jint *state,
+                                   jlong *ids,
+                                   int *xabs, int *yabs);
 
 
 /**
--- a/modules/graphics/src/main/native-glass/lens/wm/screen/fbdevScreen.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/lens/wm/screen/fbdevScreen.c	Tue Aug 20 09:38:00 2013 -0700
@@ -38,17 +38,7 @@
 #include <linux/fb.h>
 #include <sys/ioctl.h>
 
-#define FB_DEVICE "/dev/fb0"
-
-extern int useDispman;
-extern void load_bcm_symbols();
-static int loadedBcm = 0;
-#ifdef USE_DISPMAN
-extern jboolean dispman_glass_robot_screen_capture(jint x, jint y,
-                                                   jint width, jint height,
-                                                   jint *pixels);
-#endif
-
+#include "platform-util/platformUtil.h"
 
 static struct _NativeScreen fbScreen;
 
@@ -333,124 +323,10 @@
                                     jint width, jint height,
                                     jint *pixels) {
 
-    if (!loadedBcm) {
-        load_bcm_symbols();
-        loadedBcm = 1;
+    if (fbRobotScreenCapture) {
+       return (*fbRobotScreenCapture)(x, y, width, height, pixels);
     }
-
-    if (useDispman) {
-#ifdef USE_DISPMAN
-        return dispman_glass_robot_screen_capture(x, y, width, height, pixels);
-#else
-        return JNI_FALSE; // cannot reach here
-#endif
-    } else {
-        FILE *fb;
-        unsigned char *pixelBuffer = NULL;
-        unsigned char *dst = (unsigned char *) pixels;
-        unsigned int dstByteStride = width * 4;
-        int i = 0;
-        int fbFileHandle;
-        struct fb_var_screeninfo screenInfo;
-        int depth; // pixel size in bytes
-
-        GLASS_LOG_FINE("Capture %i,%i+%ix%i", x, y, width, height);
-        jboolean result = JNI_FALSE;
-
-        if (width < 1 || height < 1) {
-            GLASS_LOG_SEVERE("Failed. width/height values must be at least = 1");
-            return JNI_FALSE;
-        }
-
-        GLASS_LOG_FINE("open(%s, O_RDONLY)", FB_DEVICE);
-        fbFileHandle = open(FB_DEVICE, O_RDONLY);
-        if (fbFileHandle < 0) {
-            GLASS_LOG_SEVERE("Cannot open framebuffer");
-            return JNI_FALSE;
-        }
-        GLASS_LOG_FINE("ioctl(%s, FBIOGET_VSCREENINFO)", FB_DEVICE);
-        if (ioctl(fbFileHandle, FBIOGET_VSCREENINFO, &screenInfo)) {
-            GLASS_LOG_SEVERE("Cannot get screen info");
-            return JNI_FALSE;
-        }
-        GLASS_LOG_FINE("Read screen info: res=%ix%i, offset=%ix%i",
-                       screenInfo.xres, screenInfo.yres,
-                       screenInfo.xoffset, screenInfo.yoffset);
-        GLASS_LOG_FINE("close(%s)", FB_DEVICE);
-        close(fbFileHandle);
-        depth = screenInfo.bits_per_pixel / 8;
-        int pixelBufferLength = screenInfo.xres * screenInfo.yres * depth;
-        pixelBuffer = (unsigned char *) malloc(pixelBufferLength);
-        if (pixelBuffer == NULL) {
-            GLASS_LOG_SEVERE("Failed to allocate temporary pixel buffer");
-            return JNI_FALSE;
-        }
-
-        GLASS_LOG_FINE("fopen(%s, \"r\") to read %ix%i pixels at bit depth %i",
-                       FB_DEVICE, width, height, screenInfo.bits_per_pixel);
-        fb = fopen(FB_DEVICE, "r");
-        if (fb == NULL) {
-            GLASS_LOG_SEVERE("FB: Cannot open framebuffer for reading");
-            free(pixelBuffer);
-            return JNI_FALSE;
-        }
-
-        fseek(fb, screenInfo.yoffset * screenInfo.xres * depth, SEEK_SET);
-        int numRead = fread(pixelBuffer, 1,
-                            pixelBufferLength,
-                            fb);
-
-        if (x < 0) {
-            dst += -x * 4;
-            width += x;
-            x = 0;
-        }
-        if (y < 0) {
-            dst += -y * dstByteStride;
-            height += y;
-            y = 0;
-        }
-
-        int widthLimit = width;
-        int heightLimit = height;
-
-        // Required height is larger than screen's height
-        if ((int) screenInfo.yres < height) {
-            heightLimit = (int) screenInfo.yres;
-        }
-        // Required width is larger than screen's width
-        if ((int) screenInfo.xres < width) {
-            widthLimit = (int) screenInfo.xres;
-        }
-        // Required height is out of range
-        if (((int) screenInfo.yres - y) < height) {
-            heightLimit = (int) screenInfo.yres - y;
-        }
-        // Required width is out of range
-        if (((int) screenInfo.xres - x) < width) {
-            widthLimit = (int) screenInfo.xres - x;
-        }
-
-        if (widthLimit > 0 && heightLimit > 0) {
-            // copy the relevant portion of the screen to the supplied pixel array
-            int offset = y * screenInfo.xres * depth + x * depth;
-            for (i = 0; i < heightLimit; i++) {
-                memcpy(dst + i * dstByteStride, pixelBuffer + offset, widthLimit * depth);
-                offset += screenInfo.xres * depth;
-            }
-        } else {
-            free(pixelBuffer);
-            fclose(fb);
-            GLASS_LOG_FINE("fclose(%s)", FB_DEVICE);
-            GLASS_LOG_SEVERE("Failed to take a snapshot, some of parameters are illegal");
-            return JNI_FALSE;
-        }
-
-        free(pixelBuffer);
-        GLASS_LOG_FINE("fclose(%s)", FB_DEVICE);
-        fclose(fb);
-        return JNI_TRUE;
-    }
+    return 0;
 }
 
 LensResult lens_platform_windowMinimize(JNIEnv *env,
--- a/modules/graphics/src/main/native-glass/mac/GlassDialogs.m	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/mac/GlassDialogs.m	Tue Aug 20 09:38:00 2013 -0700
@@ -38,6 +38,66 @@
     #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__);
 #endif
 
+static BOOL doPerformKeyEquivalent(NSEvent* theEvent, NSWindow* panel)
+{
+    NSResponder* responder = [panel firstResponder];
+    if ([responder isKindOfClass:[NSText class]])
+    {
+        NSText* text = (NSText*)responder;
+        if ([theEvent type] == NSKeyDown
+            && ([theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask)
+        {    
+            NSRange range = [text selectedRange];
+            BOOL hasSelectedText = range.length > 0;
+            if ([theEvent keyCode] == 7 && hasSelectedText) // Cmd + X - Cut
+            {
+                [text cut:panel];
+                return true;
+            }
+            if ([theEvent keyCode] == 8 && hasSelectedText) // Cmd + C - Copy
+            {
+                [text copy:panel];
+                return true;
+            }
+            if ([theEvent keyCode] == 9) // Cmd + V - Paste
+            {
+                [text paste:panel];
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+@interface GlassSavePanel : NSSavePanel
+@end
+
+@implementation GlassSavePanel
+
+- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
+{
+    if (doPerformKeyEquivalent(theEvent, self)) {
+        return true;
+    }
+    return [super performKeyEquivalent:theEvent];
+}
+@end
+
+@interface GlassOpenPanel : NSOpenPanel
+@end
+
+@implementation GlassOpenPanel
+
+- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
+{
+    if (doPerformKeyEquivalent(theEvent, self)) {
+        return true;
+    }
+    return [super performKeyEquivalent:theEvent];
+}
+@end
+
+
 #pragma mark --- Dispatcher
 
 @interface DialogDispatcher : NSObject
@@ -267,12 +327,13 @@
 /*
  * Class:     com_sun_glass_ui_mac_MacFileNSURL
  * Method:    _getBookmark
- * Signature: (J)[B
+ * Signature: (JJ)[B
  */
 JNIEXPORT jbyteArray JNICALL Java_com_sun_glass_ui_mac_MacFileNSURL__1getBookmark
-(JNIEnv *env, jobject jMacFileNSURL, jlong ptr)
+(JNIEnv *env, jobject jMacFileNSURL, jlong ptr, jlong baseDocumentPtr)
 {
     NSURL * url = (NSURL*)jlong_to_ptr(ptr);
+    NSURL * baseUrl = (NSURL*)jlong_to_ptr(baseDocumentPtr); // May be 0L
     jbyteArray data = NULL;
     
     GLASS_POOL_ENTER;
@@ -280,7 +341,7 @@
         NSError *error = nil;
 
         NSData *nsData = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
-                       includingResourceValuesForKeys:nil relativeToURL:nil error:&error];
+                       includingResourceValuesForKeys:nil relativeToURL:baseUrl error:&error];
 
         if (error) {
             NSLog(@"ERROR in Glass calling bookmarkDataWithOptions: %@", error);
@@ -306,12 +367,13 @@
 /*
  * Class:     com_sun_glass_ui_mac_MacFileNSURL
  * Method:    _createFromBookmark
- * Signature: ([B)Lcom/sun/glass/ui/mac/MacFileNSURL;
+ * Signature: ([BJ)Lcom/sun/glass/ui/mac/MacFileNSURL;
  */
 JNIEXPORT jobject JNICALL Java_com_sun_glass_ui_mac_MacFileNSURL__1createFromBookmark
-(JNIEnv *env, jclass cls, jbyteArray data)
+(JNIEnv *env, jclass cls, jbyteArray data, jlong baseDocumentPtr)
 {
     jobject jMacFileNSURL = NULL;
+    NSURL * baseUrl = (NSURL*)jlong_to_ptr(baseDocumentPtr); // May be 0L
 
     GLASS_POOL_ENTER;
     {
@@ -331,7 +393,7 @@
 
             NSURL *url = [NSURL URLByResolvingBookmarkData:nsData
                 options:(NSURLBookmarkResolutionWithoutUI | NSURLBookmarkResolutionWithSecurityScope)
-                relativeToURL:nil bookmarkDataIsStale:&isStale error:&error];
+                relativeToURL:baseUrl bookmarkDataIsStale:&isStale error:&error];
 
             if (isStale) {
                 NSLog(@"URLByResolvingBookmarkData isStale=%d", isStale);
@@ -395,7 +457,7 @@
     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
     GLASS_POOL_ENTER;
     {
-        NSOpenPanel *panel = [NSOpenPanel openPanel];
+        NSOpenPanel *panel = [GlassOpenPanel openPanel];
         [panel setAllowsMultipleSelection:(jMultipleMode==JNI_TRUE)];
         [panel setTitle:[GlassHelper nsStringWithJavaString:jTitle withEnv:env]];
         NSString *folder = [GlassHelper nsStringWithJavaString:jFolder withEnv:env];
@@ -464,7 +526,7 @@
     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
     GLASS_POOL_ENTER;
     {
-        NSSavePanel *panel = [NSSavePanel savePanel];
+        NSSavePanel *panel = [GlassSavePanel savePanel];
         [panel setTitle:[GlassHelper nsStringWithJavaString:jTitle withEnv:env]];
         NSString *folder = [GlassHelper nsStringWithJavaString:jFolder withEnv:env];
         if ([folder length] > 0)
@@ -530,7 +592,7 @@
     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
     GLASS_POOL_ENTER;
     {
-        NSOpenPanel *panel = [NSOpenPanel openPanel];
+        NSOpenPanel *panel = [GlassOpenPanel openPanel];
         [panel setTitle:[GlassHelper nsStringWithJavaString:jTitle withEnv:env]];
         NSString *folder = [GlassHelper nsStringWithJavaString:jFolder withEnv:env];
         if ([folder length] > 0)
--- a/modules/graphics/src/main/native-glass/mac/GlassTouches.h	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/mac/GlassTouches.h	Tue Aug 20 09:38:00 2013 -0700
@@ -41,7 +41,6 @@
 
 + (void)startTracking:(GlassViewDelegate *)delegate;
 + (void)stopTracking:(GlassViewDelegate *)delegate;
-+ (void)updateTracking:(GlassViewDelegate *)oldDelegate newDelegate:(GlassViewDelegate *)newDelegate;
 + (void)terminate;
 
 @end
--- a/modules/graphics/src/main/native-glass/mac/GlassTouches.m	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/mac/GlassTouches.m	Tue Aug 20 09:38:00 2013 -0700
@@ -158,18 +158,6 @@
     LOG("TOUCHES: stopTracking: delegate=%p\n", glassTouches->curConsumer);
 }
 
-+ (void)updateTracking:(GlassViewDelegate *)oldDelegate newDelegate:(GlassViewDelegate *)newDelegate
-{
-    if (!glassTouches || glassTouches->curConsumer != oldDelegate)
-    {
-        return;
-    }
-
-    glassTouches->curConsumer = newDelegate;
-    
-    LOG("TOUCHES: updateTracking: old=%p new=%p\n", oldDelegate, glassTouches->curConsumer);
-}
-
 + (void)terminate
 {
     // Should be called right after Application's run loop terminate
--- a/modules/graphics/src/main/native-glass/mac/GlassViewDelegate.m	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/mac/GlassViewDelegate.m	Tue Aug 20 09:38:00 2013 -0700
@@ -44,6 +44,7 @@
 #import "GlassHelper.h"
 #import "GlassStatics.h"
 #import "GlassPasteboard.h"
+#import "GlassTouches.h"
 
 //#define VERBOSE
 #ifndef VERBOSE
@@ -369,11 +370,13 @@
             
         case NSMouseEntered:
             type = com_sun_glass_events_MouseEvent_ENTER;
+            [GlassTouches startTracking:self];
             self->lastTrackingNumber = [theEvent trackingNumber];
             break;
             
         case NSMouseExited:
             type = com_sun_glass_events_MouseEvent_EXIT;
+            [GlassTouches stopTracking:self];
             self->lastTrackingNumber = [theEvent trackingNumber];
             break;
             
--- a/modules/graphics/src/main/native-glass/mac/GlassWindow+Overrides.m	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/mac/GlassWindow+Overrides.m	Tue Aug 20 09:38:00 2013 -0700
@@ -74,8 +74,6 @@
         return;
     }
 
-    [GlassTouches startTracking:[self->view delegate]];
-
     (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyFocus, com_sun_glass_events_WindowEvent_FOCUS_GAINED);
     
     if (self->menubar != nil)
@@ -94,8 +92,6 @@
     
     [self _ungrabFocus];
 
-    [GlassTouches stopTracking:[self->view delegate]];
-
     GET_MAIN_JENV;
     (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyFocus, com_sun_glass_events_WindowEvent_FOCUS_LOST);
 }
--- a/modules/graphics/src/main/native-glass/mac/GlassWindow.m	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-glass/mac/GlassWindow.m	Tue Aug 20 09:38:00 2013 -0700
@@ -855,11 +855,6 @@
         //NSLog(@"        view: %@", window->view);
         //NSLog(@"                frame: %.2f,%.2f %.2fx%.2f", [window->view frame].origin.x, [window->view frame].origin.y, [window->view frame].size.width, [window->view frame].size.height);
 
-        // RT-24864: notify multi touch handling code that 
-        // view delegate has changed
-        [GlassTouches updateTracking:(oldView ? [oldView delegate] : nil) 
-                         newDelegate:(window->view ? [window->view delegate] : nil)];
-
         if (oldView && oldView != window->view) {
             [[oldView delegate] resetMouseTracking];
         }
--- a/modules/graphics/src/main/native-prism-d3d/D3DContext.cc	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-prism-d3d/D3DContext.cc	Tue Aug 20 09:38:00 2013 -0700
@@ -219,13 +219,18 @@
     UINT indexBufferSize = env->GetArrayLength(ib);
     USHORT *indexBuffer = (USHORT *) (env->GetPrimitiveArrayCritical(ib, NULL));
 
-    if (vertexBuffer == NULL || indexBuffer == NULL
-            || vbSize < 0 || vbSize > vertexBufferSize
-            || ibSize < 0 || ibSize > indexBufferSize) {
+    if (vbSize < 0 || ibSize < 0) {
         return JNI_FALSE;
     }
 
-    boolean result = mesh->buildBuffers(vertexBuffer, vbSize, indexBuffer, ibSize);
+    UINT uvbSize = (UINT) vbSize;
+    UINT uibSize = (UINT) ibSize;
+    if (vertexBuffer == NULL || indexBuffer == NULL
+            || uvbSize > vertexBufferSize || uibSize > indexBufferSize) {
+        return JNI_FALSE;
+    }
+
+    boolean result = mesh->buildBuffers(vertexBuffer, uvbSize, indexBuffer, uibSize);
     env->ReleasePrimitiveArrayCritical(ib, indexBuffer, 0);
     env->ReleasePrimitiveArrayCritical(vb, vertexBuffer, 0);
 
@@ -248,13 +253,18 @@
     UINT indexBufferSize = env->GetArrayLength(ib);
     UINT *indexBuffer = (UINT *) (env->GetPrimitiveArrayCritical(ib, NULL));
 
-    if (vertexBuffer == NULL || indexBuffer == NULL
-            || vbSize < 0 || vbSize > vertexBufferSize
-            || ibSize < 0 || ibSize > indexBufferSize) {
+    if (vbSize < 0 || ibSize < 0) {
         return JNI_FALSE;
     }
 
-    boolean result = mesh->buildBuffers(vertexBuffer, vbSize, indexBuffer, ibSize);
+    UINT uvbSize = (UINT) vbSize;
+    UINT uibSize = (UINT) ibSize;
+    if (vertexBuffer == NULL || indexBuffer == NULL
+            || uvbSize > vertexBufferSize || uibSize > indexBufferSize) {
+        return JNI_FALSE;
+    }
+
+    boolean result = mesh->buildBuffers(vertexBuffer, uvbSize, indexBuffer, uibSize);
     env->ReleasePrimitiveArrayCritical(ib, indexBuffer, 0);
     env->ReleasePrimitiveArrayCritical(vb, vertexBuffer, 0);
 
--- a/modules/graphics/src/main/native-prism-es2/GLContext.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-prism-es2/GLContext.c	Tue Aug 20 09:38:00 2013 -0700
@@ -1852,6 +1852,8 @@
     GLushort *indexBuffer;
     GLfloat *vertexBuffer;
     jboolean status = JNI_TRUE;
+    GLuint uvbSize;
+    GLuint uibSize;
 
     ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo);
     MeshInfo *meshInfo = (MeshInfo *) jlong_to_ptr(nativeMeshInfo);
@@ -1860,7 +1862,8 @@
             (ctxInfo->glBindBuffer == NULL) ||
             (ctxInfo->glBufferData == NULL) ||
             (meshInfo->vboIDArray[MESH_VERTEXBUFFER] == 0)||
-            (meshInfo->vboIDArray[MESH_INDEXBUFFER] == 0)) {
+            (meshInfo->vboIDArray[MESH_INDEXBUFFER] == 0) ||
+            vbSize < 0 || ibSize < 0) {
         return JNI_FALSE;
     }
 
@@ -1870,23 +1873,24 @@
     indexBufferSize = (*env)->GetArrayLength(env, ibArray);
     indexBuffer = (GLushort *) ((*env)->GetPrimitiveArrayCritical(env, ibArray, NULL));
 
+    uvbSize = (GLuint) vbSize;
+    uibSize = (GLuint) ibSize;
     if (vertexBuffer == NULL || indexBuffer == NULL
-            || vbSize < 0 || vbSize > vertexBufferSize
-            || ibSize < 0 || ibSize > indexBufferSize) {
+            || uvbSize > vertexBufferSize || uibSize > indexBufferSize) {
         status = JNI_FALSE;
     }
 
     if (status) {
         // Initialize vertex buffer
         ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, meshInfo->vboIDArray[MESH_VERTEXBUFFER]);
-        ctxInfo->glBufferData(GL_ARRAY_BUFFER, vbSize * sizeof (GLfloat),
+        ctxInfo->glBufferData(GL_ARRAY_BUFFER, uvbSize * sizeof (GLfloat),
                 vertexBuffer, GL_STATIC_DRAW);
 
         // Initialize index buffer
         ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshInfo->vboIDArray[MESH_INDEXBUFFER]);
-        ctxInfo->glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibSize * sizeof (GLushort),
+        ctxInfo->glBufferData(GL_ELEMENT_ARRAY_BUFFER, uibSize * sizeof (GLushort),
                 indexBuffer, GL_STATIC_DRAW);
-        meshInfo->indexBufferSize = ibSize;
+        meshInfo->indexBufferSize = uibSize;
         meshInfo->indexBufferType = GL_UNSIGNED_SHORT;
 
         // Unbind VBOs
@@ -1915,9 +1919,11 @@
 {
     GLuint vertexBufferSize;
     GLuint indexBufferSize;
-    GLushort *indexBuffer;
+    GLuint *indexBuffer;
     GLfloat *vertexBuffer;
     jboolean status = JNI_TRUE;
+    GLuint uvbSize;
+    GLuint uibSize;
 
     ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo);
     MeshInfo *meshInfo = (MeshInfo *) jlong_to_ptr(nativeMeshInfo);
@@ -1926,7 +1932,8 @@
             (ctxInfo->glBindBuffer == NULL) ||
             (ctxInfo->glBufferData == NULL) ||
             (meshInfo->vboIDArray[MESH_VERTEXBUFFER] == 0)||
-            (meshInfo->vboIDArray[MESH_INDEXBUFFER] == 0)) {
+            (meshInfo->vboIDArray[MESH_INDEXBUFFER] == 0) ||
+            vbSize < 0 || ibSize < 0) {
         return JNI_FALSE;
     }
 
@@ -1936,23 +1943,24 @@
     indexBufferSize = (*env)->GetArrayLength(env, ibArray);
     indexBuffer = (GLuint *) ((*env)->GetPrimitiveArrayCritical(env, ibArray, NULL));
 
+    uvbSize = (GLuint) vbSize;
+    uibSize = (GLuint) ibSize;
     if (vertexBuffer == NULL || indexBuffer == NULL
-            || vbSize < 0 || vbSize > vertexBufferSize
-            || ibSize < 0 || ibSize > indexBufferSize) {
+            || uvbSize > vertexBufferSize || uibSize > indexBufferSize) {
         status = JNI_FALSE;
     }
 
     if (status) {
         // Initialize vertex buffer
         ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, meshInfo->vboIDArray[MESH_VERTEXBUFFER]);
-        ctxInfo->glBufferData(GL_ARRAY_BUFFER, vbSize * sizeof (GLfloat),
+        ctxInfo->glBufferData(GL_ARRAY_BUFFER, uvbSize * sizeof (GLfloat),
                 vertexBuffer, GL_STATIC_DRAW);
 
         // Initialize index buffer
         ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshInfo->vboIDArray[MESH_INDEXBUFFER]);
-        ctxInfo->glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibSize * sizeof (GLuint),
+        ctxInfo->glBufferData(GL_ELEMENT_ARRAY_BUFFER, uibSize * sizeof (GLuint),
                 indexBuffer, GL_STATIC_DRAW);
-        meshInfo->indexBufferSize = ibSize;
+        meshInfo->indexBufferSize = uibSize;
         meshInfo->indexBufferType = GL_UNSIGNED_INT;
 
         // Unbind VBOs
--- a/modules/graphics/src/main/native-prism-es2/eglfb/wrapped_egl.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-prism-es2/eglfb/wrapped_egl.c	Tue Aug 20 09:38:00 2013 -0700
@@ -270,16 +270,20 @@
             src.width = screenInfo.xres << 16;
             src.height = screenInfo.yres << 16;
 
+            VC_DISPMANX_ALPHA_T alpha;
+            alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE;
+            alpha.opacity = 0xff;
+            alpha.mask = (DISPMANX_RESOURCE_HANDLE_T) 0;
             update = (*wr_vc_dispmanx_update_start)(0);
             element = (*wr_vc_dispmanx_element_add)(
                           update,
                           display,
-                          0 /*layer*/,
+                          1 /*layer*/,
                           &dst,
                           0 /*src*/,
                           &src,
                           DISPMANX_PROTECTION_NONE,
-                          0 /*alpha*/,
+                          &alpha,
                           0 /*clamp*/,
                           0 /*transform*/);
 
--- a/modules/graphics/src/main/native-prism-sw/PiscesPaint.c	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/main/native-prism-sw/PiscesPaint.c	Tue Aug 20 09:38:00 2013 -0700
@@ -368,7 +368,7 @@
     jboolean isXin = ((tx < txMax) && (tx >= txMin));
     pts[0] = (isXin) ? data[sidx + 1] : p00;
     pts[1] = data[sidx2];
-    pts[2] = (isXin) ? data[sidx2 + 1] : pts[0];
+    pts[2] = (isXin) ? data[sidx2 + 1] : data[sidx2];
 }
 
 static INLINE void getPointsToInterpolateRepeat(jint *pts, jint *data, jint sidx, jint stride, jint p00,
--- a/modules/graphics/src/test/java/com/sun/javafx/sg/prism/OcclusionCullingTest.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/test/java/com/sun/javafx/sg/prism/OcclusionCullingTest.java	Tue Aug 20 09:38:00 2013 -0700
@@ -33,70 +33,111 @@
 import static com.sun.javafx.sg.prism.NodeTestUtils.*;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
 
 /**
  *
  */
 public class OcclusionCullingTest {
-    
-    
+
+
     @Test
     public void testRectangleOcclusion() {
+        final TestNGRectangle root = createRectangle(0, 0, 50, 50);
         NodeTestUtils.TestNGGroup group = createGroup(
-                createRectangle(0, 0, 100, 100), createRectangle(0, 0, 50, 50));
-        NodePath<NGNode> rootPath = new NodePath<NGNode>();
+                createRectangle(0, 0, 100, 100), root);
+        NodePath<NGNode> rootPath = new NodePath<>();
         rootPath = group.getRenderRoot(rootPath, new RectBounds(20, 20, 30, 30), -1, BaseTransform.IDENTITY_TRANSFORM, null);
         TestGraphics g = new TestGraphics();
         g.setRenderRoot(rootPath);
         group.render(g);
-//        assertSame(group.getChildren().get(1), rootPath.);
-        rootPath.reset();
+        assertRoot(rootPath, root);
         checkRootRendering(group, rootPath);
     }
-    
+
     @Test
     public void testGroupOcclusion() {
+        final TestNGRectangle root = createRectangle(0, 0, 50, 50);
         NodeTestUtils.TestNGGroup group = createGroup(createGroup(
-                createRectangle(0, 0, 100, 100)), createGroup(createRectangle(0, 0, 50, 50)));
-        NodePath<NGNode> rootPath = new NodePath<NGNode>();
+                createRectangle(0, 0, 100, 100)), createGroup(root));
+        NodePath<NGNode> rootPath = new NodePath<>();
         rootPath = group.getRenderRoot(rootPath, new RectBounds(20, 20, 30, 30), -1, BaseTransform.IDENTITY_TRANSFORM, null);
         TestGraphics g = new TestGraphics();
         g.setRenderRoot(rootPath);
         group.render(g);
-//        assertSame(((NGGroup)group.getChildren().get(1)).getChildren().get(0), root);
-        rootPath.reset();
+        assertRoot(rootPath, root);
         checkRootRendering(group, rootPath);
     }
-    
+
     @Test
     public void testRegionOcclusion() {
+        final TestNGRegion root = createRegion(50, 50);
         NodeTestUtils.TestNGGroup group = createGroup(
-                createRegion(100, 100), createRegion(50, 50));
-        NodePath<NGNode> rootPath = new NodePath<NGNode>();
+                createRegion(100, 100), root);
+        NodePath<NGNode> rootPath = new NodePath<>();
         rootPath = group.getRenderRoot(rootPath, new RectBounds(20, 20, 30, 30), -1, BaseTransform.IDENTITY_TRANSFORM, null);
         TestGraphics g = new TestGraphics();
         g.setRenderRoot(rootPath);
         group.render(g);
-//        assertSame(group.getChildren().get(1), root);
-        rootPath.reset();
+        assertRoot(rootPath, root);
         checkRootRendering(group, rootPath);
     }
-    
+
     @Test
     public void testPresetRegionOcclusion() {
+        final TestNGRegion root = createRegion(100, 100);
+        final TestNGRegion other = createRegion(50, 50);
         NodeTestUtils.TestNGGroup group = createGroup(
-                createRegion(100, 100), createRegion(50, 50));
-        ((NGRegion)group.getChildren().get(1)).setOpaqueInsets(30, 30, 0, 0);
-        NodePath<NGNode> rootPath = new NodePath<NGNode>();
+                root, other);
+        other.setOpaqueInsets(30, 30, 0, 0);
+        NodePath<NGNode> rootPath = new NodePath<>();
         rootPath = group.getRenderRoot(rootPath, new RectBounds(20, 20, 30, 30), -1, BaseTransform.IDENTITY_TRANSFORM, null);
         TestGraphics g = new TestGraphics();
         g.setRenderRoot(rootPath);
         group.render(g);
-//        assertSame(group.getChildren().get(0), root);
-        rootPath.reset();
+        assertRoot(rootPath, root);
         checkRootRendering(group, rootPath);
     }
 
+    @Test
+    public void test2SameRectanglesOclusion() {
+        final TestNGRectangle root = createRectangle(10, 10, 100, 100);
+        NodeTestUtils.TestNGGroup group = createGroup(
+                createGroup(createRectangle(10, 10, 100, 100), createRectangle(20, 20, 20, 20)),
+                createGroup(root));
+        NodePath<NGNode> rootPath = new NodePath<>();
+        rootPath = group.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, null);
+        TestGraphics g = new TestGraphics();
+        g.setRenderRoot(rootPath);
+        group.render(g);
+        assertRoot(rootPath, root);
+        checkRootRendering(group, rootPath);
+    }
+
+    @Test
+    public void test2SameRectanglesOclusionWithRootNotDirty() {
+        final TestNGRectangle root = createRectangle(10, 10, 100, 100);
+        final TestNGGroup rootParent = createGroup(root);
+        NodeTestUtils.TestNGGroup group = createGroup(
+                createGroup(createRectangle(10, 10, 100, 100), createRectangle(20, 20, 20, 20)), rootParent);
+
+        group.dirty =  NGNode.DirtyFlag.CLEAN; // need to clean default dirty flags
+        rootParent.dirty = NGNode.DirtyFlag.CLEAN;
+        rootParent.childDirty = false;
+        root.dirty = NGNode.DirtyFlag.CLEAN;
+        NodePath<NGNode> rootPath = new NodePath<>();
+        rootPath = group.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, null);
+        assertTrue(rootPath.isEmpty());
+
+        final TestNGRectangle dirtySibling = createRectangle(0,0,10,10);
+        rootParent.add(-1,dirtySibling);
+        rootPath = new NodePath<>();
+        rootPath = group.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, null);
+        assertRoot(rootPath, rootParent);
+    }
+
     private void checkRootRendering(TestNGNode group, NodePath<NGNode> root) {
         assertTrue(group.rendered());
         if (group instanceof TestNGGroup) {
@@ -124,6 +165,15 @@
              }
         }
     }
-    
-    
+
+    private void assertRoot(NodePath<NGNode> rootPath, final NGNode root) {
+        rootPath.reset();
+        while(rootPath.hasNext()) {
+            rootPath.next();
+        }
+        assertSame(root, rootPath.getCurrentNode());
+        rootPath.reset();
+    }
+
+
 }
--- a/modules/graphics/src/test/java/javafx/scene/SceneTest.java	Tue Aug 20 08:59:55 2013 -0400
+++ b/modules/graphics/src/test/java/javafx/scene/SceneTest.java	Tue Aug 20 09:38:00 2013 -0700
@@ -36,6 +36,8 @@
 import com.sun.javafx.pgstub.StubScene;
 import com.sun.javafx.sg.prism.NGCamera;
 import com.sun.javafx.tk.Toolkit;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -751,4 +753,20 @@
             fail("It didn't allow to 'share' camera with myslef");
         }
     }
+
+    @Test
+    public void scenePropertyListenerShouldBeCalledForInitializedScene() {
+        final Group root = new Group();
+        final Rectangle rect = new Rectangle();
+        root.getChildren().add(rect);
+
+        root.sceneProperty().addListener(new InvalidationListener() {
+            @Override public void invalidated(Observable o) {
+                root.getChildren().remove(rect);
+            }
+        });
+
+        Scene scene = new Scene(root, 600, 450);
+        // if there is no exception, the test passed
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/ios/java/com/sun/javafx/scene/web/behavior/HTMLEditorBehavior.java	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,73 @@
+/*
+ * 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.scene.web.behavior;
+
+import javafx.scene.web.HTMLEditor;
+import java.util.ArrayList;
+import java.util.List;
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
+import com.sun.javafx.scene.web.skin.HTMLEditorSkin;
+import static javafx.scene.input.KeyCode.B;
+import static javafx.scene.input.KeyCode.I;
+import static javafx.scene.input.KeyCode.U;
+import static javafx.scene.input.KeyCode.F12;
+import static javafx.scene.input.KeyCode.TAB;
+
+
+/**
+ * HTML editor behavior.
+ */
+public class HTMLEditorBehavior extends BehaviorBase<HTMLEditor> {
+    protected static final List<KeyBinding> HTML_EDITOR_BINDINGS = new ArrayList<KeyBinding>();
+
+    static {
+        HTML_EDITOR_BINDINGS.add(new KeyBinding(B, "bold").shortcut());
+        HTML_EDITOR_BINDINGS.add(new KeyBinding(I, "italic").shortcut());
+        HTML_EDITOR_BINDINGS.add(new KeyBinding(U, "underline").shortcut());
+        
+        HTML_EDITOR_BINDINGS.add(new KeyBinding(F12, "F12"));
+        HTML_EDITOR_BINDINGS.add(new KeyBinding(TAB, "TraverseNext").ctrl());
+        HTML_EDITOR_BINDINGS.add(new KeyBinding(TAB, "TraversePrevious").ctrl().shift());
+    }
+
+    public HTMLEditorBehavior(HTMLEditor htmlEditor) {
+        super(htmlEditor, HTML_EDITOR_BINDINGS);
+    }
+
+    @Override
+    protected void callAction(String name) {
+        if ("bold".equals(name) || "italic".equals(name) || "underline".equals(name)) {
+            HTMLEditor editor = getControl();
+            HTMLEditorSkin editorSkin = (HTMLEditorSkin)editor.getSkin();
+            editorSkin.keyboardShortcuts(name);
+        } else if ("F12".equals(name)) {
+            getControl().getImpl_traversalEngine().getTopLeftFocusableNode();
+        } else {
+            super.callAction(name);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/web/src/ios/java/com/sun/javafx/scene/web/skin/HTMLEditorSkin.java	Tue Aug 20 09:38:00 2013 -0700
@@ -0,0 +1,1213 @@
+/*
+ * 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.scene.web.skin;
+
+import java.util.ResourceBundle;
+
+import com.sun.javafx.application.PlatformImpl;
+import org.w3c.dom.html.HTMLDocument;
+import org.w3c.dom.html.HTMLElement;
+
+import javafx.application.ConditionalFeature;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.css.StyleableProperty;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Bounds;
+import javafx.geometry.NodeOrientation;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.MenuButton;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.RadioMenuItem;
+import javafx.scene.control.Separator;
+import javafx.scene.control.TextInputControl;
+import javafx.scene.control.Toggle;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.control.ToggleGroup;
+import javafx.scene.control.ToolBar;
+import javafx.scene.control.Tooltip;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.ColumnConstraints;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Priority;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.text.Font;
+import javafx.scene.web.HTMLEditor;
+import javafx.scene.web.WebView;
+import javafx.util.Callback;
+
+import com.sun.javafx.PlatformUtil;
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.skin.ColorPickerSkin;
+import com.sun.javafx.scene.control.skin.FXVK;
+import com.sun.javafx.scene.web.behavior.HTMLEditorBehavior;
+import com.sun.javafx.scene.traversal.TraversalEngine;
+import com.sun.javafx.scene.traversal.TraverseListener;
+//import com.sun.webkit.WebPage;
+//import com.sun.webkit.event.WCFocusEvent;
+//import com.sun.javafx.webkit.Accessor;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.layout.*;
+import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
+import javafx.collections.ListChangeListener;
+
+import static javafx.geometry.NodeOrientation.*;
+
+/**
+ * HTML editor skin.
+ */
+public class HTMLEditorSkin extends BehaviorSkinBase<HTMLEditor, HTMLEditorBehavior> implements TraverseListener {
+    private GridPane gridPane;
+
+    private ToolBar toolbar1;
+    private ToolBar toolbar2;
+
+    private Button cutButton;
+    private Button copyButton;
+    private Button pasteButton;
+
+//    private Button undoButton;
+//    private Button redoButton;
+
+    private Button insertHorizontalRuleButton;
+
+    private ToggleGroup alignmentToggleGroup;
+    private ToggleButton alignLeftButton;
+    private ToggleButton alignCenterButton;
+    private ToggleButton alignRightButton;
+    private ToggleButton alignJustifyButton;
+
+    private ToggleButton bulletsButton;
+    private ToggleButton numbersButton;
+
+    private Button indentButton;
+    private Button outdentButton;
+
+    private ComboBox<String> formatComboBox;
+    private Map<String, String> formatStyleMap;
+    private Map<String, String> styleFormatMap;
+
+    private ComboBox<String> fontFamilyComboBox;
+
+    private ComboBox<String> fontSizeComboBox;
+    private Map<String, String> fontSizeMap;
+    private Map<String, String> sizeFontMap;
+
+    private ToggleButton boldButton;
+    private ToggleButton italicButton;
+    private ToggleButton underlineButton;
+    private ToggleButton strikethroughButton;
+
+    private ColorPicker fgColorButton;
+    private ColorPicker bgColorButton;
+
+    private WebView webView;
+//    private WebPage webPage;
+
+    private static final String CUT_COMMAND = "cut";
+    private static final String COPY_COMMAND = "copy";
+    private static final String PASTE_COMMAND = "paste";
+
+    private static final String UNDO_COMMAND = "undo";
+    private static final String REDO_COMMAND = "redo";
+
+    private static final String INSERT_HORIZONTAL_RULE_COMMAND = "inserthorizontalrule";
+
+    private static final String ALIGN_LEFT_COMMAND = "justifyleft";
+    private static final String ALIGN_CENTER_COMMAND = "justifycenter";
+    private static final String ALIGN_RIGHT_COMMAND = "justifyright";
+    private static final String ALIGN_JUSTIFY_COMMAND = "justifyfull";
+
+    private static final String BULLETS_COMMAND = "insertUnorderedList";
+    private static final String NUMBERS_COMMAND = "insertOrderedList";
+
+    private static final String INDENT_COMMAND = "indent";
+    private static final String OUTDENT_COMMAND = "outdent";
+
+    private static final String FORMAT_COMMAND = "formatblock";
+    private static final String FONT_FAMILY_COMMAND = "fontname";
+    private static final String FONT_SIZE_COMMAND = "fontsize";
+
+    private static final String BOLD_COMMAND = "bold";
+    private static final String ITALIC_COMMAND = "italic";
+    private static final String UNDERLINE_COMMAND = "underline";
+    private static final String STRIKETHROUGH_COMMAND = "strikethrough";
+
+    private static final String FOREGROUND_COLOR_COMMAND = "forecolor";
+    private static final String BACKGROUND_COLOR_COMMAND = "backcolor";
+
+    private static final Color DEFAULT_BG_COLOR = Color.WHITE;
+    private static final Color DEFAULT_FG_COLOR = Color.BLACK;
+
+    private static final String FORMAT_PARAGRAPH = "<p>";
+    private static final String FORMAT_HEADING_1 = "<h1>";
+    private static final String FORMAT_HEADING_2 = "<h2>";
+    private static final String FORMAT_HEADING_3 = "<h3>";
+    private static final String FORMAT_HEADING_4 = "<h4>";
+    private static final String FORMAT_HEADING_5 = "<h5>";
+    private static final String FORMAT_HEADING_6 = "<h6>";
+
+    private static final String SIZE_XX_SMALL = "1";
+    private static final String SIZE_X_SMALL = "2";
+    private static final String SIZE_SMALL = "3";
+    private static final String SIZE_MEDIUM = "4";
+    private static final String SIZE_LARGE = "5";
+    private static final String SIZE_X_LARGE = "6";
+    private static final String SIZE_XX_LARGE = "7";
+
+    private static final String INSERT_NEW_LINE_COMMAND = "insertnewline";
+    private static final String INSERT_TAB_COMMAND = "inserttab";
+
+    // As per RT-16330: default format -> bold/size mappings are as follows:
+    private static final String[][] DEFAULT_FORMAT_MAPPINGS = {
+        { FORMAT_PARAGRAPH,   "",             SIZE_SMALL     },
+        { FORMAT_HEADING_1,   BOLD_COMMAND,   SIZE_X_LARGE   },
+        { FORMAT_HEADING_2,   BOLD_COMMAND,   SIZE_LARGE     },
+        { FORMAT_HEADING_3,   BOLD_COMMAND,   SIZE_MEDIUM    },
+        { FORMAT_HEADING_4,   BOLD_COMMAND,   SIZE_SMALL     },
+        { FORMAT_HEADING_5,   BOLD_COMMAND,   SIZE_X_SMALL   },
+        { FORMAT_HEADING_6,   BOLD_COMMAND,   SIZE_XX_SMALL  },
+    };
+
+    // As per RT-16379: default OS -> font mappings:
+    private static final String[] DEFAULT_WINDOWS_7_MAPPINGS = {
+        "Windows 7",       "Segoe UI",        "12px",   "",     "120"
+    };
+    private static final String[][] DEFAULT_OS_MAPPINGS = {
+        // OS               Font name           size      weight  DPI
+        { "Windows XP",      "Tahoma",          "12px",   "",     "96"  },
+        { "Windows Vista",   "Segoe UI",        "12px",   "",     "96"  },
+        DEFAULT_WINDOWS_7_MAPPINGS,
+        { "Mac OS X",        "Lucida Grande",   "12px",   "",     "72"  },
+        { "Linux",           "Lucida Sans",   "12px",   "",     "96"  },
+    };
+    private static final String DEFAULT_OS_FONT = getOSMappings()[1];
+    
+    private static final Label IOS_UNSUPPORTED_LABEL = 
+            new Label("HTML Editor component is not supported on iOS platform"); 
+
+    private static String[] getOSMappings() {
+        String os = System.getProperty("os.name");
+        for  (int i = 0; i < DEFAULT_OS_MAPPINGS.length; i++) {
+            if (os.equals(DEFAULT_OS_MAPPINGS[i][0])) {
+                return DEFAULT_OS_MAPPINGS[i];
+            }
+        }
+
+        return DEFAULT_WINDOWS_7_MAPPINGS;
+    }
+
+    private TraversalEngine engine;
+
+    private boolean resetToolbarState = false;
+    private String cachedHTMLText = "<html><body></body></html>";
+    private ListChangeListener<Node> itemsListener = new ListChangeListener<Node>() {
+        @Override public void onChanged(ListChangeListener.Change<? extends Node> c) {
+//            while (c.next()) {
+//                if (c.getRemovedSize() > 0) {
+//                    for (Node n : c.getList()) {
+//                        if (n instanceof WebView) {
+//                            // RT-28611 webView removed - set associated webPage to null
+//                            webPage.dispose();
+//                        }
+//                    }
+//                }
+//            }
+        }
+    };
+    public HTMLEditorSkin(HTMLEditor htmlEditor) {
+        super(htmlEditor, new HTMLEditorBehavior(htmlEditor));
+
+        getChildren().clear();
+
+        gridPane = new GridPane();
+        gridPane.getStyleClass().add("grid");
+        getChildren().addAll(gridPane);
+
+        toolbar1 = new ToolBar();
+        toolbar1.getStyleClass().add("top-toolbar");
+        gridPane.add(toolbar1, 0, 0);
+
+        toolbar2 = new ToolBar();
+        toolbar2.getStyleClass().add("bottom-toolbar");
+        gridPane.add(toolbar2, 0, 1);
+
+//        populateToolbars();
+
+        webView = new WebView();
+        gridPane.add(/*webView*/IOS_UNSUPPORTED_LABEL, 0, 2);
+
+        ColumnConstraints column = new ColumnConstraints();
+        column.setHgrow(Priority.ALWAYS);
+        gridPane.getColumnConstraints().add(column);
+
+//        webPage = Accessor.getPageFor(webView.getEngine());
+
+        webView.addEventHandler(MouseEvent.ANY, new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent event) {
+                Platform.runLater(new Runnable() {
+                    @Override public void run() {
+                        updateToolbarState(true);
+                    }
+                });
+            }
+        });
+
+
+        webView.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
+            @Override public void handle(final KeyEvent event) {
+                applyTextFormatting();
+                if (event.getCode() == KeyCode.CONTROL || event.getCode() == KeyCode.META) {
+                    return;
+                }
+                if (event.getCode() == KeyCode.TAB && !event.isControlDown()) {
+                    if (!event.isShiftDown()) {
+                        /*
+                        ** if we are in either Bullet or Numbers mode then the
+                        ** TAB key tells us to indent again.
+                        */
+                        if (getCommandState(BULLETS_COMMAND) || getCommandState(NUMBERS_COMMAND)) {
+                            executeCommand(INDENT_COMMAND, null);
+                        }
+                        else {
+                            executeCommand(INSERT_TAB_COMMAND, null);
+                        }
+                    }
+                    else {
+                        /*
+                        ** if we are in either Bullet or Numbers mode then the
+                        ** Shift-TAB key tells us to outdent.
+                        */
+                        if (getCommandState(BULLETS_COMMAND) || getCommandState(NUMBERS_COMMAND)) {
+                            executeCommand(OUTDENT_COMMAND, null);
+                        }
+                    }
+                    return;
+                }
+                // Work around for bug that sends events from ColorPicker to this Scene
+                if ((fgColorButton != null && fgColorButton.isShowing()) ||
+                    (bgColorButton != null && bgColorButton.isShowing())) {
+                    return;
+                }
+                Platform.runLater(new Runnable() {
+                    @Override public void run() {
+//                        if (webPage.getClientSelectedText().isEmpty()) {
+//                            if (event.getCode() == KeyCode.UP || event.getCode() == KeyCode.DOWN ||
+//                                event.getCode() == KeyCode.LEFT || event.getCode() == KeyCode.RIGHT ||
+//                                event.getCode() == KeyCode.HOME || event.getCode() == KeyCode.END) {
+//                                updateToolbarState(true);
+//                            } else if (event.isControlDown() || event.isMetaDown()) {
+//                                if (event.getCode() == KeyCode.B) {
+//                                    keyboardShortcuts(BOLD_COMMAND);
+//                                } else if(event.getCode() == KeyCode.I) {
+//                                    keyboardShortcuts(ITALIC_COMMAND);
+//                                } else if (event.getCode() == KeyCode.U) {
+//                                    keyboardShortcuts(UNDERLINE_COMMAND);
+//                                }
+//                                updateToolbarState(true);
+//                            } else {
+//                                resetToolbarState = event.getCode() == KeyCode.ENTER;
+//                                if (resetToolbarState) {
+//                                    if (getCommandState(BOLD_COMMAND) !=  boldButton.selectedProperty().getValue()) {
+//                                        executeCommand(BOLD_COMMAND, boldButton.selectedProperty().getValue().toString());
+//                                    }
+//                                }
+//                                updateToolbarState(false);
+//                            }
+//                            resetToolbarState = false;
+//                        }
+//                        else if (event.isShiftDown() && 
+//                                 (event.getCode() == KeyCode.UP || event.getCode() == KeyCode.DOWN ||
+//                                  event.getCode() == KeyCode.LEFT || event.getCode() == KeyCode.RIGHT)) {
+//                            updateToolbarState(true);
+//                        }
+                    }
+                });
+            }
+        });
+
+        webView.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
+            @Override public void handle(final KeyEvent event) {
+                if (event.getCode() == KeyCode.CONTROL || event.getCode() == KeyCode.META) {
+                    return;
+                }
+                // Work around for bug that sends events from ColorPicker to this Scene
+                if ((fgColorButton != null && fgColorButton.isShowing()) ||
+                    (bgColorButton != null && bgColorButton.isShowing())) {
+                    return;
+                }
+                Platform.runLater(new Runnable() {
+                    @Override public void run() {
+//                        if (webPage.getClientSelectedText().isEmpty()) {
+//                            if (event.getCode() == KeyCode.UP || event.getCode() == KeyCode.DOWN ||
+//                                event.getCode() == KeyCode.LEFT || event.getCode() == KeyCode.RIGHT ||
+//                                event.getCode() == KeyCode.HOME || event.getCode() == KeyCode.END) {
+//                                updateToolbarState(true);
+//                            } else if (event.isControlDown() || event.isMetaDown()) {
+//                                if (event.getCode() == KeyCode.B) {
+//                                    keyboardShortcuts(BOLD_COMMAND);
+//                                } else if(event.getCode() == KeyCode.I) {
+//                                    keyboardShortcuts(ITALIC_COMMAND);
+//                                } else if (event.getCode() == KeyCode.U) {
+//                                    keyboardShortcuts(UNDERLINE_COMMAND);
+//                                }
+//                                updateToolbarState(true);
+//                            } else {
+//                                resetToolbarState = event.getCode() == KeyCode.ENTER;
+//                                if (!resetToolbarState) {
+//                                    updateToolbarState(false);
+//